From patchwork Fri Aug 19 12:52:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948810 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id F33ABC32771 for ; Fri, 19 Aug 2022 12:53:59 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id E948A1652; Fri, 19 Aug 2022 14:53:07 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz E948A1652 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913638; bh=dlneTxSjVzNWORAX9I/FBXwZW3hYSFXTPRiLs/gRXWw=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=M532bhxPP7EhSA0R7UYDC7YzFkZaPvWomDYjpUvz4rOvQN2wPTlNmzRjhvDNGiRgY SrFvZ4G0ycPfQY4eUJgAaUEiKFrRyhBrVNTJVsUQ7t2CMaL9O7leCkWNJwekqH2K3V eXrWVQ7McndkLBPCW1KgrJ81DBjSpg3vdZeZxGqA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 59235F8051E; Fri, 19 Aug 2022 14:52:45 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id B97FAF80527; Fri, 19 Aug 2022 14:52:43 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B5905F8016C for ; Fri, 19 Aug 2022 14:52:37 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz B5905F8016C Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="WRMPe6Is" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27JBix0P020060; Fri, 19 Aug 2022 07:52:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=fRxAdbE57d0qiTBUvDtalLSnCO5ib5KMTH5zZplYHSE=; b=WRMPe6IsGN6KjPBo/mSLOJD1f7lSd/FBuQ/iTtxmLeOVy6AS+Xp/lR5M5Fz5C0QACVea KxbezR8Bb+YY6rhU4bUx0zh1THNvisXfW+4v54NpA8KcsmrAfKD/vdsOzE0oZxwj0fEh W7xzszTWUOK6TefZvb8ma1iyCQ3WqpMFnmXkgvosXy+FpCWwOeSUimnjbUG8lMcoYIE0 695a7sMW+omoGswvosSZloaVhyWz7lwzehMg6UXYNpJ/STq4rXQwwdqKTbYZ5byaRjJz ybuLBLcGPSly0OnV+3ChzZ9Nb/LVVP0YN3WjKMtxrLx5o679/Z/DjiZKsgSpExV/746+ SQ== Received: from ediex02.ad.cirrus.com ([84.19.233.68]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 3hx8cpfuvn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:36 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:34 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:34 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 40B07B16; Fri, 19 Aug 2022 12:52:32 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 01/12] ASoC: cs42l42: Add SOFT_RESET_REBOOT register Date: Fri, 19 Aug 2022 13:52:19 +0100 Message-ID: <20220819125230.42731-2-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: xs4AYtngnCc7SOo6tZI9rnjN33jkVlp4 X-Proofpoint-GUID: xs4AYtngnCc7SOo6tZI9rnjN33jkVlp4 X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" The SOFT_RESET_REBOOT register is needed to recover CS42L42 state after a Soundwire bus reset. Signed-off-by: Richard Fitzgerald --- include/sound/cs42l42.h | 5 +++++ sound/soc/codecs/cs42l42.c | 2 ++ 2 files changed, 7 insertions(+) diff --git a/include/sound/cs42l42.h b/include/sound/cs42l42.h index a55d522f1772..9cf4baabea52 100644 --- a/include/sound/cs42l42.h +++ b/include/sound/cs42l42.h @@ -34,6 +34,7 @@ #define CS42L42_PAGE_24 0x2400 #define CS42L42_PAGE_25 0x2500 #define CS42L42_PAGE_26 0x2600 +#define CS42L42_PAGE_27 0x2700 #define CS42L42_PAGE_28 0x2800 #define CS42L42_PAGE_29 0x2900 #define CS42L42_PAGE_2A 0x2A00 @@ -719,6 +720,10 @@ #define CS42L42_SRC_SDOUT_FS (CS42L42_PAGE_26 + 0x09) +/* Page 0x27 DMA */ +#define CS42L42_SOFT_RESET_REBOOT (CS42L42_PAGE_27 + 0x01) +#define CS42L42_SFT_RST_REBOOT_MASK BIT(1) + /* Page 0x28 S/PDIF Registers */ #define CS42L42_SPDIF_CTL1 (CS42L42_PAGE_28 + 0x01) #define CS42L42_SPDIF_CTL2 (CS42L42_PAGE_28 + 0x02) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 42cdb051e0fb..440d414efe0a 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -294,6 +294,7 @@ static bool cs42l42_readable_register(struct device *dev, unsigned int reg) case CS42L42_SPDIF_SW_CTL1: case CS42L42_SRC_SDIN_FS: case CS42L42_SRC_SDOUT_FS: + case CS42L42_SOFT_RESET_REBOOT: case CS42L42_SPDIF_CTL1: case CS42L42_SPDIF_CTL2: case CS42L42_SPDIF_CTL3: @@ -358,6 +359,7 @@ static bool cs42l42_volatile_register(struct device *dev, unsigned int reg) case CS42L42_LOAD_DET_DONE: case CS42L42_DET_STATUS1: case CS42L42_DET_STATUS2: + case CS42L42_SOFT_RESET_REBOOT: return true; default: return false; From patchwork Fri Aug 19 12:52:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948817 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 96753C32773 for ; Fri, 19 Aug 2022 12:55:51 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B334D1685; Fri, 19 Aug 2022 14:54:59 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B334D1685 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913749; bh=ZJMnGVlZqYvreD+eXL0Tt4oYboqA0uYiAr1T4Pc1bAQ=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=XGoCI5eAJmaR4DnkRAgONUIO0VkViBBi2UtYK7erFgaKgnh/naqhPExF1bmoMQD+p 2cIwJY4ERM5xaYP3gXKQoGTW470inSb6T5M15WMHN8i4YIesuQnQq1sWzmV29v9dDY +sNLrU67Xhjv433zOH7y6yDaAgfrEp5hU1zUB/yI= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 4C676F80567; Fri, 19 Aug 2022 14:53:02 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0AB7EF80549; Fri, 19 Aug 2022 14:52:55 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 9FBD2F80525 for ; Fri, 19 Aug 2022 14:52:39 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 9FBD2F80525 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="WU4M3FjY" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27J5opPn018534; Fri, 19 Aug 2022 07:52:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=Cahuxfx8FbsiBBuZYNG0sBEu8gh5h4CTMFEjgx6vfNk=; b=WU4M3FjY74C34jUbsKsQxHQ3le1svxC9uCNTcQX/+lEbfXP87ZMoswBo3s06hdL9AWTZ FwLvbTdKxB9Y2PNbHiRDe/BGA4f4Ldpavakzz8j2OXp7CfgPeB4HHbkBGISjt19Vu35y O3MQSvwwzJB4Rjk9OzWQEc8aO+d3B90LaxALaUY1rnWCi47gKj7U8ObJCuaLKzFM6rFY UvKpqX21B5NV5Nv0KLYRjwbQZzdLCULfNcDA6JB1I4XGIdCp4R0u+/itfi4v3VJD4c2a 4X6+by2b/t1Vc8hOQfI1i3/hAdD1N2F8hXBwfHRZtWhL9nQpV+fMNn/H+tZ7erEtRZU6 0A== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3hx9c1yrtp-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:36 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:34 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:34 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 8FF4F476; Fri, 19 Aug 2022 12:52:34 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 02/12] ASoC: cs42l42: Add bitclock frequency argument to cs42l42_pll_config() Date: Fri, 19 Aug 2022 13:52:20 +0100 Message-ID: <20220819125230.42731-3-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: AKnqAx_bzldxlWqbCX3_YlSB19dKW_Kv X-Proofpoint-GUID: AKnqAx_bzldxlWqbCX3_YlSB19dKW_Kv X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Clean up the handling of bitclock frequency by keeping all the logic in cs42l42_pcm_hw_params(), which then simply passes the frequency as an argument to cs42l42_pll_config(). The previous code had become clunky as a legacy of earlier versions of the clock handling. The logic was split across cs42l42_pcm_hw_params() and cs42l42_pll_config(), with the params-derived bclk stashed in struct cs42l42_private only to pass it to cs42l42_pll_config(). Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/cs42l42.c | 32 ++++++++++++++++---------------- sound/soc/codecs/cs42l42.h | 1 - 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 440d414efe0a..1745b83310ac 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -649,18 +649,12 @@ static const struct cs42l42_pll_params pll_ratio_table[] = { { 24576000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12288000, 128, 1} }; -static int cs42l42_pll_config(struct snd_soc_component *component) +static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int clk) { struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); int i; - u32 clk; u32 fsync; - if (!cs42l42->sclk) - clk = cs42l42->bclk; - else - clk = cs42l42->sclk; - /* Don't reconfigure if there is an audio stream running */ if (cs42l42->stream_use) { if (pll_ratio_table[cs42l42->pll_config].sclk == clk) @@ -897,19 +891,25 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, unsigned int width = (params_width(params) / 8) - 1; unsigned int slot_width = 0; unsigned int val = 0; + unsigned int bclk; int ret; cs42l42->srate = params_rate(params); - /* - * Assume 24-bit samples are in 32-bit slots, to prevent SCLK being - * more than assumed (which would result in overclocking). - */ - if (params_width(params) == 24) - slot_width = 32; + if (cs42l42->sclk) { + /* machine driver has set the SCLK */ + bclk = cs42l42->sclk; + } else { + /* + * Assume 24-bit samples are in 32-bit slots, to prevent SCLK being + * more than assumed (which would result in overclocking). + */ + if (params_width(params) == 24) + slot_width = 32; - /* I2S frame always has multiple of 2 channels */ - cs42l42->bclk = snd_soc_tdm_params_to_bclk(params, slot_width, 0, 2); + /* I2S frame always has multiple of 2 channels */ + bclk = snd_soc_tdm_params_to_bclk(params, slot_width, 0, 2); + } switch (substream->stream) { case SNDRV_PCM_STREAM_CAPTURE: @@ -949,7 +949,7 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, break; } - ret = cs42l42_pll_config(component); + ret = cs42l42_pll_config(component, bclk); if (ret) return ret; diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h index 50299c9f283a..b4ba1467c558 100644 --- a/sound/soc/codecs/cs42l42.h +++ b/sound/soc/codecs/cs42l42.h @@ -30,7 +30,6 @@ struct cs42l42_private { struct snd_soc_jack *jack; struct mutex irq_lock; int pll_config; - int bclk; u32 sclk; u32 srate; u8 plug_state; From patchwork Fri Aug 19 12:52:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948814 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EE88DC32771 for ; Fri, 19 Aug 2022 12:55:03 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 10E05163B; Fri, 19 Aug 2022 14:54:12 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 10E05163B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913702; bh=fDTJj0sR+CjoWeLcOuLLzFTy1HUVVzg/9gEXCyhL6e0=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=KLb/5u/0ZBa9xahZyWC0+B9fbbbDJV6QlahuLzQKbVNYlSDVng0H1EiAg2GeVjp+h Mr30Qu8HWdqhKFtLlOVzL8cXwoXqr/Lfx8laCAgN1OTuuB9aZcQCtOvBk3lmc6HmOO XK6uwd/WgyFpQvxh/bHvUU2xqFaky9om7DFUXdxs= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 964F0F80551; Fri, 19 Aug 2022 14:53:00 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 24340F80533; Fri, 19 Aug 2022 14:52:51 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 97635F802A0 for ; Fri, 19 Aug 2022 14:52:39 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 97635F802A0 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="hseGJlHF" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27J5opPo018534; Fri, 19 Aug 2022 07:52:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=VG7YSU/cYAKrW65aE8mh5zeQwZiWTAjDbpKQXBnwCro=; b=hseGJlHFyKI4oLN8yXRxvhLzeh3FUYZ8P6CN4jHUqJvdL5nDsQsztJqri5yFpiHBoPQj 1s40Km0Z2AFV/4JYNUkVu/JCf5eIpS4AJqroAv7z543MaHkCtjRI5Au5zYTlt+/n/Ey6 Nd4X5p/QutuH0WuHdU8psI7kXumEDemUlg5ebjap9hXXs0Bc1TqVihPjJQSkBYdX0tJP +0DvckFxd8s98GlLagE0Wx9g0RMjjR+HNF6weN0lombIKCqEmwXje6yatavQ0lVG0sTv ZV/3tFcxDDmiLqUrVr1Q5n0SZzyInbUlmdWRiMWOofw/+fKkGkV9Y8plv4QRHs4FvA5m 1Q== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3hx9c1yrtp-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:37 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:34 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:34 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 9515C11DA; Fri, 19 Aug 2022 12:52:34 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 03/12] ASoC: cs42l42: Ensure MCLKint is a multiple of the sample rate Date: Fri, 19 Aug 2022 13:52:21 +0100 Message-ID: <20220819125230.42731-4-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: CENTUxRxpjrLobtgkyOYKYw1H2jZ2Pyj X-Proofpoint-GUID: CENTUxRxpjrLobtgkyOYKYw1H2jZ2Pyj X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" The chosen clocking configuration must give an internal MCLK (MCLKint) that is an integer multiple of the sample rate. On I2S each of the supported bit clock frequencies can only be generated from one sample rate group (either the 44100 or the 48000) so the code could use only the bitclock to look up a PLL config. The relationship between sample rate and bitclock frequency is more complex on Soundwire and so it is possible to set a frame shape to generate a bitclock from the "wrong" group. For example 2*147 with a 48000 sample rate would give a bitclock of 14112000 which on I2S could only be derived from a 44100 sample rate. Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/cs42l42.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 1745b83310ac..66c10d24169d 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -649,7 +649,8 @@ static const struct cs42l42_pll_params pll_ratio_table[] = { { 24576000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12288000, 128, 1} }; -static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int clk) +static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int clk, + unsigned int sample_rate) { struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); int i; @@ -664,6 +665,10 @@ static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int } for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) { + /* MCLKint must be a multiple of the sample rate */ + if (pll_ratio_table[i].mclk_int % sample_rate) + continue; + if (pll_ratio_table[i].sclk == clk) { cs42l42->pll_config = i; @@ -889,6 +894,7 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); unsigned int channels = params_channels(params); unsigned int width = (params_width(params) / 8) - 1; + unsigned int sample_rate = params_rate(params); unsigned int slot_width = 0; unsigned int val = 0; unsigned int bclk; @@ -949,11 +955,11 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, break; } - ret = cs42l42_pll_config(component, bclk); + ret = cs42l42_pll_config(component, bclk, sample_rate); if (ret) return ret; - cs42l42_src_config(component, params_rate(params)); + cs42l42_src_config(component, sample_rate); return 0; } From patchwork Fri Aug 19 12:52:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948811 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7B0F4C32771 for ; Fri, 19 Aug 2022 12:54:23 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id C165315F2; Fri, 19 Aug 2022 14:53:31 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C165315F2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913661; bh=zcUbqZgW7PtUZxfy6ieM2KdkGh73/EurAk/BDWW2M1I=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=IEhuP1IbSLoyAQqCyqksAw76YAbVAAaMFSFwWFgfVODoPMGGRYWGUubc6vFBoUtdy RyxycOCEhnb1+ZAK5d8e6T3L2XG+0J1CjNSCmQ2Ju8darKuFe96TmYZ8h0/Y0aBiB6 9XgFRpqn+s39z+b0EZ8WeDp5SgyJVPhO/it1nthY= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 493D3F80529; Fri, 19 Aug 2022 14:52:47 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 30A31F80526; Fri, 19 Aug 2022 14:52:44 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 3E16BF800EE for ; Fri, 19 Aug 2022 14:52:37 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 3E16BF800EE Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="DIFGxJiK" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27JBix0Q020060; Fri, 19 Aug 2022 07:52:36 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=nKtJZgoVT5msd6d2g2FF3eUTwfX6urlD3iU/MkRT4Ow=; b=DIFGxJiK1LabfmgyE6ysA2LXVuQ6SFYPkvYOvc6XP0XOt3vXgCCIfOgYx8eeu7FKCytN +SRg9IMu2MvwreA3vOffGlSEb4U6QGh+AztP6PjLYjITvF4420IUZ7bXhUKydLP03urT ERkaOXndxklQYvBdxV/d8Ec1INJB3YBuMWChXDUej9H7jDORi4flNfMp4hKWzmpPdXsj xvTa/07OhsaLvTL6YXxSBtlD52zctqI7M3KNel+hBUzy595TcPSfHRE5F3p2/JssgacX FjuZ9dCcgOUC/T0Xpi+nE5k4Q4pluS2J2aKrd17qsruU7Rhzyv9cwZUxtExXYgYlgvuM yQ== Received: from ediex02.ad.cirrus.com ([84.19.233.68]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 3hx8cpfuvn-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:36 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:34 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:34 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id A4A43B0E; Fri, 19 Aug 2022 12:52:34 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 04/12] ASoC: cs42l42: Separate ASP config from PLL config Date: Fri, 19 Aug 2022 13:52:22 +0100 Message-ID: <20220819125230.42731-5-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: nlssAeiSidrrLH-vAN240o8wIKYT_HaR X-Proofpoint-GUID: nlssAeiSidrrLH-vAN240o8wIKYT_HaR X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Setup of the ASP (audio serial port) was being done as a side-effect of cs42l42_pll_config() and forces a restriction on the ratio of sample_rate to bit_clock that is invalid for Soundwire. Move the ASP setup into a dedicated function. Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/cs42l42.c | 81 +++++++++++++++++++++----------------- sound/soc/codecs/cs42l42.h | 1 - 2 files changed, 44 insertions(+), 38 deletions(-) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 66c10d24169d..946b2a935256 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -654,7 +654,6 @@ static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int { struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); int i; - u32 fsync; /* Don't reconfigure if there is an audio stream running */ if (cs42l42->stream_use) { @@ -680,40 +679,6 @@ static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int (pll_ratio_table[i].mclk_int != 24000000)) << CS42L42_INTERNAL_FS_SHIFT); - - /* Set up the LRCLK */ - fsync = clk / cs42l42->srate; - if (((fsync * cs42l42->srate) != clk) - || ((fsync % 2) != 0)) { - dev_err(component->dev, - "Unsupported sclk %d/sample rate %d\n", - clk, - cs42l42->srate); - return -EINVAL; - } - /* Set the LRCLK period */ - snd_soc_component_update_bits(component, - CS42L42_FSYNC_P_LOWER, - CS42L42_FSYNC_PERIOD_MASK, - CS42L42_FRAC0_VAL(fsync - 1) << - CS42L42_FSYNC_PERIOD_SHIFT); - snd_soc_component_update_bits(component, - CS42L42_FSYNC_P_UPPER, - CS42L42_FSYNC_PERIOD_MASK, - CS42L42_FRAC1_VAL(fsync - 1) << - CS42L42_FSYNC_PERIOD_SHIFT); - /* Set the LRCLK to 50% duty cycle */ - fsync = fsync / 2; - snd_soc_component_update_bits(component, - CS42L42_FSYNC_PW_LOWER, - CS42L42_FSYNC_PULSE_WIDTH_MASK, - CS42L42_FRAC0_VAL(fsync - 1) << - CS42L42_FSYNC_PULSE_WIDTH_SHIFT); - snd_soc_component_update_bits(component, - CS42L42_FSYNC_PW_UPPER, - CS42L42_FSYNC_PULSE_WIDTH_MASK, - CS42L42_FRAC1_VAL(fsync - 1) << - CS42L42_FSYNC_PULSE_WIDTH_SHIFT); if (pll_ratio_table[i].mclk_src_sel == 0) { /* Pass the clock straight through */ snd_soc_component_update_bits(component, @@ -805,6 +770,46 @@ static void cs42l42_src_config(struct snd_soc_component *component, unsigned int fs << CS42L42_CLK_OASRC_SEL_SHIFT); } +static int cs42l42_asp_config(struct snd_soc_component *component, + unsigned int sclk, unsigned int sample_rate) +{ + u32 fsync = sclk / sample_rate; + + /* Set up the LRCLK */ + if (((fsync * sample_rate) != sclk) || ((fsync % 2) != 0)) { + dev_err(component->dev, + "Unsupported sclk %d/sample rate %d\n", + sclk, + sample_rate); + return -EINVAL; + } + /* Set the LRCLK period */ + snd_soc_component_update_bits(component, + CS42L42_FSYNC_P_LOWER, + CS42L42_FSYNC_PERIOD_MASK, + CS42L42_FRAC0_VAL(fsync - 1) << + CS42L42_FSYNC_PERIOD_SHIFT); + snd_soc_component_update_bits(component, + CS42L42_FSYNC_P_UPPER, + CS42L42_FSYNC_PERIOD_MASK, + CS42L42_FRAC1_VAL(fsync - 1) << + CS42L42_FSYNC_PERIOD_SHIFT); + /* Set the LRCLK to 50% duty cycle */ + fsync = fsync / 2; + snd_soc_component_update_bits(component, + CS42L42_FSYNC_PW_LOWER, + CS42L42_FSYNC_PULSE_WIDTH_MASK, + CS42L42_FRAC0_VAL(fsync - 1) << + CS42L42_FSYNC_PULSE_WIDTH_SHIFT); + snd_soc_component_update_bits(component, + CS42L42_FSYNC_PW_UPPER, + CS42L42_FSYNC_PULSE_WIDTH_MASK, + CS42L42_FRAC1_VAL(fsync - 1) << + CS42L42_FSYNC_PULSE_WIDTH_SHIFT); + + return 0; +} + static int cs42l42_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) { struct snd_soc_component *component = codec_dai->component; @@ -900,8 +905,6 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, unsigned int bclk; int ret; - cs42l42->srate = params_rate(params); - if (cs42l42->sclk) { /* machine driver has set the SCLK */ bclk = cs42l42->sclk; @@ -959,6 +962,10 @@ static int cs42l42_pcm_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; + ret = cs42l42_asp_config(component, bclk, sample_rate); + if (ret) + return ret; + cs42l42_src_config(component, sample_rate); return 0; diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h index b4ba1467c558..2e4e01f9e389 100644 --- a/sound/soc/codecs/cs42l42.h +++ b/sound/soc/codecs/cs42l42.h @@ -31,7 +31,6 @@ struct cs42l42_private { struct mutex irq_lock; int pll_config; u32 sclk; - u32 srate; u8 plug_state; u8 hs_type; u8 ts_inv; From patchwork Fri Aug 19 12:52:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948813 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id AF643C32771 for ; Fri, 19 Aug 2022 12:54:52 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id D2A41166A; Fri, 19 Aug 2022 14:54:00 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D2A41166A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913690; bh=RTyrZjbhQwuV6HNwtdQTfYlJip7B5O5VlDA4stZStqs=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=mMwHSaz2M+136aPtQNthVeZDAkmyBGj9COHgb15fSQSKR7Z3Um34Hpu1pz9p5PGMi Q6GaOq3UdGBxn1ub3I/OiTA9LkJyM/mO5GX3NlY2fhYy6BzLBcC+LR4cvffqm8Mt6F SPpn9y3XlWw//RdHt5JMyNutK8Ej+WI/sXCc84K4= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 195E7F80536; Fri, 19 Aug 2022 14:53:00 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id E2311F80537; Fri, 19 Aug 2022 14:52:50 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 48BDBF801F7 for ; Fri, 19 Aug 2022 14:52:38 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 48BDBF801F7 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="En1JpMJp" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27JBix0R020060; Fri, 19 Aug 2022 07:52:37 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=lx4GAB9Um5dfe7Rhlz40yyU1J88HrCUqmJv6PhWbfXU=; b=En1JpMJpH3HLLQKPGiD/l8+t5r2Y+PQwGq41J853g82pjHy7cdqgkgI72vcvBsukGfoi PvDyouNqj+QWSHYyVLCqW+f6ExD0kYfzOL9bMrftPtuR7zbP0hT89eQX9M3vcHi1BDMp kCxXJLS1TPiWsnI8lirI1zMnn/xQ0KBcBAIwO5hCJTWtyXjKfLv/E/NpVr3VLUwzgjcq UONodQUIX7eK2Nyf/ETLmnudHmM/yLp4Bf0NnG1YORscVBS+pZqaFHcVeC4WJBiEqMUr zYX4wlGKNJ/WpYR5r4I9zv+v//wzs49oiN8pZUrdAhyZc54PctChiXkGoUzplfmDsl+c RQ== Received: from ediex02.ad.cirrus.com ([84.19.233.68]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 3hx8cpfuvn-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:37 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:34 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:34 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id B2874476; Fri, 19 Aug 2022 12:52:34 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 05/12] ASoC: cs42l42: Use cs42l42->dev instead of &i2c_client->dev Date: Fri, 19 Aug 2022 13:52:23 +0100 Message-ID: <20220819125230.42731-6-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: osanZQ1CaN8e6fU7t7wsdiq0TeoF9Ic9 X-Proofpoint-GUID: osanZQ1CaN8e6fU7t7wsdiq0TeoF9Ic9 X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" In preparation for splitting cs42l42_i2c_probe() into multiple functions replace use of &i2c_client->dev with cs42l42->dev. This reduces diff clutter in the patch that splits the function. Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/cs42l42.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 946b2a935256..4c81bda6b593 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -2233,7 +2233,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); if (IS_ERR(cs42l42->regmap)) { ret = PTR_ERR(cs42l42->regmap); - dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); + dev_err(cs42l42->dev, "regmap_init() failed: %d\n", ret); return ret; } @@ -2241,11 +2241,11 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) for (i = 0; i < ARRAY_SIZE(cs42l42->supplies); i++) cs42l42->supplies[i].supply = cs42l42_supply_names[i]; - ret = devm_regulator_bulk_get(&i2c_client->dev, + ret = devm_regulator_bulk_get(cs42l42->dev, ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); if (ret != 0) { - dev_err(&i2c_client->dev, + dev_err(cs42l42->dev, "Failed to request supplies: %d\n", ret); return ret; } @@ -2253,13 +2253,13 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) ret = regulator_bulk_enable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); if (ret != 0) { - dev_err(&i2c_client->dev, + dev_err(cs42l42->dev, "Failed to enable supplies: %d\n", ret); return ret; } /* Reset the Device */ - cs42l42->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev, + cs42l42->reset_gpio = devm_gpiod_get_optional(cs42l42->dev, "reset", GPIOD_OUT_LOW); if (IS_ERR(cs42l42->reset_gpio)) { ret = PTR_ERR(cs42l42->reset_gpio); @@ -2267,7 +2267,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) } if (cs42l42->reset_gpio) { - dev_dbg(&i2c_client->dev, "Found reset GPIO\n"); + dev_dbg(cs42l42->dev, "Found reset GPIO\n"); gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); } usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); @@ -2281,7 +2281,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) if (ret == -EPROBE_DEFER) { goto err_disable_noirq; } else if (ret != 0) { - dev_err(&i2c_client->dev, + dev_err(cs42l42->dev, "Failed to request IRQ: %d\n", ret); goto err_disable_noirq; } @@ -2291,13 +2291,13 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) devid = cirrus_read_device_id(cs42l42->regmap, CS42L42_DEVID_AB); if (devid < 0) { ret = devid; - dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret); + dev_err(cs42l42->dev, "Failed to read device ID: %d\n", ret); goto err_disable; } if (devid != CS42L42_CHIP_ID) { ret = -ENODEV; - dev_err(&i2c_client->dev, + dev_err(cs42l42->dev, "CS42L42 Device ID (%X). Expected %X\n", devid, CS42L42_CHIP_ID); goto err_disable; @@ -2305,11 +2305,11 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) ret = regmap_read(cs42l42->regmap, CS42L42_REVID, ®); if (ret < 0) { - dev_err(&i2c_client->dev, "Get Revision ID failed\n"); + dev_err(cs42l42->dev, "Get Revision ID failed\n"); goto err_shutdown; } - dev_info(&i2c_client->dev, + dev_info(cs42l42->dev, "Cirrus Logic CS42L42, Revision: %02X\n", reg & 0xFF); /* Power up the codec */ @@ -2329,7 +2329,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) (1 << CS42L42_ADC_PDN_SHIFT) | (0 << CS42L42_PDN_ALL_SHIFT)); - ret = cs42l42_handle_device_data(&i2c_client->dev, cs42l42); + ret = cs42l42_handle_device_data(cs42l42->dev, cs42l42); if (ret != 0) goto err_shutdown; @@ -2340,7 +2340,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) cs42l42_set_interrupt_masks(cs42l42); /* Register codec for machine driver */ - ret = devm_snd_soc_register_component(&i2c_client->dev, + ret = devm_snd_soc_register_component(cs42l42->dev, &soc_component_dev_cs42l42, &cs42l42_dai, 1); if (ret < 0) goto err_shutdown; From patchwork Fri Aug 19 12:52:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948812 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EAADBC32771 for ; Fri, 19 Aug 2022 12:54:32 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 1C4881654; Fri, 19 Aug 2022 14:53:41 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 1C4881654 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913671; bh=itPQawQLraQcXYBNz1Um7sXoU5qZsKBlb26UGh7sMJk=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Nm00I9nEdzJn8WrK0PdQMLX8IavYJpnQbmnkkEX++yibnZRVPriYmKQf1bMZp/ZD7 W9od8gwJp+O7GNnEqDwqyWcGLxDVfXqd7xStkQVVX4TVDpqatiO6utktdlewA0Iz9/ kCV6ivKjBP7QlDvEEdq8lCKdU0xPgorcvAt0kAOY= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 1716FF804AA; Fri, 19 Aug 2022 14:52:52 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 3F370F80548; Fri, 19 Aug 2022 14:52:50 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 1CB08F8051D for ; Fri, 19 Aug 2022 14:52:39 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 1CB08F8051D Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="K9j16F6e" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27J5opPp018534; Fri, 19 Aug 2022 07:52:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=YPyYO+awQHghfR5w93OJCOFA7k5aAerbXnMIQeWLp5A=; b=K9j16F6ezJxWBt/sadmesYYpHAHoAOIPeLtmUGURT/5PgKSZIxUrTZV/UnpjNwqnY06y EKABZs5pJ48biDn2UK7d3ptKSkLNFvHwb9+arnBf0yYuShNYPA8Q992fwcmAxBrpKZWn 2L2yyMDlJqDaAh0UCWr+YSrxCotDbLQpNg2msFqI2obQnl25WpnhM0pOODE5E5f/ogZc ILMGR5RtggrlUUw5rarDEjTMz1bkf/cOKo72heNM8VSirF9x8+OPEBR/QtqPaHP1w0Hs fl+zBgL1zrxqri7aGrqP19Jg8Tobb7vjGjqLI+OUfC5xNnJPdzA2KtMVhxLmbea9zNA1 EA== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3hx9c1yrtp-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:38 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:34 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:34 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id C185AB16; Fri, 19 Aug 2022 12:52:34 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 06/12] ASoC: cs42l42: Split probe() and remove() into stages Date: Fri, 19 Aug 2022 13:52:24 +0100 Message-ID: <20220819125230.42731-7-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: FKvqLhMu-RBxZOc4NIsvBBQcU5Mrtsnf X-Proofpoint-GUID: FKvqLhMu-RBxZOc4NIsvBBQcU5Mrtsnf X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" To prepare for adding Soundwire the probe must be split into three parts: 1) The bus-specific probe 2) Common bus-agnostic probe steps 3) Initialization of the peripheral registers Step (3) must be separate because on Soundwire devices the probe must enable power supplies and release reset so that the peripheral can be enumerated by the bus, but it isn't possible to access registers until enumeration has completed. The call to devm_snd_soc_register_component() must be done at stage (2) so that it can EPROBE_DEFER if necessary. In Soundwire systems stage (3) is not a probe event so a deferral at this stage would not result in re-probing dependencies. A new init_done flag indicates that the chip has been identified and initialized. This is used to prevent cs42l42_remove(), cs42l42_suspend(), cs42l42_restore() and cs42l42_irq_thread() from attempting register accesses if the chip was not successfully initialized. Although this cannot happen on I2C, because the entire probe would fail, it is possible on Soundwire if probe succeeds but the cs42l42 is never enumerated. Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/cs42l42.c | 122 +++++++++++++++++++++++++------------ sound/soc/codecs/cs42l42.h | 2 + 2 files changed, 84 insertions(+), 40 deletions(-) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 4c81bda6b593..8c5909a43df6 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -1641,7 +1641,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) unsigned int i; mutex_lock(&cs42l42->irq_lock); - if (cs42l42->suspended) { + if (cs42l42->suspended || !cs42l42->init_done) { mutex_unlock(&cs42l42->irq_lock); return IRQ_NONE; } @@ -2215,28 +2215,13 @@ static int __maybe_unused cs42l42_resume(struct device *dev) return 0; } -static int cs42l42_i2c_probe(struct i2c_client *i2c_client) +static int cs42l42_common_probe(struct cs42l42_private *cs42l42) { - struct cs42l42_private *cs42l42; - int ret, i, devid; - unsigned int reg; - - cs42l42 = devm_kzalloc(&i2c_client->dev, sizeof(struct cs42l42_private), - GFP_KERNEL); - if (!cs42l42) - return -ENOMEM; + int ret, i; - cs42l42->dev = &i2c_client->dev; - i2c_set_clientdata(i2c_client, cs42l42); + dev_set_drvdata(cs42l42->dev, cs42l42); mutex_init(&cs42l42->irq_lock); - cs42l42->regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); - if (IS_ERR(cs42l42->regmap)) { - ret = PTR_ERR(cs42l42->regmap); - dev_err(cs42l42->dev, "regmap_init() failed: %d\n", ret); - return ret; - } - BUILD_BUG_ON(ARRAY_SIZE(cs42l42_supply_names) != ARRAY_SIZE(cs42l42->supplies)); for (i = 0; i < ARRAY_SIZE(cs42l42->supplies); i++) cs42l42->supplies[i].supply = cs42l42_supply_names[i]; @@ -2273,8 +2258,8 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); /* Request IRQ if one was specified */ - if (i2c_client->irq) { - ret = request_threaded_irq(i2c_client->irq, + if (cs42l42->irq) { + ret = request_threaded_irq(cs42l42->irq, NULL, cs42l42_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW, "cs42l42", cs42l42); @@ -2287,6 +2272,32 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) } } + /* Register codec now so it can EPROBE_DEFER */ + ret = devm_snd_soc_register_component(cs42l42->dev, + &soc_component_dev_cs42l42, + &cs42l42_dai, 1); + if (ret < 0) + goto err; + + return 0; + +err: + if (cs42l42->irq) + free_irq(cs42l42->irq, cs42l42); + +err_disable_noirq: + gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); +err_disable_noreset: + regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); + + return ret; +} + +static int cs42l42_init(struct cs42l42_private *cs42l42) +{ + unsigned int reg; + int devid, ret; + /* initialize codec */ devid = cirrus_read_device_id(cs42l42->regmap, CS42L42_DEVID_AB); if (devid < 0) { @@ -2336,15 +2347,15 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) /* Setup headset detection */ cs42l42_setup_hs_type_detect(cs42l42); + /* + * Set init_done before unmasking interrupts so any triggered + * immediately will be handled. + */ + cs42l42->init_done = true; + /* Mask/Unmask Interrupts */ cs42l42_set_interrupt_masks(cs42l42); - /* Register codec for machine driver */ - ret = devm_snd_soc_register_component(cs42l42->dev, - &soc_component_dev_cs42l42, &cs42l42_dai, 1); - if (ret < 0) - goto err_shutdown; - return 0; err_shutdown: @@ -2353,34 +2364,65 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) regmap_write(cs42l42->regmap, CS42L42_PWR_CTL1, 0xff); err_disable: - if (i2c_client->irq) - free_irq(i2c_client->irq, cs42l42); - -err_disable_noirq: gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); -err_disable_noreset: regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); return ret; } -static int cs42l42_i2c_remove(struct i2c_client *i2c_client) +static void cs42l42_common_remove(struct cs42l42_private *cs42l42) { - struct cs42l42_private *cs42l42 = i2c_get_clientdata(i2c_client); - - if (i2c_client->irq) - free_irq(i2c_client->irq, cs42l42); + if (cs42l42->irq) + free_irq(cs42l42->irq, cs42l42); /* * The driver might not have control of reset and power supplies, * so ensure that the chip internals are powered down. */ - regmap_write(cs42l42->regmap, CS42L42_CODEC_INT_MASK, 0xff); - regmap_write(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK, 0xff); - regmap_write(cs42l42->regmap, CS42L42_PWR_CTL1, 0xff); + if (cs42l42->init_done) { + regmap_write(cs42l42->regmap, CS42L42_CODEC_INT_MASK, 0xff); + regmap_write(cs42l42->regmap, CS42L42_TSRS_PLUG_INT_MASK, 0xff); + regmap_write(cs42l42->regmap, CS42L42_PWR_CTL1, 0xff); + } gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); +} + +static int cs42l42_i2c_probe(struct i2c_client *i2c_client) +{ + struct device *dev = &i2c_client->dev; + struct cs42l42_private *cs42l42; + struct regmap *regmap; + int ret; + + cs42l42 = devm_kzalloc(dev, sizeof(struct cs42l42_private), GFP_KERNEL); + if (!cs42l42) + return -ENOMEM; + + regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); + return ret; + } + + cs42l42->dev = dev; + cs42l42->regmap = regmap; + cs42l42->irq = i2c_client->irq; + + ret = cs42l42_common_probe(cs42l42); + if (ret) + return ret; + + return cs42l42_init(cs42l42); +} + +static int cs42l42_i2c_remove(struct i2c_client *i2c_client) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(&i2c_client->dev); + + cs42l42_common_remove(cs42l42); return 0; } diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h index 2e4e01f9e389..4ee61136080d 100644 --- a/sound/soc/codecs/cs42l42.h +++ b/sound/soc/codecs/cs42l42.h @@ -29,6 +29,7 @@ struct cs42l42_private { struct completion pdn_done; struct snd_soc_jack *jack; struct mutex irq_lock; + int irq; int pll_config; u32 sclk; u8 plug_state; @@ -45,6 +46,7 @@ struct cs42l42_private { u8 stream_use; bool hp_adc_up_pending; bool suspended; + bool init_done; }; #endif /* __CS42L42_H__ */ From patchwork Fri Aug 19 12:52:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948816 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1A77FC32771 for ; Fri, 19 Aug 2022 12:55:39 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 528D3167B; Fri, 19 Aug 2022 14:54:47 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 528D3167B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913737; bh=D1kHjFDGWR55eI090Igh4yS/xGLuhWZKvwKl3OC4GGM=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=CNUsbK5DZAVwbtdvMq2WtosdH2v2geMoA0bJsdpqVfgXW0j2myEqRhdcDMRDby56K wVOuFBDQ1ChW1fFP3an0OLVhJVCsvDRT4OrDjXTUGzg1dbDF7RN5fLRzAbjV1J6et1 kW0uvfyjDmN8k2sfTZzEco36Y7StDtAuviSsmVe0= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id C0BCDF8055B; Fri, 19 Aug 2022 14:53:01 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 8FF39F802A0; Fri, 19 Aug 2022 14:52:51 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 42E91F80217 for ; Fri, 19 Aug 2022 14:52:40 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 42E91F80217 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="q1RjZTQ0" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27J5opPq018534; Fri, 19 Aug 2022 07:52:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=+gFYFK2eJJEQkMu7BpUm9DSh8dHugunj12u4pVcE2IU=; b=q1RjZTQ0Aj4+EjAcAmUALLbzXX90u9GIl0PJHfGOFyOVsY1x3avmgAmKQSb3tm1blv+1 87eZdoh5gDN1/q7hvHJhdRl55Mcc9IukYNFloeGcMlKV5oY1RDUFIx+8G9WFvFiPD0Fl cIxL5ruScTpCWo7515dAyUxWyHZAIZvwzNTPqxfN0ZW4xyXUhdBf1VgPcz5nlFtN7U7P e/0ZQtoI4xNHLuFVq9voRB+vtDeo9BLvdHcShrg6aiFpoRpTxl/zaaMUAL6DIU8H0Vum upEOiwoUnLLQifGYKj3UgGKz3eABAEiOMyF6LumJw6NBVev6bAtL0WsFlLNRwiRh7o3X UA== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3hx9c1yrtp-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:38 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:34 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:34 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id D1AB57C; Fri, 19 Aug 2022 12:52:34 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 07/12] ASoC: cs42l42: Split cs42l42_resume into two functions Date: Fri, 19 Aug 2022 13:52:25 +0100 Message-ID: <20220819125230.42731-8-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: JJqG-086Y1AL889Nmp1m-P6S33t_WIV- X-Proofpoint-GUID: JJqG-086Y1AL889Nmp1m-P6S33t_WIV- X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" On Soundwire the system resume cannot restore registers until the host controller has re-enumerated the peripheral. This patch splits cs42l42_resume() into two functions, one to power up and the other to restore registers, ready for adding Soundwire support. Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/cs42l42.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 8c5909a43df6..54fe92b3d4da 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -2199,6 +2199,15 @@ static int __maybe_unused cs42l42_resume(struct device *dev) gpiod_set_value_cansleep(cs42l42->reset_gpio, 1); usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); + dev_dbg(dev, "System resume powered up\n"); + + return 0; +} + +static void __maybe_unused cs42l42_resume_restore(struct device *dev) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); + regcache_cache_only(cs42l42->regmap, false); regcache_mark_dirty(cs42l42->regmap); @@ -2211,6 +2220,17 @@ static int __maybe_unused cs42l42_resume(struct device *dev) mutex_unlock(&cs42l42->irq_lock); dev_dbg(dev, "System resumed\n"); +} + +static int __maybe_unused cs42l42_i2c_resume(struct device *dev) +{ + int ret; + + ret = cs42l42_resume(dev); + if (ret) + return ret; + + cs42l42_resume_restore(dev); return 0; } @@ -2428,7 +2448,7 @@ static int cs42l42_i2c_remove(struct i2c_client *i2c_client) } static const struct dev_pm_ops cs42l42_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_resume) + SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_i2c_resume) }; #ifdef CONFIG_OF From patchwork Fri Aug 19 12:52:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948818 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6FE5CC32773 for ; Fri, 19 Aug 2022 12:56:07 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 32FE1168D; Fri, 19 Aug 2022 14:55:15 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 32FE1168D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913765; bh=S54zb0JN0Lmqd8fVYMmqNAQVJMBNAOd7QFj3BaAkkHs=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=WunvlWdG+TTpi0XNX5Z5LafxJPeLQX0CiqeMS1jXQuuJRRrzLqaOEM7sLlqlzioyY pgdk6YDtY1zPLH3ulOtxPcW2P257OG1YSK2nmgMyM+WaYIYI3zuTEE8nCNB6nJDsQG c5K9FDZob+Qg1aYYb0wydtBmWSOZnIaJyJPAqBCc= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 066ACF80571; Fri, 19 Aug 2022 14:53:03 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 371BFF80548; Fri, 19 Aug 2022 14:52:56 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 2864DF8051F for ; Fri, 19 Aug 2022 14:52:41 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 2864DF8051F Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="FQBCrOln" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27J5opPr018534; Fri, 19 Aug 2022 07:52:39 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=JrQz8U2kQSkG9W2JP8isxUQBimIOKpbs46CPxYXbzho=; b=FQBCrOlnyPFf2KyUBBjEriKswsGXkve1OAk30YFwF4lGe8zTIjB/h+nwGK5bBKHUdVjQ U84NRqvPVHoiM+9zPXcDo5b9OxJBQ1wa7K9Ci6PPnDuNo5ZTAYo1oABPI8t/NC8JeeFB 9XVtN6jEUdsIDMqcKzune/JIEM6+F2u2F7Mq6HtRUovLqsOJkkchhD/Gfh7PvsY+CP2C 7m7t1zzcFt/OTjX2k8oaSxX+GVja62bFDyUVTsXIA8mMXEXlSY/HN5Nm9Tsfnptn9Ax+ rKnK3nWXVqTVHmOI+B3Y9pujRS3LJPpOMzeOhOmvxrHhCYYvTFKqwnvb6nqvWrulv/IO 6Q== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3hx9c1yrtp-5 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:39 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:34 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:34 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id DF35EB0E; Fri, 19 Aug 2022 12:52:34 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 08/12] ASoC: cs42l42: Pass component and dai defs into common probe Date: Fri, 19 Aug 2022 13:52:26 +0100 Message-ID: <20220819125230.42731-9-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: Etj4c4q5FLOqg6QqrN5hFOQ0UtwdLEhA X-Proofpoint-GUID: Etj4c4q5FLOqg6QqrN5hFOQ0UtwdLEhA X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Pass pointers to snd_soc_component_driver and snd_soc_dai_driver objects into cs42l42_common_probe(). This is in preparation for adding Soundwire support. Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/cs42l42.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 54fe92b3d4da..a98b4e6a1f05 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -581,7 +581,7 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_ return 0; } -static const struct snd_soc_component_driver soc_component_dev_cs42l42 = { +static const struct snd_soc_component_driver cs42l42_soc_component = { .set_jack = cs42l42_set_jack, .dapm_widgets = cs42l42_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets), @@ -2235,7 +2235,9 @@ static int __maybe_unused cs42l42_i2c_resume(struct device *dev) return 0; } -static int cs42l42_common_probe(struct cs42l42_private *cs42l42) +static int cs42l42_common_probe(struct cs42l42_private *cs42l42, + const struct snd_soc_component_driver *component_drv, + struct snd_soc_dai_driver *dai) { int ret, i; @@ -2293,9 +2295,7 @@ static int cs42l42_common_probe(struct cs42l42_private *cs42l42) } /* Register codec now so it can EPROBE_DEFER */ - ret = devm_snd_soc_register_component(cs42l42->dev, - &soc_component_dev_cs42l42, - &cs42l42_dai, 1); + ret = devm_snd_soc_register_component(cs42l42->dev, component_drv, dai, 1); if (ret < 0) goto err; @@ -2431,7 +2431,7 @@ static int cs42l42_i2c_probe(struct i2c_client *i2c_client) cs42l42->regmap = regmap; cs42l42->irq = i2c_client->irq; - ret = cs42l42_common_probe(cs42l42); + ret = cs42l42_common_probe(cs42l42, &cs42l42_soc_component, &cs42l42_dai); if (ret) return ret; From patchwork Fri Aug 19 12:52:27 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948815 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6C04DC32774 for ; Fri, 19 Aug 2022 12:55:23 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id B666E1679; Fri, 19 Aug 2022 14:54:31 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B666E1679 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913721; bh=qWAhwXKSqPI44EZbSQw4mEbUaUUHPxA+r6IERv7mYY4=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=LC9yfvMVnf7YlO4EHpuq7iPBvbXDIleb+jh+u2jkLS6SczCCGPj/Nj6vgvSXz5yjs qMFbaZmvI02nlHBklLPF30+kPYRk7m+XJOtByF3KVP1cbIw9ZHjC2uiLBqdMvMhTEF NxJk8CdBPNn2XLKxzz7IcQbf+7BoZbGCTBMFlSYw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 30172F80552; Fri, 19 Aug 2022 14:53:01 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 7FA3BF8051D; Fri, 19 Aug 2022 14:52:51 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0b-001ae601.pphosted.com [67.231.152.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B3E3EF804AA for ; Fri, 19 Aug 2022 14:52:39 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz B3E3EF804AA Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="dZ1WRbqZ" Received: from pps.filterd (m0077474.ppops.net [127.0.0.1]) by mx0b-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27JBix0S020060; Fri, 19 Aug 2022 07:52:38 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=RZL29OjwV5PFxm0BnfsgDRypvNSBM+O0AcZH0B1Zgog=; b=dZ1WRbqZloKqN3voZMe++m5y9GJG2p2TAwN0L3RptPXJ2lZAKzNNMhIXXA6pwLX4L3lB K2SEMqizp9pBhnhN4JreqlEWbFIUFFBX7QzVi8hXExZWG2MEsqRUCZ1iL2fgCTIDCPau 19vt2q5YGYzmjbhvdsv7md6uT3j30Rg2KqvzI7ajUbNp9dBkRfGgwEeowFEHqsa1WS6y 88Qjbf+P6TvIS1hxRHdOcepvl9PAq7nb94f3KxijLeA63QiHuPkQFz5FlSWXQm4r00tk 6ZTa9CQhOJqsFd2GLWsu+GKW7hF+epPErEPBT4EL8/yCXW0Ysyk5thUHGgutGRXaKjRW iA== Received: from ediex02.ad.cirrus.com ([84.19.233.68]) by mx0b-001ae601.pphosted.com (PPS) with ESMTPS id 3hx8cpfuvn-4 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:37 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex02.ad.cirrus.com (198.61.84.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:35 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:35 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id ED07211DA; Fri, 19 Aug 2022 12:52:34 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 09/12] ASoC: cs42l42: Split I2C identity into separate module Date: Fri, 19 Aug 2022 13:52:27 +0100 Message-ID: <20220819125230.42731-10-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: h6HfXATwKNChB_7E_GkkkiA8PxbIwRlS X-Proofpoint-GUID: h6HfXATwKNChB_7E_GkkkiA8PxbIwRlS X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Split the I2C bus driver definition and probe()/remove() into a separate module so that a Soundwire build of CS42L42 support does not have a spurious dependency on I2C. Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/Kconfig | 8 ++- sound/soc/codecs/Makefile | 4 +- sound/soc/codecs/cs42l42-i2c.c | 107 +++++++++++++++++++++++++++++++ sound/soc/codecs/cs42l42.c | 111 ++++++--------------------------- sound/soc/codecs/cs42l42.h | 15 +++++ 5 files changed, 152 insertions(+), 93 deletions(-) create mode 100644 sound/soc/codecs/cs42l42-i2c.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index d16b4efb88a7..9f6f0f97cfb9 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -690,9 +690,15 @@ config SND_SOC_CS35L45_I2C Enable support for Cirrus Logic CS35L45 smart speaker amplifier with I2C control. +config SND_SOC_CS42L42_CORE + tristate + config SND_SOC_CS42L42 - tristate "Cirrus Logic CS42L42 CODEC" + tristate "Cirrus Logic CS42L42 CODEC (I2C)" depends on I2C + select REGMAP + select REGMAP_I2C + select SND_SOC_CS42L42_CORE config SND_SOC_CS42L51 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 92fd441d426a..d91f3c1fc2b3 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -65,6 +65,7 @@ snd-soc-cs35l45-objs := cs35l45.o snd-soc-cs35l45-spi-objs := cs35l45-spi.o snd-soc-cs35l45-i2c-objs := cs35l45-i2c.o snd-soc-cs42l42-objs := cs42l42.o +snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o snd-soc-cs42l51-objs := cs42l51.o snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o snd-soc-cs42l52-objs := cs42l52.o @@ -419,7 +420,8 @@ obj-$(CONFIG_SND_SOC_CS35L45_TABLES) += snd-soc-cs35l45-tables.o obj-$(CONFIG_SND_SOC_CS35L45) += snd-soc-cs35l45.o obj-$(CONFIG_SND_SOC_CS35L45_SPI) += snd-soc-cs35l45-spi.o obj-$(CONFIG_SND_SOC_CS35L45_I2C) += snd-soc-cs35l45-i2c.o -obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42.o +obj-$(CONFIG_SND_SOC_CS42L42_CORE) += snd-soc-cs42l42.o +obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42-i2c.o obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o diff --git a/sound/soc/codecs/cs42l42-i2c.c b/sound/soc/codecs/cs42l42-i2c.c new file mode 100644 index 000000000000..5f01b6adc17e --- /dev/null +++ b/sound/soc/codecs/cs42l42-i2c.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * cs42l42-i2c.c -- CS42L42 ALSA SoC audio driver for I2C + * + * Copyright 2016, 2022 Cirrus Logic, Inc. + */ + +#include +#include +#include +#include +#include + +#include "cs42l42.h" + +static int cs42l42_i2c_probe(struct i2c_client *i2c_client) +{ + struct device *dev = &i2c_client->dev; + struct cs42l42_private *cs42l42; + struct regmap *regmap; + int ret; + + cs42l42 = devm_kzalloc(dev, sizeof(*cs42l42), GFP_KERNEL); + if (!cs42l42) + return -ENOMEM; + + regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); + dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); + return ret; + } + + cs42l42->dev = dev; + cs42l42->regmap = regmap; + cs42l42->irq = i2c_client->irq; + + ret = cs42l42_common_probe(cs42l42, &cs42l42_soc_component, &cs42l42_dai); + if (ret) + return ret; + + return cs42l42_init(cs42l42); +} + +static int cs42l42_i2c_remove(struct i2c_client *i2c_client) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(&i2c_client->dev); + + cs42l42_common_remove(cs42l42); + + return 0; +} + +static int __maybe_unused cs42l42_i2c_resume(struct device *dev) +{ + int ret; + + ret = cs42l42_resume(dev); + if (ret) + return ret; + + cs42l42_resume_restore(dev); + + return 0; +} + +static const struct dev_pm_ops cs42l42_i2c_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_i2c_resume) +}; + +static const struct of_device_id __maybe_unused cs42l42_of_match[] = { + { .compatible = "cirrus,cs42l42", }, + {} +}; +MODULE_DEVICE_TABLE(of, cs42l42_of_match); + +static const struct acpi_device_id __maybe_unused cs42l42_acpi_match[] = { + {"10134242", 0,}, + {} +}; +MODULE_DEVICE_TABLE(acpi, cs42l42_acpi_match); + +static const struct i2c_device_id cs42l42_id[] = { + {"cs42l42", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, cs42l42_id); + +static struct i2c_driver cs42l42_i2c_driver = { + .driver = { + .name = "cs42l42", + .pm = &cs42l42_i2c_pm_ops, + .of_match_table = of_match_ptr(cs42l42_of_match), + .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), + }, + .id_table = cs42l42_id, + .probe_new = cs42l42_i2c_probe, + .remove = cs42l42_i2c_remove, +}; + +module_i2c_driver(cs42l42_i2c_driver); + +MODULE_DESCRIPTION("ASoC CS42L42 I2C driver"); +MODULE_AUTHOR("Richard Fitzgerald "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(SND_SOC_CS42L42_CORE); diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index a98b4e6a1f05..7f16de593424 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include @@ -377,7 +376,7 @@ static const struct regmap_range_cfg cs42l42_page_range = { .window_len = 256, }; -static const struct regmap_config cs42l42_regmap = { +const struct regmap_config cs42l42_regmap = { .reg_bits = 8, .val_bits = 8, @@ -395,6 +394,7 @@ static const struct regmap_config cs42l42_regmap = { .use_single_read = true, .use_single_write = true, }; +EXPORT_SYMBOL_NS_GPL(cs42l42_regmap, SND_SOC_CS42L42_CORE); static DECLARE_TLV_DB_SCALE(adc_tlv, -9700, 100, true); static DECLARE_TLV_DB_SCALE(mixer_tlv, -6300, 100, true); @@ -581,7 +581,7 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_ return 0; } -static const struct snd_soc_component_driver cs42l42_soc_component = { +const struct snd_soc_component_driver cs42l42_soc_component = { .set_jack = cs42l42_set_jack, .dapm_widgets = cs42l42_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(cs42l42_dapm_widgets), @@ -592,6 +592,7 @@ static const struct snd_soc_component_driver cs42l42_soc_component = { .idle_bias_on = 1, .endianness = 1, }; +EXPORT_SYMBOL_NS_GPL(cs42l42_soc_component, SND_SOC_CS42L42_CORE); /* Switch to SCLK. Atomic delay after the write to allow the switch to complete. */ static const struct reg_sequence cs42l42_to_sclk_seq[] = { @@ -1101,7 +1102,7 @@ static const struct snd_soc_dai_ops cs42l42_ops = { .mute_stream = cs42l42_mute_stream, }; -static struct snd_soc_dai_driver cs42l42_dai = { +struct snd_soc_dai_driver cs42l42_dai = { .name = "cs42l42", .playback = { .stream_name = "Playback", @@ -1121,6 +1122,7 @@ static struct snd_soc_dai_driver cs42l42_dai = { .symmetric_sample_bits = 1, .ops = &cs42l42_ops, }; +EXPORT_SYMBOL_NS_GPL(cs42l42_dai, SND_SOC_CS42L42_CORE); static void cs42l42_manual_hs_type_detect(struct cs42l42_private *cs42l42) { @@ -2116,7 +2118,7 @@ static const struct reg_sequence __maybe_unused cs42l42_shutdown_seq[] = { REG_SEQ0(CS42L42_PWR_CTL1, 0xFF) }; -static int __maybe_unused cs42l42_suspend(struct device *dev) +int cs42l42_suspend(struct device *dev) { struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); unsigned int reg; @@ -2176,8 +2178,9 @@ static int __maybe_unused cs42l42_suspend(struct device *dev) return 0; } +EXPORT_SYMBOL_NS_GPL(cs42l42_suspend, SND_SOC_CS42L42_CORE); -static int __maybe_unused cs42l42_resume(struct device *dev) +int cs42l42_resume(struct device *dev) { struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); int ret; @@ -2203,8 +2206,9 @@ static int __maybe_unused cs42l42_resume(struct device *dev) return 0; } +EXPORT_SYMBOL_NS_GPL(cs42l42_resume, SND_SOC_CS42L42_CORE); -static void __maybe_unused cs42l42_resume_restore(struct device *dev) +void cs42l42_resume_restore(struct device *dev) { struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); @@ -2221,6 +2225,7 @@ static void __maybe_unused cs42l42_resume_restore(struct device *dev) dev_dbg(dev, "System resumed\n"); } +EXPORT_SYMBOL_NS_GPL(cs42l42_resume_restore, SND_SOC_CS42L42_CORE); static int __maybe_unused cs42l42_i2c_resume(struct device *dev) { @@ -2235,9 +2240,9 @@ static int __maybe_unused cs42l42_i2c_resume(struct device *dev) return 0; } -static int cs42l42_common_probe(struct cs42l42_private *cs42l42, - const struct snd_soc_component_driver *component_drv, - struct snd_soc_dai_driver *dai) +int cs42l42_common_probe(struct cs42l42_private *cs42l42, + const struct snd_soc_component_driver *component_drv, + struct snd_soc_dai_driver *dai) { int ret, i; @@ -2312,8 +2317,9 @@ static int cs42l42_common_probe(struct cs42l42_private *cs42l42, return ret; } +EXPORT_SYMBOL_NS_GPL(cs42l42_common_probe, SND_SOC_CS42L42_CORE); -static int cs42l42_init(struct cs42l42_private *cs42l42) +int cs42l42_init(struct cs42l42_private *cs42l42) { unsigned int reg; int devid, ret; @@ -2389,8 +2395,9 @@ static int cs42l42_init(struct cs42l42_private *cs42l42) cs42l42->supplies); return ret; } +EXPORT_SYMBOL_NS_GPL(cs42l42_init, SND_SOC_CS42L42_CORE); -static void cs42l42_common_remove(struct cs42l42_private *cs42l42) +void cs42l42_common_remove(struct cs42l42_private *cs42l42) { if (cs42l42->irq) free_irq(cs42l42->irq, cs42l42); @@ -2408,85 +2415,7 @@ static void cs42l42_common_remove(struct cs42l42_private *cs42l42) gpiod_set_value_cansleep(cs42l42->reset_gpio, 0); regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies), cs42l42->supplies); } - -static int cs42l42_i2c_probe(struct i2c_client *i2c_client) -{ - struct device *dev = &i2c_client->dev; - struct cs42l42_private *cs42l42; - struct regmap *regmap; - int ret; - - cs42l42 = devm_kzalloc(dev, sizeof(struct cs42l42_private), GFP_KERNEL); - if (!cs42l42) - return -ENOMEM; - - regmap = devm_regmap_init_i2c(i2c_client, &cs42l42_regmap); - if (IS_ERR(regmap)) { - ret = PTR_ERR(regmap); - dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); - return ret; - } - - cs42l42->dev = dev; - cs42l42->regmap = regmap; - cs42l42->irq = i2c_client->irq; - - ret = cs42l42_common_probe(cs42l42, &cs42l42_soc_component, &cs42l42_dai); - if (ret) - return ret; - - return cs42l42_init(cs42l42); -} - -static int cs42l42_i2c_remove(struct i2c_client *i2c_client) -{ - struct cs42l42_private *cs42l42 = dev_get_drvdata(&i2c_client->dev); - - cs42l42_common_remove(cs42l42); - - return 0; -} - -static const struct dev_pm_ops cs42l42_pm_ops = { - SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_i2c_resume) -}; - -#ifdef CONFIG_OF -static const struct of_device_id cs42l42_of_match[] = { - { .compatible = "cirrus,cs42l42", }, - {} -}; -MODULE_DEVICE_TABLE(of, cs42l42_of_match); -#endif - -#ifdef CONFIG_ACPI -static const struct acpi_device_id cs42l42_acpi_match[] = { - {"10134242", 0,}, - {} -}; -MODULE_DEVICE_TABLE(acpi, cs42l42_acpi_match); -#endif - -static const struct i2c_device_id cs42l42_id[] = { - {"cs42l42", 0}, - {} -}; - -MODULE_DEVICE_TABLE(i2c, cs42l42_id); - -static struct i2c_driver cs42l42_i2c_driver = { - .driver = { - .name = "cs42l42", - .pm = &cs42l42_pm_ops, - .of_match_table = of_match_ptr(cs42l42_of_match), - .acpi_match_table = ACPI_PTR(cs42l42_acpi_match), - }, - .id_table = cs42l42_id, - .probe_new = cs42l42_i2c_probe, - .remove = cs42l42_i2c_remove, -}; - -module_i2c_driver(cs42l42_i2c_driver); +EXPORT_SYMBOL_NS_GPL(cs42l42_common_remove, SND_SOC_CS42L42_CORE); MODULE_DESCRIPTION("ASoC CS42L42 driver"); MODULE_AUTHOR("James Schulman, Cirrus Logic Inc, "); diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h index 4ee61136080d..942054434afd 100644 --- a/sound/soc/codecs/cs42l42.h +++ b/sound/soc/codecs/cs42l42.h @@ -20,6 +20,8 @@ #include #include #include +#include +#include struct cs42l42_private { struct regmap *regmap; @@ -49,4 +51,17 @@ struct cs42l42_private { bool init_done; }; +extern const struct regmap_config cs42l42_regmap; +extern const struct snd_soc_component_driver cs42l42_soc_component; +extern struct snd_soc_dai_driver cs42l42_dai; + +int cs42l42_suspend(struct device *dev); +int cs42l42_resume(struct device *dev); +void cs42l42_resume_restore(struct device *dev); +int cs42l42_common_probe(struct cs42l42_private *cs42l42, + const struct snd_soc_component_driver *component_drv, + struct snd_soc_dai_driver *dai); +int cs42l42_init(struct cs42l42_private *cs42l42); +void cs42l42_common_remove(struct cs42l42_private *cs42l42); + #endif /* __CS42L42_H__ */ From patchwork Fri Aug 19 12:52:28 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948820 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B30A4C32771 for ; Fri, 19 Aug 2022 12:56:39 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id ED0C81696; Fri, 19 Aug 2022 14:55:47 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz ED0C81696 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913798; bh=EIMo+gNbw2xThrMJHnARjDvA2WbuYtFsazvuPHbw7Dk=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=uJDyu8GjBSjcJyCuKXMtI1/1OyRhcce+WrZ1CPupSQ+LhQm8k19NOkeO7S9doLPYT zziw3vDouznDEgVbNbxWna6aTA6TfnvegroXWr3M2uetnyA3hlxm+NRpSxPLgZBn/4 JD6faEZOGT1p/bn2njv4/Cz0DYvqZp5RaVEhPfuw= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 13EB8F8057D; Fri, 19 Aug 2022 14:53:04 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id E570AF8051F; Fri, 19 Aug 2022 14:52:56 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 613C6F80524 for ; Fri, 19 Aug 2022 14:52:42 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 613C6F80524 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="kdaklWQM" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27J5opPs018534; Fri, 19 Aug 2022 07:52:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=Ak2aZKCy0O23kOpbYZpmEFVDG3qgHeAzs0mNs6uszHA=; b=kdaklWQMCRqta8Ymh+m0wG40ll4fd2GV1fUy17CoPMmkRhI7UCnNL/oUDcJbR0feozS4 02uylzDGVboPB8LFlVSVZrXN0lDiychP7Swgby5y59Eego4CKarjR162Kr2IDihsc9gL L8dlZ3UB4A5VmS+CPIglE87SOXvo8YhQD09gAF3E2s+0H38LnM3uB4oPhuOMyTOofjL4 eZh9DTJ/LqNk/GMnKXJ1uLLF+ONxFCoIQ948FY21Hhf7X1Af0T9wY0qujuLFUogR4LG8 merwQwJeKlhfyYQScRY2E/+s7v77RXV6liBwEQd++xhRnki72B1ARdlWKMIElH9QTpMg WQ== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3hx9c1yrtp-6 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:40 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:35 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:35 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 0999FB16; Fri, 19 Aug 2022 12:52:35 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 10/12] ASoC: cs42l42: Export some functions for Soundwire Date: Fri, 19 Aug 2022 13:52:28 +0100 Message-ID: <20220819125230.42731-11-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: aFDVCoQdKcqxHZRCtx0HHSJKOI0B6_RS X-Proofpoint-GUID: aFDVCoQdKcqxHZRCtx0HHSJKOI0B6_RS X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" Export functions that will be needed by a Soundwire module. Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/cs42l42.c | 14 +++++++++----- sound/soc/codecs/cs42l42.h | 5 +++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 7f16de593424..3a4f65233360 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -650,8 +650,8 @@ static const struct cs42l42_pll_params pll_ratio_table[] = { { 24576000, 1, 0x03, 0x40, 0x000000, 0x03, 0x10, 12288000, 128, 1} }; -static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int clk, - unsigned int sample_rate) +int cs42l42_pll_config(struct snd_soc_component *component, unsigned int clk, + unsigned int sample_rate) { struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); int i; @@ -737,8 +737,9 @@ static int cs42l42_pll_config(struct snd_soc_component *component, unsigned int return -EINVAL; } +EXPORT_SYMBOL_NS_GPL(cs42l42_pll_config, SND_SOC_CS42L42_CORE); -static void cs42l42_src_config(struct snd_soc_component *component, unsigned int sample_rate) +void cs42l42_src_config(struct snd_soc_component *component, unsigned int sample_rate) { struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); unsigned int fs; @@ -770,6 +771,7 @@ static void cs42l42_src_config(struct snd_soc_component *component, unsigned int CS42L42_CLK_OASRC_SEL_MASK, fs << CS42L42_CLK_OASRC_SEL_SHIFT); } +EXPORT_SYMBOL_NS_GPL(cs42l42_src_config, SND_SOC_CS42L42_CORE); static int cs42l42_asp_config(struct snd_soc_component *component, unsigned int sclk, unsigned int sample_rate) @@ -996,7 +998,7 @@ static int cs42l42_set_sysclk(struct snd_soc_dai *dai, return -EINVAL; } -static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream) +int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream) { struct snd_soc_component *component = dai->component; struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); @@ -1089,6 +1091,7 @@ static int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream) return 0; } +EXPORT_SYMBOL_NS_GPL(cs42l42_mute_stream, SND_SOC_CS42L42_CORE); #define CS42L42_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ SNDRV_PCM_FMTBIT_S24_LE |\ @@ -1633,7 +1636,7 @@ static const struct cs42l42_irq_params irq_params_table[] = { CS42L42_TSRS_PLUG_VAL_MASK} }; -static irqreturn_t cs42l42_irq_thread(int irq, void *data) +irqreturn_t cs42l42_irq_thread(int irq, void *data) { struct cs42l42_private *cs42l42 = (struct cs42l42_private *)data; unsigned int stickies[12]; @@ -1750,6 +1753,7 @@ static irqreturn_t cs42l42_irq_thread(int irq, void *data) return IRQ_HANDLED; } +EXPORT_SYMBOL_NS_GPL(cs42l42_irq_thread, SND_SOC_CS42L42_CORE); static void cs42l42_set_interrupt_masks(struct cs42l42_private *cs42l42) { diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h index 942054434afd..f575ef9b5498 100644 --- a/sound/soc/codecs/cs42l42.h +++ b/sound/soc/codecs/cs42l42.h @@ -55,6 +55,11 @@ extern const struct regmap_config cs42l42_regmap; extern const struct snd_soc_component_driver cs42l42_soc_component; extern struct snd_soc_dai_driver cs42l42_dai; +int cs42l42_pll_config(struct snd_soc_component *component, + unsigned int clk, unsigned int sample_rate); +void cs42l42_src_config(struct snd_soc_component *component, unsigned int sample_rate); +int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream); +irqreturn_t cs42l42_irq_thread(int irq, void *data); int cs42l42_suspend(struct device *dev); int cs42l42_resume(struct device *dev); void cs42l42_resume_restore(struct device *dev); From patchwork Fri Aug 19 12:52:29 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948821 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 64F66C32771 for ; Fri, 19 Aug 2022 12:56:56 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id 9B214169A; Fri, 19 Aug 2022 14:56:04 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 9B214169A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913814; bh=kwsBw3poTP+VckeeOFbc3fLWjbHlQ4b9/lU9s//jgtU=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=OVqp2+27sWiCNJQG8N8AEIaF1+2Vw52cvsmX5XomH9ZFd34spF0e9bQNsAKzfVqQ6 +iW8dueAbM5ucITXFxv44wn8rORYeve0M6jHvlVsBRw8ijAPNSRUSlsouw5KiDcl7J I8snV+XSGEo9ZKuUbM2u3ba6k0ZohAPen6OJdNPM= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 8DCCEF80589; Fri, 19 Aug 2022 14:53:04 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 401F5F80524; Fri, 19 Aug 2022 14:52:58 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 5B1BEF80528 for ; Fri, 19 Aug 2022 14:52:47 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 5B1BEF80528 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="aAx0jy3K" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27J5opPt018534; Fri, 19 Aug 2022 07:52:46 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=NyADNrZibKvps7pnGhntU41oXp+rnZg+GvEi/pymPnI=; b=aAx0jy3KBkVp10BlRqV4C5PtQSVQysy1P1S27DRjiqFnrvchN89CXJiukwSsxHUfKilu 025ovWNvCzurp9MDmyYpxJxgP4prAIfP/ipuCTVSl0/73v0yoFFKOu+FmNQw77PJ5PIm 57z9ZCnF5i4W+flqD7vS6tCRW1X2dBroJFmEfdZF+NBw9KdxUVDwj6a68AnkFw2KUzkr 1AQpTQWzKTrmdr4RaMTMVSAqwercp1t+9JVUGvC/3Lsb2uVaUkqkQLbd64eWXunew3kv EQPjWPn8p/GSv3n6Jkst4w24k569J8NFcblcQuq/3v9gQ6L8au/x1jAHSw/OTYQ0ZUZS LQ== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3hx9c1yrtp-7 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:41 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:35 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:35 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 18836B0E; Fri, 19 Aug 2022 12:52:35 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 11/12] ASoC: cs42l42: Add Soundwire support Date: Fri, 19 Aug 2022 13:52:29 +0100 Message-ID: <20220819125230.42731-12-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: Uo7Y_i5rJYkBTXLGH1I2jTXANT2Urh6U X-Proofpoint-GUID: Uo7Y_i5rJYkBTXLGH1I2jTXANT2Urh6U X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" This adds support for using CS42L42 as a Soundwire device. Soundwire-specifics are kept separate from the I2S implementation as much as possible, aiming to limit the risk of breaking the I2C+I2S support. There are some important differences in the silicon behaviour between I2S and Soundwire mode that are reflected in the implementation: - ASP (I2S) most not be used in Soundwire mode because the two interfaces share pins. - The Soundwire capture (record) port only supports 1 channel. It does not have left-to-right duplication like the ASP. - DP2 can only be prepared if the HP has powered-up. DP1 can only be prepared if the ADC has powered-up. (This ordering restriction does not exist for ASPs.) The Soundwire core port-prepare step is triggered by the DAI-link prepare(). This happens before the codec DAI prepare() or the DAPM sequence so these cannot be used to enable HP/ADC. Instead the HP/ADC enable are done in hw_params() and hw_free(). - The SRCs are an integral part of the audio chain but in silicon their power control is linked to the ASP. There is no equivalent power link to Soundwire DPs so the driver must take "manual" control of SRC power. - The Soundwire control registers occupy the lower part of the Soundwire address space so cs42l42 registers are offset by 0x8000 (non-paged) in Soundwire mode. - Register addresses are 8-bit paged in I2C mode but 16-bit unpaged in Soundwire. - Special procedures are needed on register read/writes to (a) ensure that the previous internal bus transaction has completed, and (b) handle delayed read results, when the read value could not be returned within the Soundwire read command. There are also some differences in driver implementation between I2S and Soundwire operation: - CS42L42 does not runtime_suspend, but runtime_suspend/resume are required in Soundwire mode as the most convenient way to power-up the bus manager and to handle the unattach_request condition. - Intel Soundwire host controllers have a low-power clock-stop mode that requires resetting all peripherals when resuming. This is not compatible with the plug-detect and button-detect because it will clear the condition that caused the wakeup before the driver can handle it. So clock-stop must be blocked when a snd_soc_jack handler is registered. - As in I2S mode, the PLL is only used while audio is active because of clocking quirks in the silicon. For Soundwire the cs42l42_pll_config() is deferred until the DAI prepare(), to allow the cs42l42_bus_config() callback to set the SCLK. Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/Kconfig | 6 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/cs42l42-sdw.c | 601 +++++++++++++++++++++++++++++++++ sound/soc/codecs/cs42l42.c | 35 ++ sound/soc/codecs/cs42l42.h | 3 + 5 files changed, 647 insertions(+) create mode 100644 sound/soc/codecs/cs42l42-sdw.c diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 9f6f0f97cfb9..464e44efa06b 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -68,6 +68,7 @@ config SND_SOC_ALL_CODECS imply SND_SOC_CS35L45_I2C imply SND_SOC_CS35L45_SPI imply SND_SOC_CS42L42 + imply SND_SOC_CS42L42_SDW imply SND_SOC_CS42L51_I2C imply SND_SOC_CS42L52 imply SND_SOC_CS42L56 @@ -700,6 +701,11 @@ config SND_SOC_CS42L42 select REGMAP_I2C select SND_SOC_CS42L42_CORE +config SND_SOC_CS42L42_SDW + tristate "Cirrus Logic CS42L42 CODEC on Soundwire" + depends on SOUNDWIRE + select SND_SOC_CS42L42_CORE + config SND_SOC_CS42L51 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index d91f3c1fc2b3..11c19df9cb6a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -66,6 +66,7 @@ snd-soc-cs35l45-spi-objs := cs35l45-spi.o snd-soc-cs35l45-i2c-objs := cs35l45-i2c.o snd-soc-cs42l42-objs := cs42l42.o snd-soc-cs42l42-i2c-objs := cs42l42-i2c.o +snd-soc-cs42l42-sdw-objs := cs42l42-sdw.o snd-soc-cs42l51-objs := cs42l51.o snd-soc-cs42l51-i2c-objs := cs42l51-i2c.o snd-soc-cs42l52-objs := cs42l52.o @@ -422,6 +423,7 @@ obj-$(CONFIG_SND_SOC_CS35L45_SPI) += snd-soc-cs35l45-spi.o obj-$(CONFIG_SND_SOC_CS35L45_I2C) += snd-soc-cs35l45-i2c.o obj-$(CONFIG_SND_SOC_CS42L42_CORE) += snd-soc-cs42l42.o obj-$(CONFIG_SND_SOC_CS42L42) += snd-soc-cs42l42-i2c.o +obj-$(CONFIG_SND_SOC_CS42L42_SDW) += snd-soc-cs42l42-sdw.o obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o obj-$(CONFIG_SND_SOC_CS42L51_I2C) += snd-soc-cs42l51-i2c.o obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o diff --git a/sound/soc/codecs/cs42l42-sdw.c b/sound/soc/codecs/cs42l42-sdw.c new file mode 100644 index 000000000000..ed69a0a44d8c --- /dev/null +++ b/sound/soc/codecs/cs42l42-sdw.c @@ -0,0 +1,601 @@ +// SPDX-License-Identifier: GPL-2.0-only +// cs42l42-sdw.c -- CS42L42 ALSA SoC audio driver Soundwire binding +// +// Copyright (C) 2022 Cirrus Logic, Inc. and +// Cirrus Logic International Semiconductor Ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cs42l42.h" + +#define CS42L42_SDW_CAPTURE_PORT 1 +#define CS42L42_SDW_PLAYBACK_PORT 2 + +/* Register addresses are offset when sent over Soundwire */ +#define CS42L42_SDW_ADDR_OFFSET 0x8000 + +#define CS42L42_SDW_MEM_ACCESS_STATUS 0xd0 +#define CS42L42_SDW_MEM_READ_DATA 0xd8 + +#define CS42L42_SDW_LAST_LATE BIT(3) +#define CS42L42_SDW_CMD_IN_PROGRESS BIT(2) +#define CS42L42_SDW_RDATA_RDY BIT(0) + +#define CS42L42_DELAYED_READ_POLL_US 1 +#define CS42L42_DELAYED_READ_TIMEOUT_US 100 + +static const struct snd_soc_dapm_route cs42l42_sdw_audio_map[] = { + /* Playback Path */ + { "HP", NULL, "MIXER" }, + { "MIXER", NULL, "DACSRC" }, + { "DACSRC", NULL, "Playback" }, + + /* Capture Path */ + { "ADCSRC", NULL, "HS" }, + { "Capture", NULL, "ADCSRC" }, +}; + +static int cs42l42_sdw_dai_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component); + + if (!cs42l42->init_done) + return -ENODEV; + + return 0; +} + +static int cs42l42_sdw_dai_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component); + struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream); + struct sdw_stream_config sconfig; + struct sdw_port_config pconfig; + unsigned int pdn_mask; + int ret; + + if (!sdw_stream) + return -EINVAL; + + /* Needed for PLL configuration when we are notified of new bus config */ + cs42l42->sample_rate = params_rate(params); + + memset(&sconfig, 0, sizeof(sconfig)); + memset(&pconfig, 0, sizeof(pconfig)); + + sconfig.frame_rate = params_rate(params); + sconfig.ch_count = params_channels(params); + sconfig.bps = snd_pcm_format_width(params_format(params)); + pconfig.ch_mask = GENMASK(sconfig.ch_count - 1, 0); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + sconfig.direction = SDW_DATA_DIR_RX; + pconfig.num = CS42L42_SDW_PLAYBACK_PORT; + pdn_mask = CS42L42_HP_PDN_MASK; + } else { + sconfig.direction = SDW_DATA_DIR_TX; + pconfig.num = CS42L42_SDW_CAPTURE_PORT; + pdn_mask = CS42L42_ADC_PDN_MASK; + } + + /* + * The DAI-link prepare() will trigger Soundwire DP prepare. But CS42L42 + * DP will only prepare if the HP/ADC is already powered-up. The + * DAI prepare() and DAPM sequence run after DAI-link prepare() so the + * PDN bit must be written here. + */ + regmap_clear_bits(cs42l42->regmap, CS42L42_PWR_CTL1, pdn_mask); + usleep_range(CS42L42_HP_ADC_EN_TIME_US, CS42L42_HP_ADC_EN_TIME_US + 1000); + + ret = sdw_stream_add_slave(cs42l42->sdw_peripheral, &sconfig, &pconfig, 1, sdw_stream); + if (ret) { + dev_err(dai->dev, "Failed to add sdw stream: %d\n", ret); + goto err; + } + + cs42l42_src_config(dai->component, params_rate(params)); + + return 0; + +err: + regmap_set_bits(cs42l42->regmap, CS42L42_PWR_CTL1, pdn_mask); + + return ret; +} + +static int cs42l42_sdw_dai_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component); + + dev_dbg(dai->dev, "dai_prepare: sclk=%u rate=%u\n", cs42l42->sclk, cs42l42->sample_rate); + + if (!cs42l42->sclk || !cs42l42->sample_rate) + return -EINVAL; + + return cs42l42_pll_config(dai->component, cs42l42->sclk, cs42l42->sample_rate); +} + +static int cs42l42_sdw_dai_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component); + struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream); + unsigned int pdn_mask; + + sdw_stream_remove_slave(cs42l42->sdw_peripheral, sdw_stream); + cs42l42->sample_rate = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + pdn_mask = CS42L42_HP_PDN_MASK; + else + pdn_mask = CS42L42_ADC_PDN_MASK; + + regmap_set_bits(cs42l42->regmap, CS42L42_PWR_CTL1, pdn_mask); + + return 0; +} + +static int cs42l42_sdw_dai_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, + int direction) +{ + if (!sdw_stream) + return 0; + + if (direction == SNDRV_PCM_STREAM_PLAYBACK) + dai->playback_dma_data = sdw_stream; + else + dai->capture_dma_data = sdw_stream; + + return 0; +} + +static void cs42l42_sdw_dai_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + snd_soc_dai_set_dma_data(dai, substream, NULL); +} + +static const struct snd_soc_dai_ops cs42l42_sdw_dai_ops = { + .startup = cs42l42_sdw_dai_startup, + .shutdown = cs42l42_sdw_dai_shutdown, + .hw_params = cs42l42_sdw_dai_hw_params, + .prepare = cs42l42_sdw_dai_prepare, + .hw_free = cs42l42_sdw_dai_hw_free, + .mute_stream = cs42l42_mute_stream, + .set_stream = cs42l42_sdw_dai_set_sdw_stream, +}; + +static struct snd_soc_dai_driver cs42l42_sdw_dai = { + .name = "cs42l42-sdw", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + }, + .symmetric_rate = 1, + .ops = &cs42l42_sdw_dai_ops, +}; + +static int cs42l42_sdw_poll_status(struct sdw_slave *peripheral, u8 mask, u8 match) +{ + int ret, sdwret; + + ret = read_poll_timeout(sdw_read_no_pm, sdwret, + (sdwret < 0) || ((sdwret & mask) == match), + CS42L42_DELAYED_READ_POLL_US, CS42L42_DELAYED_READ_TIMEOUT_US, + false, peripheral, CS42L42_SDW_MEM_ACCESS_STATUS); + if (ret == 0) + ret = sdwret; + + if (ret < 0) + dev_err(&peripheral->dev, "MEM_ACCESS_STATUS & %#x for %#x fail: %d\n", + mask, match, ret); + + return ret; +} + +static int cs42l42_sdw_read(void *context, unsigned int reg, unsigned int *val) +{ + struct sdw_slave *peripheral = context; + u8 data; + int ret; + + reg += CS42L42_SDW_ADDR_OFFSET; + + ret = cs42l42_sdw_poll_status(peripheral, CS42L42_SDW_CMD_IN_PROGRESS, 0); + if (ret < 0) + return ret; + + ret = sdw_read_no_pm(peripheral, reg); + if (ret < 0) { + dev_err(&peripheral->dev, "Failed to issue read @0x%x: %d\n", reg, ret); + return ret; + } + + data = (u8)ret; /* possible non-delayed read value */ + ret = sdw_read_no_pm(peripheral, CS42L42_SDW_MEM_ACCESS_STATUS); + if (ret < 0) { + dev_err(&peripheral->dev, "Failed to read MEM_ACCESS_STATUS: %d\n", ret); + return ret; + } + + /* If read was not delayed we already have the result */ + if ((ret & CS42L42_SDW_LAST_LATE) == 0) { + *val = data; + return 0; + } + + /* Poll for delayed read completion */ + if ((ret & CS42L42_SDW_RDATA_RDY) == 0) { + ret = cs42l42_sdw_poll_status(peripheral, + CS42L42_SDW_RDATA_RDY, CS42L42_SDW_RDATA_RDY); + if (ret < 0) + return ret; + } + + ret = sdw_read_no_pm(peripheral, CS42L42_SDW_MEM_READ_DATA); + if (ret < 0) { + dev_err(&peripheral->dev, "Failed to read READ_DATA: %d\n", ret); + return ret; + } + + *val = (u8)ret; + + return 0; +} + +static int cs42l42_sdw_write(void *context, unsigned int reg, unsigned int val) +{ + struct sdw_slave *peripheral = context; + int ret; + + ret = cs42l42_sdw_poll_status(peripheral, CS42L42_SDW_CMD_IN_PROGRESS, 0); + if (ret < 0) + return ret; + + return sdw_write_no_pm(peripheral, reg + CS42L42_SDW_ADDR_OFFSET, (u8)val); +} + +static void cs42l42_sdw_init(struct sdw_slave *peripheral) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); + int ret = 0; + + regcache_cache_only(cs42l42->regmap, false); + + ret = cs42l42_init(cs42l42); + if (ret < 0) { + regcache_cache_only(cs42l42->regmap, true); + return; + } + + /* Write out any cached changes that happened between probe and attach */ + ret = regcache_sync(cs42l42->regmap); + if (ret < 0) + dev_warn(cs42l42->dev, "Failed to sync cache: %d\n", ret); + + /* Disable internal logic that makes clock-stop conditional */ + regmap_clear_bits(cs42l42->regmap, CS42L42_PWR_CTL3, CS42L42_SW_CLK_STP_STAT_SEL_MASK); + + /* + * pm_runtime is needed to control bus manager suspend, and to + * recover from an unattach_request when the manager suspends. + * Autosuspend delay must be long enough to enumerate. + */ + pm_runtime_set_autosuspend_delay(cs42l42->dev, 3000); + pm_runtime_use_autosuspend(cs42l42->dev); + pm_runtime_set_active(cs42l42->dev); + pm_runtime_enable(cs42l42->dev); + pm_runtime_mark_last_busy(cs42l42->dev); + pm_runtime_idle(cs42l42->dev); +} + +static int cs42l42_sdw_read_prop(struct sdw_slave *peripheral) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); + struct sdw_slave_prop *prop = &peripheral->prop; + struct sdw_dpn_prop *ports; + + ports = devm_kcalloc(cs42l42->dev, 2, sizeof(*ports), GFP_KERNEL); + if (!ports) + return -ENOMEM; + + prop->source_ports = BIT(CS42L42_SDW_CAPTURE_PORT); + prop->sink_ports = BIT(CS42L42_SDW_PLAYBACK_PORT); + prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; + prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; + + /* DP1 - capture */ + ports[0].num = CS42L42_SDW_CAPTURE_PORT, + ports[0].type = SDW_DPN_FULL, + ports[0].ch_prep_timeout = 10, + prop->src_dpn_prop = &ports[0]; + + /* DP2 - playback */ + ports[1].num = CS42L42_SDW_PLAYBACK_PORT, + ports[1].type = SDW_DPN_FULL, + ports[1].ch_prep_timeout = 10, + prop->sink_dpn_prop = &ports[1]; + + return 0; +} + +static int cs42l42_sdw_update_status(struct sdw_slave *peripheral, + enum sdw_slave_status status) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); + + switch (status) { + case SDW_SLAVE_ATTACHED: + dev_dbg(cs42l42->dev, "ATTACHED\n"); + if (!cs42l42->init_done) + cs42l42_sdw_init(peripheral); + break; + case SDW_SLAVE_UNATTACHED: + dev_dbg(cs42l42->dev, "UNATTACHED\n"); + break; + default: + break; + } + + return 0; +} + +static int cs42l42_sdw_bus_config(struct sdw_slave *peripheral, + struct sdw_bus_params *params) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); + unsigned int new_sclk = params->curr_dr_freq / 2; + + /* The cs42l42 cannot support a glitchless SWIRE_CLK change. */ + if ((new_sclk != cs42l42->sclk) && cs42l42->stream_use) { + dev_warn(cs42l42->dev, "Rejected SCLK change while audio active\n"); + return -EBUSY; + } + + cs42l42->sclk = new_sclk; + + dev_dbg(cs42l42->dev, "bus_config: sclk=%u c=%u r=%u\n", + cs42l42->sclk, params->col, params->row); + + return 0; +} + +static int __maybe_unused cs42l42_sdw_clk_stop(struct sdw_slave *peripheral, + enum sdw_clk_stop_mode mode, + enum sdw_clk_stop_type type) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); + + dev_dbg(cs42l42->dev, "clk_stop mode:%d type:%d\n", mode, type); + + return 0; +} + +static const struct sdw_slave_ops cs42l42_sdw_ops = { + .read_prop = cs42l42_sdw_read_prop, + .update_status = cs42l42_sdw_update_status, + .bus_config = cs42l42_sdw_bus_config, +#ifdef DEBUG + .clk_stop = cs42l42_sdw_clk_stop, +#endif +}; + +static int __maybe_unused cs42l42_sdw_runtime_suspend(struct device *dev) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); + + dev_dbg(dev, "Runtime suspend\n"); + + /* The host controller could suspend, which would mean no register access */ + regcache_cache_only(cs42l42->regmap, true); + + return 0; +} + +static const struct reg_sequence __maybe_unused cs42l42_soft_reboot_seq[] = { + REG_SEQ0(CS42L42_SOFT_RESET_REBOOT, 0x1e), +}; + +static int __maybe_unused cs42l42_sdw_handle_unattach(struct cs42l42_private *cs42l42) +{ + struct sdw_slave *peripheral = cs42l42->sdw_peripheral; + + if (!peripheral->unattach_request) + return 0; + + /* Cannot access registers until master re-attaches. */ + dev_dbg(&peripheral->dev, "Wait for initialization_complete\n"); + if (!wait_for_completion_timeout(&peripheral->initialization_complete, + msecs_to_jiffies(5000))) { + dev_err(&peripheral->dev, "initialization_complete timed out\n"); + return -ETIMEDOUT; + } + + peripheral->unattach_request = 0; + + /* + * After a bus reset there must be a reconfiguration reset to + * reinitialize the internal state of CS42L42. + */ + regmap_multi_reg_write_bypassed(cs42l42->regmap, + cs42l42_soft_reboot_seq, + ARRAY_SIZE(cs42l42_soft_reboot_seq)); + usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2); + regcache_mark_dirty(cs42l42->regmap); + + return 0; +} + +static int __maybe_unused cs42l42_sdw_runtime_resume(struct device *dev) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); + int ret; + + dev_dbg(dev, "Runtime resume\n"); + + ret = cs42l42_sdw_handle_unattach(cs42l42); + if (ret < 0) + return ret; + + regcache_cache_only(cs42l42->regmap, false); + + /* Sync LATCH_TO_VP first so the VP domain registers sync correctly */ + regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1); + regcache_sync(cs42l42->regmap); + + return 0; +} + +static int __maybe_unused cs42l42_sdw_resume(struct device *dev) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(dev); + int ret; + + dev_dbg(dev, "System resume\n"); + + /* Power-up so it can re-enumerate */ + ret = cs42l42_resume(dev); + if (ret) + return ret; + + /* Wait for re-attach */ + ret = cs42l42_sdw_handle_unattach(cs42l42); + if (ret < 0) + return ret; + + cs42l42_resume_restore(dev); + + return 0; +} + +static int cs42l42_sdw_probe(struct sdw_slave *peripheral, const struct sdw_device_id *id) +{ + struct device *dev = &peripheral->dev; + struct cs42l42_private *cs42l42; + struct regmap_config *regmap_conf; + struct regmap *regmap; + struct snd_soc_component_driver *component_drv; + int irq, ret; + + cs42l42 = devm_kzalloc(dev, sizeof(*cs42l42), GFP_KERNEL); + if (!cs42l42) + return -ENOMEM; + + if (has_acpi_companion(dev)) + irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(dev), 0); + else + irq = of_irq_get(dev->of_node, 0); + + if (irq == -ENOENT) + irq = 0; + else if (irq < 0) + return dev_err_probe(dev, irq, "Failed to get IRQ\n"); + + regmap_conf = devm_kmemdup(dev, &cs42l42_regmap, sizeof(cs42l42_regmap), GFP_KERNEL); + if (!regmap_conf) + return -ENOMEM; + regmap_conf->reg_bits = 16; + regmap_conf->num_ranges = 0; + regmap_conf->reg_read = cs42l42_sdw_read; + regmap_conf->reg_write = cs42l42_sdw_write; + + regmap = devm_regmap_init(dev, NULL, peripheral, regmap_conf); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), "Failed to allocate register map\n"); + + /* Start in cache-only until device is enumerated */ + regcache_cache_only(regmap, true); + + component_drv = devm_kmemdup(dev, + &cs42l42_soc_component, + sizeof(cs42l42_soc_component), + GFP_KERNEL); + if (!component_drv) + return -ENOMEM; + + component_drv->dapm_routes = cs42l42_sdw_audio_map; + component_drv->num_dapm_routes = ARRAY_SIZE(cs42l42_sdw_audio_map); + + cs42l42->dev = dev; + cs42l42->regmap = regmap; + cs42l42->sdw_peripheral = peripheral; + cs42l42->irq = irq; + + ret = cs42l42_common_probe(cs42l42, component_drv, &cs42l42_sdw_dai); + if (ret < 0) + return ret; + + return 0; +} + +static int cs42l42_sdw_remove(struct sdw_slave *peripheral) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); + + /* Resume so that cs42l42_remove() can access registers */ + pm_runtime_get_sync(cs42l42->dev); + cs42l42_common_remove(cs42l42); + pm_runtime_put(cs42l42->dev); + pm_runtime_disable(cs42l42->dev); + + return 0; +} + +static const struct dev_pm_ops cs42l42_sdw_pm = { + SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_sdw_resume) + SET_RUNTIME_PM_OPS(cs42l42_sdw_runtime_suspend, cs42l42_sdw_runtime_resume, NULL) +}; + +static const struct sdw_device_id cs42l42_sdw_id[] = { + SDW_SLAVE_ENTRY(0x01FA, 0x4242, 0), + {}, +}; +MODULE_DEVICE_TABLE(sdw, cs42l42_sdw_id); + +static struct sdw_driver cs42l42_sdw_driver = { + .driver = { + .name = "cs42l42-sdw", + .pm = &cs42l42_sdw_pm, + }, + .probe = cs42l42_sdw_probe, + .remove = cs42l42_sdw_remove, + .ops = &cs42l42_sdw_ops, + .id_table = cs42l42_sdw_id, +}; + +module_sdw_driver(cs42l42_sdw_driver); + +MODULE_DESCRIPTION("ASoC CS42L42 Soundwire driver"); +MODULE_AUTHOR("Richard Fitzgerald "); +MODULE_LICENSE("GPL"); +MODULE_IMPORT_NS(SND_SOC_CS42L42_CORE); diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c index 3a4f65233360..15996bb3be96 100644 --- a/sound/soc/codecs/cs42l42.c +++ b/sound/soc/codecs/cs42l42.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -522,6 +523,10 @@ static const struct snd_soc_dapm_widget cs42l42_dapm_widgets[] = { /* Playback/Capture Requirements */ SND_SOC_DAPM_SUPPLY("SCLK", CS42L42_ASP_CLK_CFG, CS42L42_ASP_SCLK_EN_SHIFT, 0, NULL, 0), + + /* Soundwire SRC power control */ + SND_SOC_DAPM_PGA("DACSRC", CS42L42_PWR_CTL2, CS42L42_DAC_SRC_PDNB_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_PGA("ADCSRC", CS42L42_PWR_CTL2, CS42L42_ADC_SRC_PDNB_SHIFT, 0, NULL, 0), }; static const struct snd_soc_dapm_route cs42l42_audio_map[] = { @@ -559,6 +564,20 @@ static int cs42l42_set_jack(struct snd_soc_component *component, struct snd_soc_ { struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(component); + /* + * If the Soundwire controller issues bus reset when coming out of + * clock-stop it will erase the jack state. This can lose button press + * events, and plug/unplug interrupt bits take between 125ms and 1500ms + * before they are valid again. + * Prevent this by holding our pm_runtime to block clock-stop. + */ + if (cs42l42->sdw_peripheral) { + if (jk) + pm_runtime_get_sync(cs42l42->dev); + else + pm_runtime_put_autosuspend(cs42l42->dev); + } + /* Prevent race with interrupt handler */ mutex_lock(&cs42l42->irq_lock); cs42l42->jack = jk; @@ -1645,9 +1664,11 @@ irqreturn_t cs42l42_irq_thread(int irq, void *data) unsigned int current_button_status; unsigned int i; + pm_runtime_get_sync(cs42l42->dev); mutex_lock(&cs42l42->irq_lock); if (cs42l42->suspended || !cs42l42->init_done) { mutex_unlock(&cs42l42->irq_lock); + pm_runtime_put_autosuspend(cs42l42->dev); return IRQ_NONE; } @@ -1750,6 +1771,8 @@ irqreturn_t cs42l42_irq_thread(int irq, void *data) } mutex_unlock(&cs42l42->irq_lock); + pm_runtime_mark_last_busy(cs42l42->dev); + pm_runtime_put_autosuspend(cs42l42->dev); return IRQ_HANDLED; } @@ -2374,6 +2397,18 @@ int cs42l42_init(struct cs42l42_private *cs42l42) if (ret != 0) goto err_shutdown; + /* + * SRC power is linked to ASP power so doesn't work in Soundwire mode. + * Override it and use DAPM to control SRC power for Soundwire. + */ + if (cs42l42->sdw_peripheral) { + regmap_update_bits(cs42l42->regmap, CS42L42_PWR_CTL2, + CS42L42_SRC_PDN_OVERRIDE_MASK | + CS42L42_DAC_SRC_PDNB_MASK | + CS42L42_ADC_SRC_PDNB_MASK, + CS42L42_SRC_PDN_OVERRIDE_MASK); + } + /* Setup headset detection */ cs42l42_setup_hs_type_detect(cs42l42); diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h index f575ef9b5498..038db45d95b3 100644 --- a/sound/soc/codecs/cs42l42.h +++ b/sound/soc/codecs/cs42l42.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -30,10 +31,12 @@ struct cs42l42_private { struct gpio_desc *reset_gpio; struct completion pdn_done; struct snd_soc_jack *jack; + struct sdw_slave *sdw_peripheral; struct mutex irq_lock; int irq; int pll_config; u32 sclk; + u32 sample_rate; u8 plug_state; u8 hs_type; u8 ts_inv; From patchwork Fri Aug 19 12:52:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Fitzgerald X-Patchwork-Id: 12948819 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D9130C32771 for ; Fri, 19 Aug 2022 12:56:23 +0000 (UTC) Received: from alsa1.perex.cz (alsa1.perex.cz [207.180.221.201]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by alsa0.perex.cz (Postfix) with ESMTPS id CD4FD1675; Fri, 19 Aug 2022 14:55:31 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz CD4FD1675 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1660913781; bh=Ifqjzvby5WnUB+w1adm0h3yHL08RI39kaWQ+suT5Mu0=; h=From:To:Subject:Date:In-Reply-To:References:Cc:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=IEndZbobyV0h4ht3PneqFvN2/LrGWUAHS8c+z2Q3Lpa1Cj/emVhtAoKQXCFmoIQ/v 3+UD8tuQh2Zi+5eKDOrvvJH1mwR196FcxGRZ4Obxk6vtE6kPEc3FkhPLt+SXfeLp8Y STzU6udLA8N7yGLDJ7plHNCBVI07HaK9T8UMaOSs= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 892AFF8057B; Fri, 19 Aug 2022 14:53:03 +0200 (CEST) Received: by alsa1.perex.cz (Postfix, from userid 50401) id 672FCF80525; Fri, 19 Aug 2022 14:52:56 +0200 (CEST) Received: from mx0b-001ae601.pphosted.com (mx0a-001ae601.pphosted.com [67.231.149.25]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 04E71F80536 for ; Fri, 19 Aug 2022 14:52:48 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 04E71F80536 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=cirrus.com header.i=@cirrus.com header.b="TS/8sl1l" Received: from pps.filterd (m0077473.ppops.net [127.0.0.1]) by mx0a-001ae601.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27J5opPu018534; Fri, 19 Aug 2022 07:52:47 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cirrus.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=PODMain02222019; bh=gK6+4+wdJ9G6qdOUweYveTrtoslYy4n8rVAMQAoDT80=; b=TS/8sl1lkdTTP448M2fS4ZUpDcmLQVJo9jfxv8DRFpecRo5NiK6LeSqZ0IKnHNdowN3H xI62ZboJCVA7uomqo3CcuPi2Wm+Wkn0g+o+FWlmaDct+SnPSxE42FkCg2cuqmrifks9l ucjbEMApdTuwPu5myGJe7jKdxRwO47RPA94Y2J567YoXFA3LbhTj6q46mxWK1ITR1IEB CoNrvM4cdajrvJc4LA87PqXEykV2VcQCsMEWx9DTBy37BY0HuBo3hAKvN9BmhtsfD1fG bWTQfxZq6tI1pIl0yZ4Aar3SsNYuYzMdMNJ2nBNqF9sN1N+izul55eNYG7uF4+/2OniI zg== Received: from ediex01.ad.cirrus.com ([84.19.233.68]) by mx0a-001ae601.pphosted.com (PPS) with ESMTPS id 3hx9c1yrtp-8 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 19 Aug 2022 07:52:46 -0500 Received: from ediex01.ad.cirrus.com (198.61.84.80) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.9; Fri, 19 Aug 2022 07:52:35 -0500 Received: from ediswmail.ad.cirrus.com (198.61.86.93) by ediex01.ad.cirrus.com (198.61.84.80) with Microsoft SMTP Server id 15.2.1118.9 via Frontend Transport; Fri, 19 Aug 2022 07:52:35 -0500 Received: from edi-sw-dsktp-006.ad.cirrus.com (edi-sw-dsktp-006.ad.cirrus.com [198.90.251.95]) by ediswmail.ad.cirrus.com (Postfix) with ESMTP id 2BF2311DA; Fri, 19 Aug 2022 12:52:35 +0000 (UTC) From: Richard Fitzgerald To: Subject: [PATCH 12/12] ASoC: cs42l42: Add support for Soundwire interrupts Date: Fri, 19 Aug 2022 13:52:30 +0100 Message-ID: <20220819125230.42731-13-rf@opensource.cirrus.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220819125230.42731-1-rf@opensource.cirrus.com> References: <20220819125230.42731-1-rf@opensource.cirrus.com> MIME-Version: 1.0 X-Proofpoint-ORIG-GUID: 1KuQ84OFZmYMzgHL1qMs9r8dp6A6aMPj X-Proofpoint-GUID: 1KuQ84OFZmYMzgHL1qMs9r8dp6A6aMPj X-Proofpoint-Spam-Reason: safe Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org, Richard Fitzgerald , linux-kernel@vger.kernel.org X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: "Alsa-devel mailing list for ALSA developers - http://www.alsa-project.org" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: alsa-devel-bounces@alsa-project.org Sender: "Alsa-devel" This adds support for using the Soundwire interrupt mechanism to handle CS42L42 chip interrupts. Soundwire interrupts are used if a hard INT line is not declared. Wake-from-clock-stop is not used. The CS42L42 has limited wake capability, but clock-stop is already disabled when a snd_soc_jack is registered to prevent the host controller issuing a bus-reset on exit from clock stop mode, which would clear the interrupt status and break jack and button detection. Signed-off-by: Richard Fitzgerald --- sound/soc/codecs/cs42l42-sdw.c | 90 +++++++++++++++++++++++++++++++++- sound/soc/codecs/cs42l42.h | 3 ++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/cs42l42-sdw.c b/sound/soc/codecs/cs42l42-sdw.c index ed69a0a44d8c..1bdeed93587d 100644 --- a/sound/soc/codecs/cs42l42-sdw.c +++ b/sound/soc/codecs/cs42l42-sdw.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,8 @@ /* Register addresses are offset when sent over Soundwire */ #define CS42L42_SDW_ADDR_OFFSET 0x8000 +#define CS42L42_SDW_GEN_INT_STATUS_1 0xc0 +#define CS42L42_SDW_GEN_INT_MASK_1 0xc1 #define CS42L42_SDW_MEM_ACCESS_STATUS 0xd0 #define CS42L42_SDW_MEM_READ_DATA 0xd8 @@ -33,6 +36,11 @@ #define CS42L42_SDW_CMD_IN_PROGRESS BIT(2) #define CS42L42_SDW_RDATA_RDY BIT(0) +#define CS42L42_SDW_M_SCP_IMP_DEF1 BIT(0) +#define CS42L42_GEN_INT_CASCADE SDW_SCP_INT1_IMPL_DEF + +#define CS42L42_SDW_INT_MASK_CODEC_IRQ BIT(0) + #define CS42L42_DELAYED_READ_POLL_US 1 #define CS42L42_DELAYED_READ_TIMEOUT_US 100 @@ -306,6 +314,13 @@ static void cs42l42_sdw_init(struct sdw_slave *peripheral) /* Disable internal logic that makes clock-stop conditional */ regmap_clear_bits(cs42l42->regmap, CS42L42_PWR_CTL3, CS42L42_SW_CLK_STP_STAT_SEL_MASK); + /* Enable Soundwire interrupts */ + if (!cs42l42->irq) { + dev_dbg(cs42l42->dev, "Using Soundwire interrupts\n"); + sdw_write_no_pm(peripheral, CS42L42_SDW_GEN_INT_MASK_1, + CS42L42_SDW_INT_MASK_CODEC_IRQ); + } + /* * pm_runtime is needed to control bus manager suspend, and to * recover from an unattach_request when the manager suspends. @@ -319,6 +334,49 @@ static void cs42l42_sdw_init(struct sdw_slave *peripheral) pm_runtime_idle(cs42l42->dev); } +static int cs42l42_sdw_interrupt(struct sdw_slave *peripheral, + struct sdw_slave_intr_status *status) +{ + struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); + + /* Soundwire core holds our pm_runtime when calling this function. */ + + dev_dbg(cs42l42->dev, "int control_port=0x%x\n", status->control_port); + + if ((status->control_port & CS42L42_GEN_INT_CASCADE) == 0) + return 0; + + /* + * Clear and mask until it has been handled. The read of GEN_INT_STATUS_1 + * is required as per the Soundwire spec for interrupt status bits to clear. + */ + sdw_write_no_pm(peripheral, CS42L42_SDW_GEN_INT_MASK_1, 0); + sdw_read_no_pm(peripheral, CS42L42_SDW_GEN_INT_STATUS_1); + sdw_write_no_pm(peripheral, CS42L42_SDW_GEN_INT_STATUS_1, 0xFF); + queue_work(system_power_efficient_wq, &cs42l42->sdw_irq_work); + + /* Prevent host controller suspending before we handle the interrupt */ + pm_runtime_get_noresume(cs42l42->dev); + + return 0; +} + +static void cs42l42_sdw_irq_work(struct work_struct *work) +{ + struct cs42l42_private *cs42l42 = container_of(work, + struct cs42l42_private, + sdw_irq_work); + + cs42l42_irq_thread(-1, cs42l42); + + /* unmask interrupt */ + if (!cs42l42->sdw_irq_no_unmask) + sdw_write_no_pm(cs42l42->sdw_peripheral, CS42L42_SDW_GEN_INT_MASK_1, + CS42L42_SDW_INT_MASK_CODEC_IRQ); + + pm_runtime_put_autosuspend(cs42l42->dev); +} + static int cs42l42_sdw_read_prop(struct sdw_slave *peripheral) { struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); @@ -334,6 +392,14 @@ static int cs42l42_sdw_read_prop(struct sdw_slave *peripheral) prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY; + /* + * CS42L42 doesn't have a SDW_SCP_INT1_IMPL_DEF mask bit but it must be + * set in scp_int1_mask else the Soundwire framework won't notify us + * when the IMPL_DEF interrupt is asserted. + */ + if (!cs42l42->irq) + prop->scp_int1_mask |= SDW_SCP_INT1_IMPL_DEF; + /* DP1 - capture */ ports[0].num = CS42L42_SDW_CAPTURE_PORT, ports[0].type = SDW_DPN_FULL, @@ -403,6 +469,7 @@ static int __maybe_unused cs42l42_sdw_clk_stop(struct sdw_slave *peripheral, static const struct sdw_slave_ops cs42l42_sdw_ops = { .read_prop = cs42l42_sdw_read_prop, + .interrupt_callback = cs42l42_sdw_interrupt, .update_status = cs42l42_sdw_update_status, .bus_config = cs42l42_sdw_bus_config, #ifdef DEBUG @@ -473,6 +540,11 @@ static int __maybe_unused cs42l42_sdw_runtime_resume(struct device *dev) regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1); regcache_sync(cs42l42->regmap); + /* Re-enable Soundwire interrupts */ + if (!cs42l42->irq) + sdw_write_no_pm(cs42l42->sdw_peripheral, CS42L42_SDW_GEN_INT_MASK_1, + CS42L42_SDW_INT_MASK_CODEC_IRQ); + return 0; } @@ -495,6 +567,11 @@ static int __maybe_unused cs42l42_sdw_resume(struct device *dev) cs42l42_resume_restore(dev); + /* Re-enable Soundwire interrupts */ + if (!cs42l42->irq) + sdw_write_no_pm(cs42l42->sdw_peripheral, CS42L42_SDW_GEN_INT_MASK_1, + CS42L42_SDW_INT_MASK_CODEC_IRQ); + return 0; } @@ -546,6 +623,7 @@ static int cs42l42_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi component_drv->dapm_routes = cs42l42_sdw_audio_map; component_drv->num_dapm_routes = ARRAY_SIZE(cs42l42_sdw_audio_map); + INIT_WORK(&cs42l42->sdw_irq_work, cs42l42_sdw_irq_work); cs42l42->dev = dev; cs42l42->regmap = regmap; cs42l42->sdw_peripheral = peripheral; @@ -562,8 +640,18 @@ static int cs42l42_sdw_remove(struct sdw_slave *peripheral) { struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev); - /* Resume so that cs42l42_remove() can access registers */ + /* Resume so that we can access registers */ pm_runtime_get_sync(cs42l42->dev); + + /* Disable Soundwire interrupts */ + if (!cs42l42->irq) { + cs42l42->sdw_irq_no_unmask = true; + cancel_work_sync(&cs42l42->sdw_irq_work); + sdw_write_no_pm(peripheral, CS42L42_SDW_GEN_INT_MASK_1, 0); + sdw_read_no_pm(peripheral, CS42L42_SDW_GEN_INT_STATUS_1); + sdw_write_no_pm(peripheral, CS42L42_SDW_GEN_INT_STATUS_1, 0xFF); + } + cs42l42_common_remove(cs42l42); pm_runtime_put(cs42l42->dev); pm_runtime_disable(cs42l42->dev); diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h index 038db45d95b3..b29126d218c4 100644 --- a/sound/soc/codecs/cs42l42.h +++ b/sound/soc/codecs/cs42l42.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,7 @@ struct cs42l42_private { struct completion pdn_done; struct snd_soc_jack *jack; struct sdw_slave *sdw_peripheral; + struct work_struct sdw_irq_work; struct mutex irq_lock; int irq; int pll_config; @@ -52,6 +54,7 @@ struct cs42l42_private { bool hp_adc_up_pending; bool suspended; bool init_done; + bool sdw_irq_no_unmask; }; extern const struct regmap_config cs42l42_regmap;