From patchwork Sat Feb 24 13:54:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Ond=C5=99ej_Jirman?= X-Patchwork-Id: 205889 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp1157141dyb; Sat, 24 Feb 2024 05:57:47 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCVKJ8a70+MBXz3Z5tdqTSIoGbrtA1Fk88KHB4j+Bem+2txXSrPddc9luqsc/ghrwgX8uQFIipbHliTnkIpSIE3WHLwCFw== X-Google-Smtp-Source: AGHT+IHiMdjZqsYxxLEi8uxRg0vNSKngX2Ndmq/Vkz9v+FSLE45+bUaMyG63Vde2rCopTC5dYYBk X-Received: by 2002:a05:6358:16d4:b0:179:22c:4a4d with SMTP id r20-20020a05635816d400b00179022c4a4dmr3534078rwl.22.1708783067075; Sat, 24 Feb 2024 05:57:47 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708783067; cv=pass; d=google.com; s=arc-20160816; b=h5c9iSOFLPV27WZnIevZ8p45Xt6NMtRLybRYuLashi7EQF+6cu76at2P3qkv1Re1v4 jHKcviOr+gZGjNWPVzspL3KR15bXzpRuBSV2G+iqgAPzE0dh/OGcyFAg1awCXd4ZKOvh ekTj1m+ZTV6I/BJv2hR5nVCLug7SaPVwisQ3++1NAb5H9xEVNNw5oQx14Pn+YNAuIcNT LAhw64/gEnQIEZGAfIA9DQmvYPejqCCnlE1ut5cNMDKvryJrSIp3ZdBbXq4REE7+XfHy UtkseBobB82zG/f3QQbvGkxO4D0ulEj3b07tXcSpA5eafDoogMLMwOLUVBhkUcUssna8 LwbA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=VMM3kr0XFuu4JkBUoBGLzM8sz7y9oqJcf7OMoDjJSlc=; fh=BtptTc38Fo4YUTAEjUDBJT4+tGt26BbgQPuKT5WgtPM=; b=O6IAYr/AepHcEkaXrh9kp9uTy692GTseSVPfGvjK5l7aEnuChHx+fm3vgiPBerr9j6 NGrEuuuDNfmC2lO+3lXSKZWezgDzuiwPwP8LmCzhLRTElEYTQ2cAaPVnaxQikFEcGHoi 7rXVVUn4dG+TPpLoYSPZ/mi1rHt0LMPkpsTOdD2ErDGEJkrPwzxD9gYnZPUIPMOHOC8C w6evYRkSni8rEoR71A1Kb8mDnCS/Fu38B1H2Og4O5iRRwUFLfkSuCxYV40S9Xiwi4ZPy c55DvtPzfqo+v0hpi+1T5gp/jyTlptdRRfwgD4G2PqWU05sUja0ZpVv7LJExnUkBeQiY 5N3A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b="tn8/8t7m"; arc=pass (i=1 spf=pass spfdomain=xff.cz dkim=pass dkdomain=xff.cz dmarc=pass fromdomain=xff.cz); spf=pass (google.com: domain of linux-kernel+bounces-79693-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79693-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id w186-20020a6262c3000000b006e466aa6862si932277pfb.122.2024.02.24.05.57.46 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 24 Feb 2024 05:57:47 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-79693-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b="tn8/8t7m"; arc=pass (i=1 spf=pass spfdomain=xff.cz dkim=pass dkdomain=xff.cz dmarc=pass fromdomain=xff.cz); spf=pass (google.com: domain of linux-kernel+bounces-79693-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79693-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 3221BB20A71 for ; Sat, 24 Feb 2024 13:57:44 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 281E14D9EC; Sat, 24 Feb 2024 13:55:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=xff.cz header.i=@xff.cz header.b="tn8/8t7m" Received: from vps.xff.cz (vps.xff.cz [195.181.215.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9C26B29438; Sat, 24 Feb 2024 13:55:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.181.215.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708782912; cv=none; b=NpsWXJcTXdq0fBERvwgcoxUoYCNqmf5RfAt9dktHYoMUpuiWPqZ8SAP0BssqhclVPRmiwUVmL/4R20I/XhyAKkt37QwLuJ98uvP6fSEoQynBuZ/PxQTPEyvQmsCsPyglzm9JmGa6VHPibvX4DrDuY0EQGewouaGk1Ae3Xlpdpjk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708782912; c=relaxed/simple; bh=worLZTo9a3xOqnG2MGSIZHpGnCKBAdHSzTO+24Aiyj8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VH4OMuQ6WNQq2Zv0OuTQ+U0iZ3UsPSdLden5+BAOH6CaFTMHSfxSjo5JP2S7MPP9oTrpgaptlZVh62ZxqkYlH3Igy769FhxPG5ZdbcJ+7i4xx1pGW8TKgKX53KclO4iJD1V6FXxSuEaene13FLstNfnEUK7ewqsvnPC27tjIJEk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=xff.cz; spf=pass smtp.mailfrom=xff.cz; dkim=pass (1024-bit key) header.d=xff.cz header.i=@xff.cz header.b=tn8/8t7m; arc=none smtp.client-ip=195.181.215.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=xff.cz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=xff.cz DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xff.cz; s=mail; t=1708782908; bh=worLZTo9a3xOqnG2MGSIZHpGnCKBAdHSzTO+24Aiyj8=; h=From:To:Cc:Subject:Date:References:From; b=tn8/8t7mgo1t0W+dgEr3h18KJxNXgTwIDGoRwGL0K1ToGMr+JXPkjDgWyZH3WlDaQ ++ktmgqP+wztmcEKw37RGrWx2mGWU7p/XBN+Mxm9xwgW40Rqm6pGiFojY+B0rFK4gF nuR/lqe88VaCCdfVDJ87ucvKDna7KxuCUsKoaukg= From: =?utf-8?q?Ond=C5=99ej_Jirman?= To: linux-kernel@vger.kernel.org, Liam Girdwood , Rob Herring , Conor Dooley , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Ondrej Jirman , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Arnaud Ferraris , linux-sound@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-sunxi@lists.linux.dev Subject: [RESEND PATCH v2 1/5] dt-bindings: sound: Add jack-type property to sun8i-a33-codec Date: Sat, 24 Feb 2024 14:54:54 +0100 Message-ID: <20240224135501.3822390-2-megi@xff.cz> In-Reply-To: <20240224135501.3822390-1-megi@xff.cz> References: <20240224135501.3822390-1-megi@xff.cz> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791788913242495728 X-GMAIL-MSGID: 1791788913242495728 From: Ondrej Jirman The codec driver needs to know what jack connector it is connected to on the board. Add proprty to describe the type of connector. Signed-off-by: Ondrej Jirman --- .../bindings/sound/allwinner,sun8i-a33-codec.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml index 63eadc4200ac..399fc00ad3f4 100644 --- a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml +++ b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml @@ -44,6 +44,15 @@ properties: - const: bus - const: mod + jack-type: + enum: + - headset + - headphone + description: + Type of jack connector connected to the codec. This can be either + a 3-pin headphone connector or 4-pin headset connector. If not + specified, jack detection is disabled. + required: - "#sound-dai-cells" - compatible From patchwork Sat Feb 24 13:54:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ond=C5=99ej_Jirman?= X-Patchwork-Id: 205890 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp1157194dyb; Sat, 24 Feb 2024 05:57:59 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWhH+ezQl4+17lgkAeZRLERKVo6qROwCvTH8MA0a/aKKPlrTi6KuxZ/n1IDW4/EmPwLbugu/4YqtnpNfujPUEmvc8jb+w== X-Google-Smtp-Source: AGHT+IEB3xzBp512blCmG3vgipGeQmYnF/pRmEIGDiOI34qJi2YpaOjlsDPNYPUrOiojdGojkZIQ X-Received: by 2002:a17:906:3397:b0:a3f:33b5:64dd with SMTP id v23-20020a170906339700b00a3f33b564ddmr1597909eja.49.1708783079195; Sat, 24 Feb 2024 05:57:59 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708783079; cv=pass; d=google.com; s=arc-20160816; b=nvkPwlqAC2XUSTD3kuJ9ljbk+vzaUxBv69pcDUgHbe+38nuqyQlF8drwY2WfpU4Hvr YoJNGCu7nM+3BMDE/Sl4yoNbSpt7mybCR6TkUcfuahb+5JleSXPhup4gxpM2GtMH0HXF bkKZfz6D5R56icObpssEnnvUIE+fPrybqUZ+YJrWFJo0L+XaVPO5AqxkrBJQjlrbIm4J qEqCTPE6vh/zhsk4Cq7x5bCS6qE8k6InUfytxaRX54+Ico4jswI58lvjfhb/3lvTE6gs /JxWU8fzM1axtAelB+h7QRW4VXlsFOMHgwIScfw4br0XRy1NcIGV2/ITLBP7QILBWFds jRwQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=JGVtLGJoNrifEQCr1YZ3zkxMW3g5EFoYp9uHA+YPkVo=; fh=c0ByhCenn9n2/Gg3f79DXng527omIiP5Cr8W9F+Rrb8=; b=EdvJ4oarevPVQsS5TI1Tq9zoCIq5DQCo/EOj8j1ZdaPlIOI5+abBe3uxst8KoaJ3Wm niynMWOUcouLCmLTfbX0LSeM+in+DGGXG3/Pt+Q+AUOxLUzCJrkJotXfbvom44smePTG RCfJljpjbc7iu59B/fym0g1iQHmIylRVoZAdODGzeFF2cFZXV4V4jH2Rt9L/FqeyWnhJ 5nUClldtmuP88MqGacN7AoXnxzIvPcpha/ULHBh0TXrurRliY90jbVzfbRcTCaCZ1oHR cDAIUxAdF3Rqu9t9tTee1CO98QzdDa3ZmyOVj88Pp9MhyrBJqnpEsNpGsiUvcLS1pkQg d10Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b=wd9DTMKD; arc=pass (i=1 spf=pass spfdomain=xff.cz dkim=pass dkdomain=xff.cz dmarc=pass fromdomain=xff.cz); spf=pass (google.com: domain of linux-kernel+bounces-79694-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79694-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id o24-20020a1709064f9800b00a3e256e95d2si551605eju.205.2024.02.24.05.57.59 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 24 Feb 2024 05:57:59 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-79694-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b=wd9DTMKD; arc=pass (i=1 spf=pass spfdomain=xff.cz dkim=pass dkdomain=xff.cz dmarc=pass fromdomain=xff.cz); spf=pass (google.com: domain of linux-kernel+bounces-79694-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79694-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id C34111F210DA for ; Sat, 24 Feb 2024 13:57:58 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 244704DA16; Sat, 24 Feb 2024 13:55:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=xff.cz header.i=@xff.cz header.b="wd9DTMKD" Received: from vps.xff.cz (vps.xff.cz [195.181.215.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 62012405F4; Sat, 24 Feb 2024 13:55:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.181.215.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708782913; cv=none; b=N2hYg0hImVK2Dv3sXI+tY3nx7J9M4dBCRHj/7qMM34dMRbpwBqhUqHp5go1E/P8yY8zXQNZv0JqShnVwubNVsNUf0h7alZevmV2Hrap/cuIGC3buVwoMm+FglIhBM4oAMebOVQQRRvpMCaR0s2heTxbG7W3L/l7urq3uXYdjWfM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708782913; c=relaxed/simple; bh=0xAlq3FKxyKOFVzLVHdJfOKR9ZGZX8El43JyE9dp5i8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Fw1JAOlwjd7mrE7A7g1j5KRrnybkSEIyPpEoZtU3eucTZLM33C+BmRYvt/dG0K5t/RpCN+iPh3M0CjepkpGF0bYnFCKO31pVWcwUdfX9LKPF95ycw8gfkeUczdiD52GLzDCs2TAs9j3jJOdXOmyMrBCtMY4H3fdTdWaCPTuETEU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=xff.cz; spf=pass smtp.mailfrom=xff.cz; dkim=pass (1024-bit key) header.d=xff.cz header.i=@xff.cz header.b=wd9DTMKD; arc=none smtp.client-ip=195.181.215.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=xff.cz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=xff.cz DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xff.cz; s=mail; t=1708782909; bh=0xAlq3FKxyKOFVzLVHdJfOKR9ZGZX8El43JyE9dp5i8=; h=From:To:Cc:Subject:Date:References:From; b=wd9DTMKDUrorPP8TJV46+jKHCZLJxBaZKFYdOT9ySCSrdDNgeVRe44ufvZ/epRk8O 7Wx0XcEuPsXh5o060cK8SisRCJKlxtBEpBJG2SSB5O9aaRf9gWaGV+J1YnPS42qJur gKMLqqOIX/3IhKx93KD01QgunTwePGaSkocxW5RM= From: =?utf-8?q?Ond=C5=99ej_Jirman?= To: linux-kernel@vger.kernel.org, Liam Girdwood , Rob Herring , Conor Dooley , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Samuel Holland , Chen-Yu Tsai , Jernej Skrabec , Ondrej Jirman , Arnaud Ferraris , linux-sound@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-sunxi@lists.linux.dev Subject: [RESEND PATCH v2 2/5] ASoC: sun50i-codec-analog: Move suspend/resume to set_bias_level Date: Sat, 24 Feb 2024 14:54:55 +0100 Message-ID: <20240224135501.3822390-3-megi@xff.cz> In-Reply-To: <20240224135501.3822390-1-megi@xff.cz> References: <20240224135501.3822390-1-megi@xff.cz> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791788925853273922 X-GMAIL-MSGID: 1791788925853273922 From: Samuel Holland With idle_bias_on and suspend_bias_off, there are bias level transitions that match the suspend/resume callbacks. However, there are also transitions during probe (OFF => STANDBY) and removal (STANDBY => OFF). By using the set_bias_level hook, the driver can have one copy of code that would otherwise be duplicated between the probe/resume and suspend/remove hooks. Signed-off-by: Samuel Holland Signed-off-by: Ondřej Jirman --- sound/soc/sunxi/sun50i-codec-analog.c | 29 +++++++++++++++++---------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c index 8a32d05e23e1..cedd4de42d1a 100644 --- a/sound/soc/sunxi/sun50i-codec-analog.c +++ b/sound/soc/sunxi/sun50i-codec-analog.c @@ -471,17 +471,23 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = { { "EARPIECE", NULL, "Earpiece Amp" }, }; -static int sun50i_a64_codec_suspend(struct snd_soc_component *component) +static int sun50i_a64_codec_set_bias_level(struct snd_soc_component *component, + enum snd_soc_bias_level level) { - return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL, - BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE), - BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE)); -} + switch (level) { + case SND_SOC_BIAS_OFF: + regmap_set_bits(component->regmap, SUN50I_ADDA_HP_CTRL, + BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE)); + break; + case SND_SOC_BIAS_STANDBY: + regmap_clear_bits(component->regmap, SUN50I_ADDA_HP_CTRL, + BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE)); + break; + default: + break; + } -static int sun50i_a64_codec_resume(struct snd_soc_component *component) -{ - return regmap_update_bits(component->regmap, SUN50I_ADDA_HP_CTRL, - BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE), 0); + return 0; } static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = { @@ -491,8 +497,9 @@ static const struct snd_soc_component_driver sun50i_codec_analog_cmpnt_drv = { .num_dapm_widgets = ARRAY_SIZE(sun50i_a64_codec_widgets), .dapm_routes = sun50i_a64_codec_routes, .num_dapm_routes = ARRAY_SIZE(sun50i_a64_codec_routes), - .suspend = sun50i_a64_codec_suspend, - .resume = sun50i_a64_codec_resume, + .set_bias_level = sun50i_a64_codec_set_bias_level, + .idle_bias_on = true, + .suspend_bias_off = true, }; static const struct of_device_id sun50i_codec_analog_of_match[] = { From patchwork Sat Feb 24 13:54:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ond=C5=99ej_Jirman?= X-Patchwork-Id: 205892 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp1157261dyb; Sat, 24 Feb 2024 05:58:12 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCUzo9/AyW83ObUx0f/opsA+BS65KEcf4EM7VB3ua8FhsmmnQqSNC/wFpWJeYFVg638PX/z8wsb0PDMjLWfrLRrfgyHalQ== X-Google-Smtp-Source: AGHT+IHF/6y8POGuVqi0SoZB2GTYZoO2qHuEo1ZfBzfHpcTVKJPrl1m9RcGX6LKF9HDKd05RIGP6 X-Received: by 2002:aa7:d912:0:b0:564:7962:4545 with SMTP id a18-20020aa7d912000000b0056479624545mr1731798edr.15.1708783092339; Sat, 24 Feb 2024 05:58:12 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708783092; cv=pass; d=google.com; s=arc-20160816; b=KTvssZg7KImmLP0PYAlue+SuzlXsjmCsF13kcsowuCNYgz7UUWjtFlONCTp+E4lcrq x0ZzrPKKWicINDXUG4ncxXoirI6TBcv59xQB7uRwY4nnJNqyfkWTL4DH9przS6Y4Wqsw pZ+oRgTcnuOkCVI45kxxAoHnvzgePWeiKYA8XXd+Gqw0RNCAdrCcDWa1TOBZNM+gqeEE C09N7pPj/5VeJXWduLr8xiFwbrZO49XvQeaRui1skOzLR2VluBCUkNDjz5P/oD0c+rAs ACrn8eFBA8EYgdy7TNsTdBuyC45wGeoUpveqXhyGJwFUwkgO0U9xGOOwb05I6EED9smw ldNg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=wBePflGuTIzSp+nsddwFz5v1Bexw5+WgmLeux8C68Tg=; fh=c0ByhCenn9n2/Gg3f79DXng527omIiP5Cr8W9F+Rrb8=; b=x5m9qo0DjMHdYGtgn0xT3EYAGmMCpKvT15PT3YRaimRx7fOyBfqyqGCLPFOwg+0gUj 9P2suVmjjF0k0nGpa8bu6UELTBe9efLN7y98mZRvEm2kVqbc/wkVR1+wxLBQ+bAGv3g7 NO2IvVRKMASKzPaRT6/70iL8l3h/ukCdwJHh3YI/Ttnfdbqul4bmjHI8yeKhk4wnovlp B+ny4xl7emSEupNQ9uyVis6HLpSWW29E3Y2+fQoqjdLXKnst+QtUHksGa3smfEHC7fhS LOE5WMEDWglouA1KQtqRDvXIinnCzLg4eWE8uhmwJUpjrh+wX6TSXL8s84s6MicpvdqL JW2Q==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b=YGQyERaX; arc=pass (i=1 spf=pass spfdomain=xff.cz dkim=pass dkdomain=xff.cz dmarc=pass fromdomain=xff.cz); spf=pass (google.com: domain of linux-kernel+bounces-79696-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79696-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [2604:1380:4601:e00::3]) by mx.google.com with ESMTPS id y24-20020aa7c258000000b005646fd47ec7si519420edo.244.2024.02.24.05.58.12 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 24 Feb 2024 05:58:12 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-79696-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) client-ip=2604:1380:4601:e00::3; Authentication-Results: mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b=YGQyERaX; arc=pass (i=1 spf=pass spfdomain=xff.cz dkim=pass dkdomain=xff.cz dmarc=pass fromdomain=xff.cz); spf=pass (google.com: domain of linux-kernel+bounces-79696-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:4601:e00::3 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79696-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id C581E1F23003 for ; Sat, 24 Feb 2024 13:58:11 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 11A674F5EC; Sat, 24 Feb 2024 13:55:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=xff.cz header.i=@xff.cz header.b="YGQyERaX" Received: from vps.xff.cz (vps.xff.cz [195.181.215.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 664B941212; Sat, 24 Feb 2024 13:55:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.181.215.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708782914; cv=none; b=CbCdcRnZyqyOQs5+KPZlk0jixkoomSpoKAeT1mkIQuW8Bjq+ndL19AVGREO3Inr3CYg1OSJvAIkKk51lGwhbkOkw6MrLfxEmzZvw9cgsCYaqJd+9UL86vydzZ+XKFdiB2wLC6v9gX4bJdU+wmvTLEURfFCs5rQ+kQ2utxgFhH5Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708782914; c=relaxed/simple; bh=Yqk0ASm3qdzudKQuluB7RYak2VVWIt+QMV2iJnIWwSI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nQrNx8N4BEGN0lnGA0IIYIGrrZoERFJCVs9DKyPG/SHbjhnIJ+hB1GyEZtUnV9K/7IQGmj6VmR+uDqy0PdR8tvzNs8N0DLftlpTqse+JqidTgniEE75tFKY9m43uGwRfc6wvWjzdyz1TRLnOgY6wLT2IM6srTTVr4k0NxjGccWI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=xff.cz; spf=pass smtp.mailfrom=xff.cz; dkim=pass (1024-bit key) header.d=xff.cz header.i=@xff.cz header.b=YGQyERaX; arc=none smtp.client-ip=195.181.215.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=xff.cz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=xff.cz DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xff.cz; s=mail; t=1708782909; bh=Yqk0ASm3qdzudKQuluB7RYak2VVWIt+QMV2iJnIWwSI=; h=From:To:Cc:Subject:Date:References:From; b=YGQyERaXkCKyDWPMH36QpBpzqFlYB0fHMSVwd4U1y0yg34s7GsIleYaR7PkvMwJ6Y KDkmGOHRr6XiE6IXTnQLEDXf+q9VjEMM9GilmfDu4R3J2AgtX8m/v+pk703FZWjJ/C ShXBIIfOEALtX+a4dwac1i0slhy9/LItwhiiSUbQ= From: =?utf-8?q?Ond=C5=99ej_Jirman?= To: linux-kernel@vger.kernel.org, Liam Girdwood , Rob Herring , Conor Dooley , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Samuel Holland , Chen-Yu Tsai , Jernej Skrabec , Ondrej Jirman , Arnaud Ferraris , linux-sound@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-sunxi@lists.linux.dev Subject: [RESEND PATCH v2 3/5] ASoC: sun8i-codec: Enable bus clock at STANDBY and higher bias Date: Sat, 24 Feb 2024 14:54:56 +0100 Message-ID: <20240224135501.3822390-4-megi@xff.cz> In-Reply-To: <20240224135501.3822390-1-megi@xff.cz> References: <20240224135501.3822390-1-megi@xff.cz> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791788940183044747 X-GMAIL-MSGID: 1791788940183044747 From: Samuel Holland For codec variants that have a bus clock, that clock must be running to receive interrupts. Since jack and mic accessory detection should work even when no audio is playing, that means the bus clock should be enabled any time the system is on. Accomplish that by tying the bus clock to the runtime PM state, which is then tied to the bias level not being OFF. Since the codec sets idle_bias_on, bias will generally never be OFF. However, we can set suspend_bias_off to maintain the power savings of gating the bus clock during suspend, when we don't expect jack/accessory detection to work. Signed-off-by: Samuel Holland Signed-off-by: Ondřej Jirman --- sound/soc/sunxi/sun8i-codec.c | 41 ++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 7b45ddffe990..2a46b96b03cc 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -177,12 +177,14 @@ struct sun8i_codec_aif { }; struct sun8i_codec_quirks { - bool legacy_widgets : 1; - bool lrck_inversion : 1; + bool bus_clock : 1; + bool legacy_widgets : 1; + bool lrck_inversion : 1; }; struct sun8i_codec { struct regmap *regmap; + struct clk *clk_bus; struct clk *clk_module; const struct sun8i_codec_quirks *quirks; struct sun8i_codec_aif aifs[SUN8I_CODEC_NAIFS]; @@ -197,6 +199,14 @@ static int sun8i_codec_runtime_resume(struct device *dev) struct sun8i_codec *scodec = dev_get_drvdata(dev); int ret; + if (scodec->clk_bus) { + ret = clk_prepare_enable(scodec->clk_bus); + if (ret) { + dev_err(dev, "Failed to enable the bus clock\n"); + return ret; + } + } + regcache_cache_only(scodec->regmap, false); ret = regcache_sync(scodec->regmap); @@ -215,6 +225,9 @@ static int sun8i_codec_runtime_suspend(struct device *dev) regcache_cache_only(scodec->regmap, true); regcache_mark_dirty(scodec->regmap); + if (scodec->clk_bus) + clk_disable_unprepare(scodec->clk_bus); + return 0; } @@ -1277,6 +1290,7 @@ static const struct snd_soc_component_driver sun8i_soc_component = { .num_dapm_routes = ARRAY_SIZE(sun8i_codec_dapm_routes), .probe = sun8i_codec_component_probe, .idle_bias_on = 1, + .suspend_bias_off = 1, .endianness = 1, }; @@ -1299,6 +1313,18 @@ static int sun8i_codec_probe(struct platform_device *pdev) if (!scodec) return -ENOMEM; + scodec->quirks = of_device_get_match_data(&pdev->dev); + + platform_set_drvdata(pdev, scodec); + + if (scodec->quirks->bus_clock) { + scodec->clk_bus = devm_clk_get(&pdev->dev, "bus"); + if (IS_ERR(scodec->clk_bus)) { + dev_err(&pdev->dev, "Failed to get the bus clock\n"); + return PTR_ERR(scodec->clk_bus); + } + } + scodec->clk_module = devm_clk_get(&pdev->dev, "mod"); if (IS_ERR(scodec->clk_module)) { dev_err(&pdev->dev, "Failed to get the module clock\n"); @@ -1311,17 +1337,14 @@ static int sun8i_codec_probe(struct platform_device *pdev) return PTR_ERR(base); } - scodec->regmap = devm_regmap_init_mmio_clk(&pdev->dev, "bus", base, - &sun8i_codec_regmap_config); + scodec->regmap = devm_regmap_init_mmio(&pdev->dev, base, + &sun8i_codec_regmap_config); if (IS_ERR(scodec->regmap)) { dev_err(&pdev->dev, "Failed to create our regmap\n"); return PTR_ERR(scodec->regmap); } - scodec->quirks = of_device_get_match_data(&pdev->dev); - - platform_set_drvdata(pdev, scodec); - + regcache_cache_only(scodec->regmap, true); pm_runtime_enable(&pdev->dev); if (!pm_runtime_enabled(&pdev->dev)) { ret = sun8i_codec_runtime_resume(&pdev->dev); @@ -1357,11 +1380,13 @@ static void sun8i_codec_remove(struct platform_device *pdev) } static const struct sun8i_codec_quirks sun8i_a33_quirks = { + .bus_clock = true, .legacy_widgets = true, .lrck_inversion = true, }; static const struct sun8i_codec_quirks sun50i_a64_quirks = { + .bus_clock = true, }; static const struct of_device_id sun8i_codec_of_match[] = { From patchwork Sat Feb 24 13:54:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Ond=C5=99ej_Jirman?= X-Patchwork-Id: 205891 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp1157218dyb; Sat, 24 Feb 2024 05:58:05 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCU5f2FsqAjlN1/hWvVWFcJe62Aqafkrlx4x0x/u9ksyZQ4WO3ef590Sez0n99WNY1CMHSZPnhf7Rzpvir+irlv/UOxyLA== X-Google-Smtp-Source: AGHT+IGG+REBmGeMX5ammPdb2uYyumbzf9W+Bk1jzfp1fMZkS0ZszRQHkP1RO/jMRUzBZkoSU7ih X-Received: by 2002:a05:6a00:8c04:b0:6e4:62ed:23c3 with SMTP id ih4-20020a056a008c0400b006e462ed23c3mr2982612pfb.9.1708783085778; Sat, 24 Feb 2024 05:58:05 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708783085; cv=pass; d=google.com; s=arc-20160816; b=PMzQblVGbhFjjPE/dgOXhhLO4SWkx5XPZ8VbYnILbBFPHf6qVTICQoiVAt191Ys0tq M5TYvZfC0p6o7oFVasFxhvO6UGEJaqSt8NBEZTCYI9XxA+wnK79wKpI0kThwYxg7vjC4 phU/r33qUahNtS1jwSV9LbUp6FK2Aw3TU7PtHEYyO1OqpHuXI88H1aADRfm3OtQcfVgQ oLIwz/BQAOLDbCuc33kLo5oSMnx9Ipcpw0MtVBEG5smeofBsXtps3gMyv6E9wftJNbJZ q4eVHdidWxV+7kqWKFPS/uYwI3xH9sacTICYPC2+Sj3/HrZFFKw4p2xCIOIx1Xvh0GLI Dt6w== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=FWdJspBYMrhtTSLSa4y1djhqrRBMjUznKJebsmkbZis=; fh=AvgKWciTdOx1lyoO25YULpYZBLmX1pG/bKEy4jWriL0=; b=ZLXbMPJR8UsaktHxMLlGpob3m/tVNKHSojUi2EJToRVs/hCNbeiVx/UbHY2iwLrxqS G6XwHcQ3Sd67P6DL1Mu81jmC5KnPSX8UTKadI62yQw5ijG/iC5hAGLd8o3SPnOrpDY14 GCPKdXbPwyh5n1JtRWaWQ7jP/mEQdG+0GnDre9jZCelNjmWWhw7rj2Jfs3eT+DCa3lzm KosLpcQSy2pzq5mjyj5GnHfmpCHAnN05UdrlYhnc+vxB2oBaHMJFoJK/R0f+0qq3sGM1 nPgEnq+n1Rs4wJMnFBj7jKoJT7YosTqX+1HaT/ObeMPfxMR/GAum4dV9vKySr7a1VUl7 fHnA==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b=D88CM6ek; arc=pass (i=1 spf=pass spfdomain=xff.cz dkim=pass dkdomain=xff.cz dmarc=pass fromdomain=xff.cz); spf=pass (google.com: domain of linux-kernel+bounces-79695-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79695-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id e26-20020a63545a000000b005dc88260f76si952334pgm.330.2024.02.24.05.58.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 24 Feb 2024 05:58:05 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-79695-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b=D88CM6ek; arc=pass (i=1 spf=pass spfdomain=xff.cz dkim=pass dkdomain=xff.cz dmarc=pass fromdomain=xff.cz); spf=pass (google.com: domain of linux-kernel+bounces-79695-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79695-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id CB706B212B8 for ; Sat, 24 Feb 2024 13:58:04 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 746F14E1CE; Sat, 24 Feb 2024 13:55:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=xff.cz header.i=@xff.cz header.b="D88CM6ek" Received: from vps.xff.cz (vps.xff.cz [195.181.215.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 85AC640BFE; Sat, 24 Feb 2024 13:55:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.181.215.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708782913; cv=none; b=aYtSryWjLlrOiGz1SEDKCslbKLHuu4eIZ7K05oksYES4rO+pHkqCS8X0e6vC/DfDnWAP4CNj6KpstiTwGise0Az1cxA7WzUq9oMWT304oCGnPQcF5y45UUb4SIqAyKHLPFVdieRTskuqxTLJDvf0ReC4HyMprPUXENvgn8B7J0c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708782913; c=relaxed/simple; bh=8aPsPyUjJEl/R2IiSeB6qnP9Jf53fx5I0eeKkSCAPzA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=sGLLtW5zWdHZ7Hwp0LDSuOH4S7SXqhmAjebg9FVzwBmw7LSGAkRQWCec1SDP+3k20EYc0g1hW7xeBrh7569zDNTQIsMPrfvP5SzMZ3Wc9UfAP2Az0JUGwVW6Fmhrja8AnYLH7EAi0mebOu2jW9aD8fCvHXLGw1fn0RKPPXVSOuM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=xff.cz; spf=pass smtp.mailfrom=xff.cz; dkim=pass (1024-bit key) header.d=xff.cz header.i=@xff.cz header.b=D88CM6ek; arc=none smtp.client-ip=195.181.215.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=xff.cz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=xff.cz DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xff.cz; s=mail; t=1708782909; bh=8aPsPyUjJEl/R2IiSeB6qnP9Jf53fx5I0eeKkSCAPzA=; h=From:To:Cc:Subject:Date:References:From; b=D88CM6ekulNrNZzctmxlJ60Qm8q1PGfsrWMse8uyjRRX1OdYsW1eSwCJvWLARfuOH 72MN8+eOGaW0jJUOolgNrp/UpcpKQn7fe2DsxtbSGRSzwAx5xBtpPrpiv93F8FV4x9 QEUZdgpi+wXnGngU5/RIpIQoBDjM2bycR7WwYa3Q= From: =?utf-8?q?Ond=C5=99ej_Jirman?= To: linux-kernel@vger.kernel.org, Liam Girdwood , Rob Herring , Conor Dooley , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Arnaud Ferraris , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Ondrej Jirman , linux-sound@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-sunxi@lists.linux.dev Subject: [RESEND PATCH v2 4/5] ASoC: sun50i-codec-analog: Enable jack detection on startup Date: Sat, 24 Feb 2024 14:54:57 +0100 Message-ID: <20240224135501.3822390-5-megi@xff.cz> In-Reply-To: <20240224135501.3822390-1-megi@xff.cz> References: <20240224135501.3822390-1-megi@xff.cz> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791788933165207817 X-GMAIL-MSGID: 1791788933165207817 From: Arnaud Ferraris This commit adds the necessary setup to enable jack detection on startup as well as the callback function enabling the microphone ADC when headset bias is enabled. The microphone ADC is also disabled in suspend. Signed-off-by: Arnaud Ferraris [Samuel: Moved MICADCEN setup to HBIAS event, added bias hooks] Signed-off-by: Samuel Holland Signed-off-by: Ondřej Jirman --- sound/soc/sunxi/sun50i-codec-analog.c | 32 ++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c index cedd4de42d1a..2081721a8ff2 100644 --- a/sound/soc/sunxi/sun50i-codec-analog.c +++ b/sound/soc/sunxi/sun50i-codec-analog.c @@ -116,8 +116,10 @@ #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN 7 #define SUN50I_ADDA_JACK_MIC_CTRL 0x1d +#define SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN 7 #define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN 6 #define SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN 5 +#define SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN 4 /* mixer controls */ static const struct snd_kcontrol_new sun50i_a64_codec_mixer_controls[] = { @@ -296,6 +298,19 @@ static const struct snd_kcontrol_new sun50i_codec_earpiece_switch[] = { SUN50I_ADDA_EARPIECE_CTRL1_ESPPA_MUTE, 1, 0), }; +static int sun50i_codec_hbias_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + u32 value = !!SND_SOC_DAPM_EVENT_ON(event); + + regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL, + BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN), + value << SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN); + + return 0; +} + static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = { /* DAC */ SND_SOC_DAPM_DAC("Left DAC", NULL, SUN50I_ADDA_MIX_DAC_CTRL, @@ -367,7 +382,8 @@ static const struct snd_soc_dapm_widget sun50i_a64_codec_widgets[] = { /* Microphone Bias */ SND_SOC_DAPM_SUPPLY("HBIAS", SUN50I_ADDA_JACK_MIC_CTRL, SUN50I_ADDA_JACK_MIC_CTRL_HMICBIASEN, - 0, NULL, 0), + 0, sun50i_codec_hbias_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), /* Mic input path */ SND_SOC_DAPM_PGA("Mic2 Amplifier", SUN50I_ADDA_MIC2_CTRL, @@ -474,14 +490,28 @@ static const struct snd_soc_dapm_route sun50i_a64_codec_routes[] = { static int sun50i_a64_codec_set_bias_level(struct snd_soc_component *component, enum snd_soc_bias_level level) { + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + int hbias; + switch (level) { case SND_SOC_BIAS_OFF: + regmap_clear_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL, + BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) | + BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN)); + regmap_set_bits(component->regmap, SUN50I_ADDA_HP_CTRL, BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE)); break; case SND_SOC_BIAS_STANDBY: regmap_clear_bits(component->regmap, SUN50I_ADDA_HP_CTRL, BIT(SUN50I_ADDA_HP_CTRL_PA_CLK_GATE)); + + hbias = snd_soc_dapm_get_pin_status(dapm, "HBIAS"); + regmap_update_bits(component->regmap, SUN50I_ADDA_JACK_MIC_CTRL, + BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) | + BIT(SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN), + BIT(SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN) | + hbias << SUN50I_ADDA_JACK_MIC_CTRL_MICADCEN); break; default: break; From patchwork Sat Feb 24 13:54:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Ond=C5=99ej_Jirman?= X-Patchwork-Id: 205893 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7300:a81b:b0:108:e6aa:91d0 with SMTP id bq27csp1157335dyb; Sat, 24 Feb 2024 05:58:26 -0800 (PST) X-Forwarded-Encrypted: i=3; AJvYcCWAJnHZBM+95qtQRZmLs9pfCC/rB41Iq2osKGBnGnWeumoD2gkHWX45Ou+SK5sGrpa7MmATMjYjQRqegia+W0SK/nMo+Q== X-Google-Smtp-Source: AGHT+IE+DhYTtoVylXXWwhIK8fS85dTdtKPho95YFzisRDCIt9Cwcchu0IPtpX5QaG8ZdAYKt3jq X-Received: by 2002:a17:90a:ad97:b0:299:41dd:95c0 with SMTP id s23-20020a17090aad9700b0029941dd95c0mr3350077pjq.16.1708783105835; Sat, 24 Feb 2024 05:58:25 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1708783105; cv=pass; d=google.com; s=arc-20160816; b=0UuzIy9TvdSoCz3CiBLqpx2+VyXCv26P6zt8MnvnMa+PEp7CIIKWgo3FPQbs4q8elt vYk0qtf6Z6X4P8Y7XtJJJgXe9gsXLn/tZq/hSeZX5SbXinh6GTdXvlUU+gWFIkPLVtbv pH+DgWvbuhFFe5ZJ+S+eoM0dr1Un4+88I9Dswry4XwbhTWtHSI3hlhYSdEYPvGJzKvjV nPObfPBPIBSVwqiAw4ToSj4Ytd5dJiMqQkW6wV0GHXfwnFw+2PzvymaM0JP+XCKo09B0 Yw0cHbRnTXH+VTE5Ag+x53hzL0UocTDYKY0EGCUeO9x3EYhOxngLqtVmj/4Cv+mHIsRc OByg== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature; bh=oNS3XIvJyUinOUxhOX68dN2GsZ5MwvNNDptcrw/lEYs=; fh=AvgKWciTdOx1lyoO25YULpYZBLmX1pG/bKEy4jWriL0=; b=GImC/U8fRW+4ggH88s1tAtffAwqcy3+rgj09SeMPoKBIMzqCz4WOc4QS4PDqjpbHlS AzZPP8pvbzcWteTuMNUAgySqJWw3FNGIqP+kBq2XU2CDVriK1TnRD+cmeNFc7f3gSUFu GRuzZcTb1RRI/OVS2cCKWBnlCxbrh0+Q8ujwfnyly7QuM2VWBjlaRZ9iD3+ybZxnrlmq IjwoBp26+0PxrDNOTZwAcmd14jxB40YxiFSOcR5MxZKdoJbY4Yc96pdumAEiwpVs/hIv WBc7jbqrkP9DJioKulAW+kZYWwWHPjJ/74Kwu4v0QOFLYWdBNCqvQ/TSonJD5LQ2ebwF 9N+A==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b=MK2rejev; arc=pass (i=1 spf=pass spfdomain=xff.cz dkim=pass dkdomain=xff.cz dmarc=pass fromdomain=xff.cz); spf=pass (google.com: domain of linux-kernel+bounces-79697-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79697-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id l33-20020a635721000000b005cf0abea01dsi935525pgb.114.2024.02.24.05.58.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 24 Feb 2024 05:58:25 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-79697-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@xff.cz header.s=mail header.b=MK2rejev; arc=pass (i=1 spf=pass spfdomain=xff.cz dkim=pass dkdomain=xff.cz dmarc=pass fromdomain=xff.cz); spf=pass (google.com: domain of linux-kernel+bounces-79697-ouuuleilei=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-79697-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=xff.cz Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 64A55B215C1 for ; Sat, 24 Feb 2024 13:58:24 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 34B514F888; Sat, 24 Feb 2024 13:55:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=xff.cz header.i=@xff.cz header.b="MK2rejev" Received: from vps.xff.cz (vps.xff.cz [195.181.215.36]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C445447F7A; Sat, 24 Feb 2024 13:55:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=195.181.215.36 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708782916; cv=none; b=LTSi+1X/i6eXcavKvpgw3o7OM0I+l/KLZa1nQO4hAg0lqXD0WTDslx8JphsxzMoi+exn6oT48BXTPKtiyPDUGwPwiSWf787j0swViQ/NNSx2AFAM8XUQvNMfaEGjeaCb2t/mcknwEXGSVDLoeE1IQGUlu/cLKuntdMrDRuH278U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708782916; c=relaxed/simple; bh=+KDS8iSsEdaVbR9vv7dpeQO+DKaM2BjDrK0qFu2BvpQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=s850RGpPlIMWHOFFNvClD7g5qGq5RwOLysFk9eMlB4YRcFg1mCbE8h1CPIhqTvJUh+h6tCSSnFjRXdOTrAEej1zQGp4R2YQgmQUi2kUFgYigUjEgndFvVJuQ4BqcTgx6jXJ/pktFfvyyqT34s+nkAyiC7L6g9bjkXcF9tE9Rl2w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=xff.cz; spf=pass smtp.mailfrom=xff.cz; dkim=pass (1024-bit key) header.d=xff.cz header.i=@xff.cz header.b=MK2rejev; arc=none smtp.client-ip=195.181.215.36 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=xff.cz Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=xff.cz DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=xff.cz; s=mail; t=1708782910; bh=+KDS8iSsEdaVbR9vv7dpeQO+DKaM2BjDrK0qFu2BvpQ=; h=From:To:Cc:Subject:Date:References:From; b=MK2rejevt013by9I7BGX/3+nLkAp0NafG0p6IlM/MvMEtA5K7bvxWUDIlKroJIR9g /G5MTMSh9Qo3Ems+FIbb1yJPYM7nBlJuYic2vuUDmn9w15cxz5Du9LA9tYSoLDpIQ4 XANnoF3NS4f2ea6DWGCyQhUNoNaoQkc6Ez75Z1Gs= From: =?utf-8?q?Ond=C5=99ej_Jirman?= To: linux-kernel@vger.kernel.org, Liam Girdwood , Rob Herring , Conor Dooley , Mark Brown , Jaroslav Kysela , Takashi Iwai Cc: Arnaud Ferraris , Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Ondrej Jirman , linux-sound@vger.kernel.org, linux-arm-kernel@lists.infradead.org, devicetree@vger.kernel.org, linux-sunxi@lists.linux.dev Subject: [RESEND PATCH v2 5/5] ASoC: sun8i-codec: Implement jack and accessory detection Date: Sat, 24 Feb 2024 14:54:58 +0100 Message-ID: <20240224135501.3822390-6-megi@xff.cz> In-Reply-To: <20240224135501.3822390-1-megi@xff.cz> References: <20240224135501.3822390-1-megi@xff.cz> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1791788954163113938 X-GMAIL-MSGID: 1791788954163113938 From: Arnaud Ferraris Add support for the jack detection functionality in the A64 variant, which uses a pair of IRQs; and microphone accessory (button) detection, which uses an ADC with an IRQ trigger. IRQs will only be triggered if the JACKDETEN, HMICBIASEN, and MICADCEN bits are set appropriately in the analog codec component (sun50i-codec-analog), but there is no direct software dependency between the two components. Setup ADC so that it samples with period of 16ms, disable smoothing and enable MDATA threshold (should be below idle voltage/HMIC_DATA value). Also enable HMIC_N, which makes sure we get HMIC_N samples after HMIC_DATA crosses the threshold. This allows us to perform steady state detection of HMIC_DATA, by comparing current and previous ADC samples, to detect end of the transient when the user de-presses the button. Otherwise ADC could sample anywhere within the transient, and the driver may mis-issue key-press events for other buttons attached to the resistor ladder. Signed-off-by: Arnaud Ferraris [Samuel: Decouple from analog codec, fixes] Co-developed-by: Samuel Holland Signed-off-by: Samuel Holland [Ondrej: Almost complete rewrite of the patch, change to use set_jack/ get_jack_type. Better de-bounce, fix mic button handling, better interrupt processing.] Co-developed-by: Ondrej Jirman Signed-off-by: Ondrej Jirman --- sound/soc/sunxi/sun50i-codec-analog.c | 12 + sound/soc/sunxi/sun8i-codec.c | 318 ++++++++++++++++++++++++++ 2 files changed, 330 insertions(+) diff --git a/sound/soc/sunxi/sun50i-codec-analog.c b/sound/soc/sunxi/sun50i-codec-analog.c index 2081721a8ff2..2dcdf113b66e 100644 --- a/sound/soc/sunxi/sun50i-codec-analog.c +++ b/sound/soc/sunxi/sun50i-codec-analog.c @@ -115,6 +115,11 @@ #define SUN50I_ADDA_HS_MBIAS_CTRL 0x0e #define SUN50I_ADDA_HS_MBIAS_CTRL_MMICBIASEN 7 +#define SUN50I_ADDA_MDET_CTRL 0x1c +#define SUN50I_ADDA_MDET_CTRL_SELDETADC_FS 4 +#define SUN50I_ADDA_MDET_CTRL_SELDETADC_DB 2 +#define SUN50I_ADDA_MDET_CTRL_SELDETADC_BF 0 + #define SUN50I_ADDA_JACK_MIC_CTRL 0x1d #define SUN50I_ADDA_JACK_MIC_CTRL_JACKDETEN 7 #define SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN 6 @@ -564,6 +569,13 @@ static int sun50i_codec_analog_probe(struct platform_device *pdev) BIT(SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN), enable << SUN50I_ADDA_JACK_MIC_CTRL_INNERRESEN); + /* Select sample interval of the ADC sample to 16ms */ + regmap_update_bits(regmap, SUN50I_ADDA_MDET_CTRL, + 0x7 << SUN50I_ADDA_MDET_CTRL_SELDETADC_FS | + 0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_BF, + 0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_FS | + 0x3 << SUN50I_ADDA_MDET_CTRL_SELDETADC_BF); + return devm_snd_soc_register_component(&pdev->dev, &sun50i_codec_analog_cmpnt_drv, NULL, 0); diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 2a46b96b03cc..097418364985 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -12,12 +12,16 @@ #include #include #include +#include #include +#include +#include #include #include #include #include +#include #include #include #include @@ -118,6 +122,23 @@ #define SUN8I_ADC_VOL_CTRL 0x104 #define SUN8I_ADC_VOL_CTRL_ADCL_VOL 8 #define SUN8I_ADC_VOL_CTRL_ADCR_VOL 0 +#define SUN8I_HMIC_CTRL1 0x110 +#define SUN8I_HMIC_CTRL1_HMIC_M 12 +#define SUN8I_HMIC_CTRL1_HMIC_N 8 +#define SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB 5 +#define SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN 4 +#define SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN 3 +#define SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN 0 +#define SUN8I_HMIC_CTRL2 0x114 +#define SUN8I_HMIC_CTRL2_HMIC_SAMPLE 14 +#define SUN8I_HMIC_CTRL2_HMIC_MDATA_THRESHOLD 8 +#define SUN8I_HMIC_CTRL2_HMIC_SF 6 +#define SUN8I_HMIC_STS 0x118 +#define SUN8I_HMIC_STS_MDATA_DISCARD 13 +#define SUN8I_HMIC_STS_HMIC_DATA 8 +#define SUN8I_HMIC_STS_JACK_OUT_IRQ_ST 4 +#define SUN8I_HMIC_STS_JACK_IN_IRQ_ST 3 +#define SUN8I_HMIC_STS_HMIC_DATA_IRQ_ST 0 #define SUN8I_DAC_DIG_CTRL 0x120 #define SUN8I_DAC_DIG_CTRL_ENDA 15 #define SUN8I_DAC_VOL_CTRL 0x124 @@ -143,6 +164,17 @@ #define SUN8I_AIF_CLK_CTRL_WORD_SIZ_MASK GENMASK(5, 4) #define SUN8I_AIF_CLK_CTRL_DATA_FMT_MASK GENMASK(3, 2) #define SUN8I_AIF3_CLK_CTRL_AIF3_CLK_SRC_MASK GENMASK(1, 0) +#define SUN8I_HMIC_CTRL1_HMIC_M_MASK GENMASK(15, 12) +#define SUN8I_HMIC_CTRL1_HMIC_N_MASK GENMASK(11, 8) +#define SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB_MASK GENMASK(6, 5) +#define SUN8I_HMIC_CTRL2_HMIC_SAMPLE_MASK GENMASK(15, 14) +#define SUN8I_HMIC_CTRL2_HMIC_SF_MASK GENMASK(7, 6) +#define SUN8I_HMIC_STS_HMIC_DATA_MASK GENMASK(12, 8) + +#define SUN8I_CODEC_BUTTONS (SND_JACK_BTN_0|\ + SND_JACK_BTN_1|\ + SND_JACK_BTN_2|\ + SND_JACK_BTN_3) #define SUN8I_CODEC_PASSTHROUGH_SAMPLE_RATE 48000 @@ -178,16 +210,32 @@ struct sun8i_codec_aif { struct sun8i_codec_quirks { bool bus_clock : 1; + bool jack_detection : 1; bool legacy_widgets : 1; bool lrck_inversion : 1; }; +enum { + SUN8I_JACK_STATUS_DISCONNECTED, + SUN8I_JACK_STATUS_WAITING_HBIAS, + SUN8I_JACK_STATUS_CONNECTED, +}; + struct sun8i_codec { + struct snd_soc_component *component; struct regmap *regmap; struct clk *clk_bus; struct clk *clk_module; const struct sun8i_codec_quirks *quirks; struct sun8i_codec_aif aifs[SUN8I_CODEC_NAIFS]; + struct snd_soc_jack *jack; + struct delayed_work jack_work; + int jack_irq; + int jack_status; + int jack_last_sample; + ktime_t jack_hbias_ready; + struct mutex jack_mutex; + int last_hmic_irq; unsigned int sysclk_rate; int sysclk_refcnt; }; @@ -1245,6 +1293,8 @@ static int sun8i_codec_component_probe(struct snd_soc_component *component) struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component); int ret; + scodec->component = component; + /* Add widgets for backward compatibility with old device trees. */ if (scodec->quirks->legacy_widgets) { ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_legacy_widgets, @@ -1281,6 +1331,263 @@ static int sun8i_codec_component_probe(struct snd_soc_component *component) return 0; } +static void sun8i_codec_set_hmic_bias(struct sun8i_codec *scodec, bool enable) +{ + struct snd_soc_dapm_context *dapm = &scodec->component->card->dapm; + int irq_mask = BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN); + + if (enable) + snd_soc_dapm_force_enable_pin(dapm, "HBIAS"); + else + snd_soc_dapm_disable_pin(dapm, "HBIAS"); + + snd_soc_dapm_sync(dapm); + + regmap_update_bits(scodec->regmap, SUN8I_HMIC_CTRL1, + irq_mask, enable ? irq_mask : 0); +} + +static void sun8i_codec_jack_work(struct work_struct *work) +{ + struct sun8i_codec *scodec = container_of(work, struct sun8i_codec, + jack_work.work); + unsigned int mdata; + int type_mask = scodec->jack->jack->type; + int type; + + guard(mutex)(&scodec->jack_mutex); + + if (scodec->jack_status == SUN8I_JACK_STATUS_DISCONNECTED) { + if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_IN_IRQ_ST) + return; + + scodec->jack_last_sample = -1; + + if (type_mask & SND_JACK_MICROPHONE) { + /* + * If we were in disconnected state, we enable HBIAS and + * wait 600ms before reading initial HDATA value. + */ + scodec->jack_hbias_ready = ktime_add_ms(ktime_get(), 600); + sun8i_codec_set_hmic_bias(scodec, true); + queue_delayed_work(system_power_efficient_wq, + &scodec->jack_work, + msecs_to_jiffies(610)); + scodec->jack_status = SUN8I_JACK_STATUS_WAITING_HBIAS; + } else { + snd_soc_jack_report(scodec->jack, SND_JACK_HEADPHONE, + type_mask); + scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED; + } + } else if (scodec->jack_status == SUN8I_JACK_STATUS_WAITING_HBIAS) { + /* + * If we're waiting for HBIAS to stabilize, and we get plug-out + * interrupt and nothing more for > 100ms, just cancel the + * initialization. + */ + if (scodec->last_hmic_irq == SUN8I_HMIC_STS_JACK_OUT_IRQ_ST) { + scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED; + sun8i_codec_set_hmic_bias(scodec, false); + return; + } + + /* + * If we're not done waiting for HBIAS to stabilize, wait more. + */ + if (!ktime_after(ktime_get(), scodec->jack_hbias_ready)) { + s64 msecs = ktime_ms_delta(scodec->jack_hbias_ready, + ktime_get()); + + queue_delayed_work(system_power_efficient_wq, + &scodec->jack_work, + msecs_to_jiffies(msecs + 10)); + return; + } + + /* + * Everything is stabilized, determine jack type and report it. + */ + regmap_read(scodec->regmap, SUN8I_HMIC_STS, &mdata); + mdata &= SUN8I_HMIC_STS_HMIC_DATA_MASK; + mdata >>= SUN8I_HMIC_STS_HMIC_DATA; + + regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0); + + type = mdata < 16 ? SND_JACK_HEADPHONE : SND_JACK_HEADSET; + if (type == SND_JACK_HEADPHONE) + sun8i_codec_set_hmic_bias(scodec, false); + + snd_soc_jack_report(scodec->jack, type, type_mask); + scodec->jack_status = SUN8I_JACK_STATUS_CONNECTED; + } else if (scodec->jack_status == SUN8I_JACK_STATUS_CONNECTED) { + if (scodec->last_hmic_irq != SUN8I_HMIC_STS_JACK_OUT_IRQ_ST) + return; + + scodec->jack_status = SUN8I_JACK_STATUS_DISCONNECTED; + if (type_mask & SND_JACK_MICROPHONE) + sun8i_codec_set_hmic_bias(scodec, false); + + snd_soc_jack_report(scodec->jack, 0, type_mask); + } +} + +static irqreturn_t sun8i_codec_jack_irq(int irq, void *dev_id) +{ + struct sun8i_codec *scodec = dev_id; + int type = SND_JACK_HEADSET; + unsigned int status, value; + + guard(mutex)(&scodec->jack_mutex); + + regmap_read(scodec->regmap, SUN8I_HMIC_STS, &status); + regmap_write(scodec->regmap, SUN8I_HMIC_STS, status); + + /* + * De-bounce in/out interrupts via a delayed work re-scheduling to + * 100ms after each interrupt.. + */ + if (status & BIT(SUN8I_HMIC_STS_JACK_OUT_IRQ_ST)) { + /* + * Out interrupt has priority over in interrupt so that if + * we get both, we assume the disconnected state, which is + * safer. + */ + scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_OUT_IRQ_ST; + mod_delayed_work(system_power_efficient_wq, &scodec->jack_work, + msecs_to_jiffies(100)); + } else if (status & BIT(SUN8I_HMIC_STS_JACK_IN_IRQ_ST)) { + scodec->last_hmic_irq = SUN8I_HMIC_STS_JACK_IN_IRQ_ST; + mod_delayed_work(system_power_efficient_wq, &scodec->jack_work, + msecs_to_jiffies(100)); + } else if (status & BIT(SUN8I_HMIC_STS_HMIC_DATA_IRQ_ST)) { + /* + * Ignore data interrupts until jack status turns to connected + * state, which is after HMIC enable stabilization is completed. + * Until then tha data are bogus. + */ + if (scodec->jack_status != SUN8I_JACK_STATUS_CONNECTED) + return IRQ_HANDLED; + + value = (status & SUN8I_HMIC_STS_HMIC_DATA_MASK) >> + SUN8I_HMIC_STS_HMIC_DATA; + + /* + * Assumes 60 mV per ADC LSB increment, 2V bias voltage, 2.2kOhm + * bias resistor. + */ + if (value == 0) + type |= SND_JACK_BTN_0; + else if (value == 1) + type |= SND_JACK_BTN_3; + else if (value <= 3) + type |= SND_JACK_BTN_1; + else if (value <= 8) + type |= SND_JACK_BTN_2; + + /* + * De-bounce. Only report button after two consecutive A/D + * samples are identical. + */ + if (scodec->jack_last_sample >= 0 && + scodec->jack_last_sample == value) + snd_soc_jack_report(scodec->jack, type, + scodec->jack->jack->type); + + scodec->jack_last_sample = value; + } + + return IRQ_HANDLED; +} + +static int sun8i_codec_enable_jack_detect(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) +{ + struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component); + struct platform_device *pdev = to_platform_device(component->dev); + int ret; + + if (!scodec->quirks->jack_detection) + return 0; + + scodec->jack = jack; + + scodec->jack_irq = platform_get_irq(pdev, 0); + if (scodec->jack_irq < 0) + return scodec->jack_irq; + + /* Reserved value required for jack IRQs to trigger. */ + regmap_write(scodec->regmap, SUN8I_HMIC_CTRL1, + 0xf << SUN8I_HMIC_CTRL1_HMIC_N | + 0x0 << SUN8I_HMIC_CTRL1_MDATA_THRESHOLD_DB | + 0x4 << SUN8I_HMIC_CTRL1_HMIC_M); + + /* Sample the ADC at 128 Hz; bypass smooth filter. */ + regmap_write(scodec->regmap, SUN8I_HMIC_CTRL2, + 0x0 << SUN8I_HMIC_CTRL2_HMIC_SAMPLE | + 0x17 << SUN8I_HMIC_CTRL2_HMIC_MDATA_THRESHOLD | + 0x0 << SUN8I_HMIC_CTRL2_HMIC_SF); + + /* Do not discard any MDATA, enable user written MDATA threshold. */ + regmap_write(scodec->regmap, SUN8I_HMIC_STS, 0); + + regmap_set_bits(scodec->regmap, SUN8I_HMIC_CTRL1, + BIT(SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN) | + BIT(SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN)); + + ret = devm_request_threaded_irq(&pdev->dev, scodec->jack_irq, + NULL, sun8i_codec_jack_irq, + IRQF_ONESHOT, + dev_name(&pdev->dev), scodec); + if (ret) + return ret; + + return 0; +} + +static void sun8i_codec_disable_jack_detect(struct snd_soc_component *component) +{ + struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component); + + if (!scodec->quirks->jack_detection) + return; + + devm_free_irq(component->dev, scodec->jack_irq, scodec); + + cancel_delayed_work_sync(&scodec->jack_work); + + regmap_clear_bits(scodec->regmap, SUN8I_HMIC_CTRL1, + BIT(SUN8I_HMIC_CTRL1_JACK_OUT_IRQ_EN) | + BIT(SUN8I_HMIC_CTRL1_JACK_IN_IRQ_EN) | + BIT(SUN8I_HMIC_CTRL1_HMIC_DATA_IRQ_EN)); + + scodec->jack = NULL; +} + +static int sun8i_codec_component_get_jack_type(struct snd_soc_component *component) +{ + struct device_node *node = component->dev->of_node; + + if (of_property_match_string(node, "jack-type", "headset") >= 0) + return SND_JACK_HEADSET | SUN8I_CODEC_BUTTONS; + else if (of_property_match_string(node, "jack-type", "headphone") >= 0) + return SND_JACK_HEADPHONE; + + return 0; +} + +static int sun8i_codec_component_set_jack(struct snd_soc_component *component, + struct snd_soc_jack *jack, void *data) +{ + int ret = 0; + + if (jack) + ret = sun8i_codec_enable_jack_detect(component, jack, data); + else + sun8i_codec_disable_jack_detect(component); + + return ret; +} + static const struct snd_soc_component_driver sun8i_soc_component = { .controls = sun8i_codec_controls, .num_controls = ARRAY_SIZE(sun8i_codec_controls), @@ -1288,16 +1595,24 @@ static const struct snd_soc_component_driver sun8i_soc_component = { .num_dapm_widgets = ARRAY_SIZE(sun8i_codec_dapm_widgets), .dapm_routes = sun8i_codec_dapm_routes, .num_dapm_routes = ARRAY_SIZE(sun8i_codec_dapm_routes), + .set_jack = sun8i_codec_component_set_jack, + .get_jack_type = sun8i_codec_component_get_jack_type, .probe = sun8i_codec_component_probe, .idle_bias_on = 1, .suspend_bias_off = 1, .endianness = 1, }; +static bool sun8i_codec_volatile_reg(struct device *dev, unsigned int reg) +{ + return reg == SUN8I_HMIC_STS; +} + static const struct regmap_config sun8i_codec_regmap_config = { .reg_bits = 32, .reg_stride = 4, .val_bits = 32, + .volatile_reg = sun8i_codec_volatile_reg, .max_register = SUN8I_DAC_MXR_SRC, .cache_type = REGCACHE_FLAT, @@ -1314,6 +1629,8 @@ static int sun8i_codec_probe(struct platform_device *pdev) return -ENOMEM; scodec->quirks = of_device_get_match_data(&pdev->dev); + INIT_DELAYED_WORK(&scodec->jack_work, sun8i_codec_jack_work); + mutex_init(&scodec->jack_mutex); platform_set_drvdata(pdev, scodec); @@ -1387,6 +1704,7 @@ static const struct sun8i_codec_quirks sun8i_a33_quirks = { static const struct sun8i_codec_quirks sun50i_a64_quirks = { .bus_clock = true, + .jack_detection = true, }; static const struct of_device_id sun8i_codec_of_match[] = {