From patchwork Sat Oct 5 05:57:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 11175493 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EFC191709 for ; Sat, 5 Oct 2019 06:00:28 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 84FAE222C0 for ; Sat, 5 Oct 2019 06:00:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="b15C1Iwk"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="aIqzNjao" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 84FAE222C0 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 C4ACA167C; Sat, 5 Oct 2019 07:59:36 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C4ACA167C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1570255226; bh=dSqLiQZM3LRsqko2rhNe4K1PX7eDT2eM0wZGCXhWeOs=; h=Date:In-Reply-To:References:From:To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=b15C1IwktzElgwyFnWn/JaAGPmASTPRAhIyWD+2FLciQ+Tnw4cx2Zi9kIjyRiVoNO 2Y03R6WaK9nOKmFj0k9+T0FdEdRkue0Xd+PGL7RttbPwNsb9swhJsj41lPL0eWRr4D pCYahS48pCdQu0fujBvZ2nS5R+QMdvTcEggX64T0= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 4F248F805A0; Sat, 5 Oct 2019 07:58:43 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 2717BF805AF; Sat, 5 Oct 2019 07:58:42 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id C29ACF80137 for ; Sat, 5 Oct 2019 07:58:38 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz C29ACF80137 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="aIqzNjao" Received: by mail-qt1-x849.google.com with SMTP id d3so9034312qtr.2 for ; Fri, 04 Oct 2019 22:58:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=Z6x5CooX+KOT5/OTrrb8SPQO8MJH2PsqtriuzR88xtc=; b=aIqzNjao7eGlpDOkBJUo1bOShLQ0zbuy3gRuIGgwxMwHbzVXdUm/tmnBaTcv46rIcR eaw7GsfCxzAjSIADv8zxCBZSPfKF7t3HkG5uBqLZqwncZoGs6x02LW9vLTUvFILHXAN9 djcSKbCA/oCxL4sKnkVHlONRorVo1fku0bH8vL7hh0FaPy3vsZxxzXdaZM+b3FuEBStT LAHlL9cvDbmNSOG0kJq9h3oPk0WVgAtwhjebey4QPGImeZHzRhiIbpFi03Fzpe2jCCyB pKFWFQZR5eRna6U77eRNcxhioznupjEOFJXichqPmUixpCSWLC1MyFyeR4uIB4UcOsAH PtLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=Z6x5CooX+KOT5/OTrrb8SPQO8MJH2PsqtriuzR88xtc=; b=DW3cd4Qp9wLrjkYZ7KGyaEJKxIHMucrbSiasR4JWnA51ryp5JXK2A9lWIwUUeUcRlY GuvGyoeaJ+bWNgri5nAdIJqnXLtEaxfnb9HpajrUqBFuZz6gvuolc/Nh49CtAkDSoczp 9JJc7jPvqyNrfEb75tmfmgimBifv1fFULi/T9Hr40Im2p627BBzx26qJjRYE2L/EaVZs jj9rCcrlS/jT+cSLyUqhT3yaARPDVCMqQ1SfuMNnb5mkSKZ0Dkmqes0zwNMb1pnet40O +Vi4fayd8OFwF2qJYq6PeySE4P5DycHo+x9g6vjfr06eJcnJwXqlO6I1InFiWu/smk2s qBhA== X-Gm-Message-State: APjAAAWaqnREG4MLHA6cJwwZ7is4d/SM4F7+2+6U2DbrMPTTaZ+UC9b1 46pwMthIYi7UfyHHO9E3y6SX51+AWECg X-Google-Smtp-Source: APXvYqx2zBUYSjjB09ua6ZMesuhjXWY6OXHFCexT3WCngq0RnSzyv3lkzrA7ht0WMZDaW3QUwAsVPn3TuIFc X-Received: by 2002:ac8:6985:: with SMTP id o5mr2262786qtq.151.1570255117489; Fri, 04 Oct 2019 22:58:37 -0700 (PDT) Date: Sat, 5 Oct 2019 13:57:59 +0800 In-Reply-To: <20191005055808.249089-1-tzungbi@google.com> Message-Id: <20191005130552.1.I374c311eaca0d47944a37b07acbe48fdb74f734d@changeid> Mime-Version: 1.0 References: <20191005055808.249089-1-tzungbi@google.com> X-Mailer: git-send-email 2.23.0.581.g78d2f28ef7-goog From: Tzung-Bi Shih To: broonie@kernel.org Cc: gwendal@google.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, cychiang@google.com, drinkcat@google.com, tzungbi@google.com, robh+dt@kernel.org, enric.balletbo@collabora.com, bleung@google.com, dgreid@google.com Subject: [alsa-devel] [PATCH 01/10] platform/chrome: cros_ec: remove unused EC feature 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" Remove unused EC_FEATURE_AUDIO_CODEC. Signed-off-by: Tzung-Bi Shih --- include/linux/platform_data/cros_ec_commands.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 98415686cbfa..43b8f7dae4cc 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -1277,8 +1277,6 @@ enum ec_feature_code { * MOTIONSENSE_CMD_TABLET_MODE_LID_ANGLE. */ EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS = 37, - /* EC supports audio codec. */ - EC_FEATURE_AUDIO_CODEC = 38, /* The MCU is a System Companion Processor (SCP). */ EC_FEATURE_SCP = 39, /* The MCU is an Integrated Sensor Hub */ From patchwork Sat Oct 5 05:58:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 11175495 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 0B3761709 for ; Sat, 5 Oct 2019 06:01:16 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 8F7E020830 for ; Sat, 5 Oct 2019 06:01:15 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="hxZNa7dw"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="PdUeuBF/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8F7E020830 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 B62F3168E; Sat, 5 Oct 2019 08:00:23 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B62F3168E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1570255273; bh=Zye/CB8hQ8xKucoprdtrpW8z8B9J3ijU5P2CubaVdZE=; h=Date:In-Reply-To:References:From:To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=hxZNa7dwjLYPBW8c051drIhQ9fC4K3r8PSu24MuFtXl5nJYhWXmQoL5wQC+xvehVt 8uJQlFxqx5VYL0c8q4YFtBLxy4icGvWyIt6G0nPAFBp2asHtLfpClOxHcPoyfE2ZN/ 5XweuMv1xfTWbTZ/YfEVlsRu8vsRnJP38XM8fnkQ= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 8B27AF805FB; Sat, 5 Oct 2019 07:58:49 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id ED48EF805FC; Sat, 5 Oct 2019 07:58:47 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 400C3F805AF for ; Sat, 5 Oct 2019 07:58:44 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 400C3F805AF Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="PdUeuBF/" Received: by mail-qt1-x849.google.com with SMTP id m6so8927768qtk.23 for ; Fri, 04 Oct 2019 22:58:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=pcEvtHEgwhJdYwtCmoTG06J4DaEkR26zSb6abuQZf24=; b=PdUeuBF/2gbp0q32H0fBfPR6DimIm3GReHq5uz2OWgZcqVo0MCv0VZpF29NyXavEuK M+Jn+kJUzizIdoga8z6Qm7GIxUynlXJl1pygmlUN3gcGYEMt45OnxmRKBjhoBKcDj1+u rp0KNKVCYvgYTxjxv3BVCvo7yo0kPyrTCbrxZxA10hkFxUrLbNOqdqQ4GBjCmCwNNhGd Ns9YUYPwlAbvH//Et1OfEaeRB1pIdgMl+31qSqBZ5zcChO9fC9j6iK693CZPo6SNCiWz RYo109Q+ZLWrlDiIX4vDkRYVBkOjCJ/uG/BK4NbVXdyhPuI8W/Y8aLkmkq+eJiBgT+KT hceQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=pcEvtHEgwhJdYwtCmoTG06J4DaEkR26zSb6abuQZf24=; b=Wa0yvRvR23D7yXc7DZVGbSYgCqhSJJWwu28ItTeUJZ2n7y3L++GVeaTF8XMgNjqHQQ 5P0/GhDlJMGNim6BlNC3rAnHUjvOeNaHlZ35VYiVacd9pQwdtn6D8zqzuJ150K8AoggB g/67a52MAwCkoM0ubFx+8DEMi3+zazbedoyqcc1w2CFCHnfpYf9K2wJz9JhKsB2jnSLv Xq5cOSTQP3izTlaeI1NBcyYODMYCxq7yZOQHTSRQjjMlWDM9CGeZSWW/dAKyekoFd7aR bGeZyCgcCSTXPVH/9o/Gnyttpk0Nt133QVTT1efaAd+mdWIFArUdKIuJNqWKWqQelTkR /P7A== X-Gm-Message-State: APjAAAVtjpIlMAxGG4XBCUZkOVYahKbU13itgLRF3yML6OLIeevefy2Q KG24Y1IdnjV4kEiXDcU0jcDxHA06xG1N X-Google-Smtp-Source: APXvYqz4Bk1bDWbqmSiLhGKP+cVrCMtb8alwqC8QtALGnwuvNNKtHze+kuc1/uz63Y/wgD0n+T4v2e7ZKhV9 X-Received: by 2002:a37:a106:: with SMTP id k6mr13411292qke.158.1570255122956; Fri, 04 Oct 2019 22:58:42 -0700 (PDT) Date: Sat, 5 Oct 2019 13:58:00 +0800 In-Reply-To: <20191005055808.249089-1-tzungbi@google.com> Message-Id: <20191005130552.2.I43373b9a66dbb70196b3f216b3aa86111c410836@changeid> Mime-Version: 1.0 References: <20191005055808.249089-1-tzungbi@google.com> X-Mailer: git-send-email 2.23.0.581.g78d2f28ef7-goog From: Tzung-Bi Shih To: broonie@kernel.org Cc: gwendal@google.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, cychiang@google.com, drinkcat@google.com, tzungbi@google.com, robh+dt@kernel.org, enric.balletbo@collabora.com, bleung@google.com, dgreid@google.com Subject: [alsa-devel] [PATCH 02/10] ASoC: cros_ec_codec: refactor I2S RX 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" Refactor by the following items: - reformat copyright declaration - use more specific name "i2s rx" - use verbose symbol names to separate namespaces - make some short functions inline - remove unused TDM-related code Signed-off-by: Tzung-Bi Shih --- drivers/platform/chrome/cros_ec_trace.c | 2 +- .../linux/platform_data/cros_ec_commands.h | 120 ++--- sound/soc/codecs/cros_ec_codec.c | 502 +++++++----------- 3 files changed, 251 insertions(+), 373 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_trace.c b/drivers/platform/chrome/cros_ec_trace.c index 6f80ff4532ae..901850004b2b 100644 --- a/drivers/platform/chrome/cros_ec_trace.c +++ b/drivers/platform/chrome/cros_ec_trace.c @@ -98,7 +98,7 @@ TRACE_SYMBOL(EC_CMD_SB_READ_BLOCK), \ TRACE_SYMBOL(EC_CMD_SB_WRITE_BLOCK), \ TRACE_SYMBOL(EC_CMD_BATTERY_VENDOR_PARAM), \ - TRACE_SYMBOL(EC_CMD_CODEC_I2S), \ + TRACE_SYMBOL(EC_CMD_EC_CODEC_I2S_RX), \ TRACE_SYMBOL(EC_CMD_REBOOT_EC), \ TRACE_SYMBOL(EC_CMD_GET_PANIC_INFO), \ TRACE_SYMBOL(EC_CMD_ACPI_READ), \ diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 43b8f7dae4cc..261ac83bd007 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -4466,92 +4466,74 @@ enum mkbp_cec_event { /*****************************************************************************/ -/* Commands for I2S recording on audio codec. */ - -#define EC_CMD_CODEC_I2S 0x00BC -#define EC_WOV_I2S_SAMPLE_RATE 48000 - -enum ec_codec_i2s_subcmd { - EC_CODEC_SET_SAMPLE_DEPTH = 0x0, - EC_CODEC_SET_GAIN = 0x1, - EC_CODEC_GET_GAIN = 0x2, - EC_CODEC_I2S_ENABLE = 0x3, - EC_CODEC_I2S_SET_CONFIG = 0x4, - EC_CODEC_I2S_SET_TDM_CONFIG = 0x5, - EC_CODEC_I2S_SET_BCLK = 0x6, - EC_CODEC_I2S_SUBCMD_COUNT = 0x7, +/* Commands for I2S RX on audio codec. */ + +#define EC_CMD_EC_CODEC_I2S_RX 0x00BC + +enum ec_codec_i2s_rx_subcmd { + EC_CODEC_I2S_RX_ENABLE = 0x0, + EC_CODEC_I2S_RX_DISABLE = 0x1, + EC_CODEC_I2S_RX_SET_GAIN = 0x2, + EC_CODEC_I2S_RX_GET_GAIN = 0x3, + EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH = 0x4, + EC_CODEC_I2S_RX_SET_DAIFMT = 0x5, + EC_CODEC_I2S_RX_SET_BCLK = 0x6, + EC_CODEC_I2S_RX_SUBCMD_COUNT, }; -enum ec_sample_depth_value { - EC_CODEC_SAMPLE_DEPTH_16 = 0, - EC_CODEC_SAMPLE_DEPTH_24 = 1, +enum ec_codec_i2s_rx_sample_depth { + EC_CODEC_I2S_RX_SAMPLE_DEPTH_16 = 0x0, + EC_CODEC_I2S_RX_SAMPLE_DEPTH_24 = 0x1, + EC_CODEC_I2S_RX_SAMPLE_DEPTH_COUNT, }; -enum ec_i2s_config { - EC_DAI_FMT_I2S = 0, - EC_DAI_FMT_RIGHT_J = 1, - EC_DAI_FMT_LEFT_J = 2, - EC_DAI_FMT_PCM_A = 3, - EC_DAI_FMT_PCM_B = 4, - EC_DAI_FMT_PCM_TDM = 5, +enum ec_codec_i2s_rx_daifmt { + EC_CODEC_I2S_RX_DAIFMT_I2S = 0x0, + EC_CODEC_I2S_RX_DAIFMT_RIGHT_J = 0x1, + EC_CODEC_I2S_RX_DAIFMT_LEFT_J = 0x2, + EC_CODEC_I2S_RX_DAIFMT_COUNT, }; -/* - * For subcommand EC_CODEC_GET_GAIN. - */ -struct __ec_align1 ec_codec_i2s_gain { +struct __ec_align1 ec_param_ec_codec_i2s_rx_set_sample_depth { + uint8_t depth; + uint8_t reserved[3]; +}; + +struct __ec_align1 ec_param_ec_codec_i2s_rx_set_gain { uint8_t left; uint8_t right; + uint8_t reserved[2]; }; -struct __ec_todo_unpacked ec_param_codec_i2s_tdm { - int16_t ch0_delay; /* 0 to 496 */ - int16_t ch1_delay; /* -1 to 496 */ - uint8_t adjacent_to_ch0; - uint8_t adjacent_to_ch1; +struct __ec_align1 ec_param_ec_codec_i2s_rx_set_daifmt { + uint8_t daifmt; + uint8_t reserved[3]; }; -struct __ec_todo_packed ec_param_codec_i2s { - /* enum ec_codec_i2s_subcmd */ - uint8_t cmd; - union { - /* - * EC_CODEC_SET_SAMPLE_DEPTH - * Value should be one of ec_sample_depth_value. - */ - uint8_t depth; - - /* - * EC_CODEC_SET_GAIN - * Value should be 0~43 for both channels. - */ - struct ec_codec_i2s_gain gain; - - /* - * EC_CODEC_I2S_ENABLE - * 1 to enable, 0 to disable. - */ - uint8_t i2s_enable; - - /* - * EC_CODEC_I2S_SET_CONFIG - * Value should be one of ec_i2s_config. - */ - uint8_t i2s_config; +struct __ec_align4 ec_param_ec_codec_i2s_rx_set_bclk { + uint32_t bclk; +}; - /* - * EC_CODEC_I2S_SET_TDM_CONFIG - * Value should be one of ec_i2s_config. - */ - struct ec_param_codec_i2s_tdm tdm_param; +struct __ec_align4 ec_param_ec_codec_i2s_rx { + uint8_t cmd; /* enum ec_codec_i2s_rx_subcmd */ + uint8_t reserved[3]; - /* - * EC_CODEC_I2S_SET_BCLK - */ - uint32_t bclk; + union { + struct ec_param_ec_codec_i2s_rx_set_sample_depth + set_sample_depth_param; + struct ec_param_ec_codec_i2s_rx_set_gain + set_gain_param; + struct ec_param_ec_codec_i2s_rx_set_daifmt + set_daifmt_param; + struct ec_param_ec_codec_i2s_rx_set_bclk + set_bclk_param; }; }; +struct __ec_align1 ec_response_ec_codec_i2s_rx_get_gain { + uint8_t left; + uint8_t right; +}; /*****************************************************************************/ /* System commands */ diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 3c1bd24a1057..179fa77291cd 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -1,6 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Driver for ChromeOS Embedded Controller codec. + * Copyright 2019 Google, Inc. + * + * ChromeOS Embedded Controller codec driver. * * This driver uses the cros-ec interface to communicate with the ChromeOS * EC for audio function. @@ -18,403 +20,297 @@ #include #include -#define DRV_NAME "cros-ec-codec" - -/** - * struct cros_ec_codec_data - ChromeOS EC codec driver data. - * @dev: Device structure used in sysfs. - * @ec_device: cros_ec_device structure to talk to the physical device. - * @component: Pointer to the component. - * @max_dmic_gain: Maximum gain in dB supported by EC codec. - */ -struct cros_ec_codec_data { +struct cros_ec_codec_priv { struct device *dev; struct cros_ec_device *ec_device; - struct snd_soc_component *component; - unsigned int max_dmic_gain; }; -static const DECLARE_TLV_DB_SCALE(ec_mic_gain_tlv, 0, 100, 0); - -static int ec_command_get_gain(struct snd_soc_component *component, - struct ec_param_codec_i2s *param, - struct ec_codec_i2s_gain *resp) +static int send_ec_host_command(struct cros_ec_device *ec_dev, uint32_t cmd, + uint8_t *out, size_t outsize, + uint8_t *in, size_t insize) { - struct cros_ec_codec_data *codec_data = - snd_soc_component_get_drvdata(component); - struct cros_ec_device *ec_device = codec_data->ec_device; - u8 buffer[sizeof(struct cros_ec_command) + - max(sizeof(struct ec_param_codec_i2s), - sizeof(struct ec_codec_i2s_gain))]; - struct cros_ec_command *msg = (struct cros_ec_command *)&buffer; int ret; + struct cros_ec_command *msg; + + msg = kmalloc(sizeof(*msg) + max(outsize, insize), GFP_KERNEL); + if (!msg) + return -ENOMEM; msg->version = 0; - msg->command = EC_CMD_CODEC_I2S; - msg->outsize = sizeof(struct ec_param_codec_i2s); - msg->insize = sizeof(struct ec_codec_i2s_gain); + msg->command = cmd; + msg->outsize = outsize; + msg->insize = insize; + + if (outsize) + memcpy(msg->data, out, outsize); - memcpy(msg->data, param, msg->outsize); + ret = cros_ec_cmd_xfer_status(ec_dev, msg); + if (ret < 0) + goto error; - ret = cros_ec_cmd_xfer_status(ec_device, msg); - if (ret > 0) - memcpy(resp, msg->data, msg->insize); + if (insize) + memcpy(in, msg->data, insize); + ret = 0; +error: + kfree(msg); return ret; } -/* - * Wrapper for EC command without response. - */ -static int ec_command_no_resp(struct snd_soc_component *component, - struct ec_param_codec_i2s *param) +static int dmic_get_gain(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct cros_ec_codec_data *codec_data = + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(component); - struct cros_ec_device *ec_device = codec_data->ec_device; - u8 buffer[sizeof(struct cros_ec_command) + - sizeof(struct ec_param_codec_i2s)]; - struct cros_ec_command *msg = (struct cros_ec_command *)&buffer; - - msg->version = 0; - msg->command = EC_CMD_CODEC_I2S; - msg->outsize = sizeof(struct ec_param_codec_i2s); - msg->insize = 0; - - memcpy(msg->data, param, msg->outsize); - - return cros_ec_cmd_xfer_status(ec_device, msg); -} - -static int set_i2s_config(struct snd_soc_component *component, - enum ec_i2s_config i2s_config) -{ - struct ec_param_codec_i2s param; + struct ec_param_ec_codec_i2s_rx p; + struct ec_response_ec_codec_i2s_rx_get_gain r; + int ret; - dev_dbg(component->dev, "%s set I2S format to %u\n", __func__, - i2s_config); + p.cmd = EC_CODEC_I2S_RX_GET_GAIN; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, + (uint8_t *)&p, sizeof(p), + (uint8_t *)&r, sizeof(r)); + if (ret < 0) + return ret; - param.cmd = EC_CODEC_I2S_SET_CONFIG; - param.i2s_config = i2s_config; + ucontrol->value.integer.value[0] = r.left; + ucontrol->value.integer.value[1] = r.right; - return ec_command_no_resp(component, ¶m); + return 0; } -static int cros_ec_i2s_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +static int dmic_put_gain(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { - struct snd_soc_component *component = dai->component; - enum ec_i2s_config i2s_config; - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - break; - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - i2s_config = EC_DAI_FMT_I2S; - break; - - case SND_SOC_DAIFMT_RIGHT_J: - i2s_config = EC_DAI_FMT_RIGHT_J; - break; - - case SND_SOC_DAIFMT_LEFT_J: - i2s_config = EC_DAI_FMT_LEFT_J; - break; - - case SND_SOC_DAIFMT_DSP_A: - i2s_config = EC_DAI_FMT_PCM_A; - break; - - case SND_SOC_DAIFMT_DSP_B: - i2s_config = EC_DAI_FMT_PCM_B; - break; + struct snd_soc_component *component = + snd_soc_kcontrol_component(kcontrol); + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + struct soc_mixer_control *control = + (struct soc_mixer_control *)kcontrol->private_value; + int max_dmic_gain = control->max; + int left = ucontrol->value.integer.value[0]; + int right = ucontrol->value.integer.value[1]; + struct ec_param_ec_codec_i2s_rx p; - default: + if (left > max_dmic_gain || right > max_dmic_gain) return -EINVAL; - } - return set_i2s_config(component, i2s_config); -} - -static int set_i2s_sample_depth(struct snd_soc_component *component, - enum ec_sample_depth_value depth) -{ - struct ec_param_codec_i2s param; - - dev_dbg(component->dev, "%s set depth to %u\n", __func__, depth); - - param.cmd = EC_CODEC_SET_SAMPLE_DEPTH; - param.depth = depth; + dev_dbg(component->dev, "set mic gain to %u, %u\n", left, right); - return ec_command_no_resp(component, ¶m); + p.cmd = EC_CODEC_I2S_RX_SET_GAIN; + p.set_gain_param.left = left; + p.set_gain_param.right = right; + return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, + (uint8_t *)&p, sizeof(p), NULL, 0); } -static int set_i2s_bclk(struct snd_soc_component *component, uint32_t bclk) -{ - struct ec_param_codec_i2s param; - - dev_dbg(component->dev, "%s set i2s bclk to %u\n", __func__, bclk); +static const DECLARE_TLV_DB_SCALE(dmic_gain_tlv, 0, 100, 0); - param.cmd = EC_CODEC_I2S_SET_BCLK; - param.bclk = bclk; +enum { + DMIC_CTL_GAIN = 0, +}; - return ec_command_no_resp(component, ¶m); -} +static struct snd_kcontrol_new dmic_controls[] = { + [DMIC_CTL_GAIN] = + SOC_DOUBLE_EXT_TLV("EC Mic Gain", SND_SOC_NOPM, SND_SOC_NOPM, + 0, 0, 0, dmic_get_gain, dmic_put_gain, + dmic_gain_tlv), +}; -static int cros_ec_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) +static int i2s_rx_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; - unsigned int rate, bclk; + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + struct ec_param_ec_codec_i2s_rx p; + enum ec_codec_i2s_rx_sample_depth depth; int ret; - rate = params_rate(params); - if (rate != 48000) + if (params_rate(params) != 48000) return -EINVAL; switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: - ret = set_i2s_sample_depth(component, EC_CODEC_SAMPLE_DEPTH_16); + depth = EC_CODEC_I2S_RX_SAMPLE_DEPTH_16; break; case SNDRV_PCM_FORMAT_S24_LE: - ret = set_i2s_sample_depth(component, EC_CODEC_SAMPLE_DEPTH_24); + depth = EC_CODEC_I2S_RX_SAMPLE_DEPTH_24; break; default: return -EINVAL; } - if (ret < 0) - return ret; - - bclk = snd_soc_params_to_bclk(params); - return set_i2s_bclk(component, bclk); -} -static const struct snd_soc_dai_ops cros_ec_i2s_dai_ops = { - .hw_params = cros_ec_i2s_hw_params, - .set_fmt = cros_ec_i2s_set_dai_fmt, -}; + dev_dbg(component->dev, "set depth to %u\n", depth); -static struct snd_soc_dai_driver cros_ec_dai[] = { - { - .name = "cros_ec_codec I2S", - .id = 0, - .capture = { - .stream_name = "I2S Capture", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S24_LE, - }, - .ops = &cros_ec_i2s_dai_ops, - } -}; - -static int get_ec_mic_gain(struct snd_soc_component *component, - u8 *left, u8 *right) -{ - struct ec_param_codec_i2s param; - struct ec_codec_i2s_gain resp; - int ret; - - param.cmd = EC_CODEC_GET_GAIN; - - ret = ec_command_get_gain(component, ¶m, &resp); + p.cmd = EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH; + p.set_sample_depth_param.depth = depth; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, + (uint8_t *)&p, sizeof(p), NULL, 0); if (ret < 0) return ret; - *left = resp.left; - *right = resp.right; - - return 0; -} - -static int mic_gain_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component = - snd_soc_kcontrol_component(kcontrol); - u8 left, right; - int ret; - - ret = get_ec_mic_gain(component, &left, &right); - if (ret) - return ret; - - ucontrol->value.integer.value[0] = left; - ucontrol->value.integer.value[1] = right; - - return 0; -} - -static int set_ec_mic_gain(struct snd_soc_component *component, - u8 left, u8 right) -{ - struct ec_param_codec_i2s param; - - dev_dbg(component->dev, "%s set mic gain to %u, %u\n", - __func__, left, right); + dev_dbg(component->dev, "set bclk to %u\n", + snd_soc_params_to_bclk(params)); - param.cmd = EC_CODEC_SET_GAIN; - param.gain.left = left; - param.gain.right = right; - - return ec_command_no_resp(component, ¶m); + p.cmd = EC_CODEC_I2S_RX_SET_BCLK; + p.set_bclk_param.bclk = snd_soc_params_to_bclk(params); + return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, + (uint8_t *)&p, sizeof(p), NULL, 0); } -static int mic_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static int i2s_rx_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) { - struct snd_soc_component *component = - snd_soc_kcontrol_component(kcontrol); - struct cros_ec_codec_data *codec_data = + struct snd_soc_component *component = dai->component; + struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(component); - int left = ucontrol->value.integer.value[0]; - int right = ucontrol->value.integer.value[1]; - unsigned int max_dmic_gain = codec_data->max_dmic_gain; + struct ec_param_ec_codec_i2s_rx p; + enum ec_codec_i2s_rx_daifmt daifmt; - if (left > max_dmic_gain || right > max_dmic_gain) + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: return -EINVAL; + } - return set_ec_mic_gain(component, (u8)left, (u8)right); -} - -static struct snd_kcontrol_new mic_gain_control = - SOC_DOUBLE_EXT_TLV("EC Mic Gain", SND_SOC_NOPM, SND_SOC_NOPM, 0, 0, 0, - mic_gain_get, mic_gain_put, ec_mic_gain_tlv); - -static int enable_i2s(struct snd_soc_component *component, int enable) -{ - struct ec_param_codec_i2s param; + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + default: + return -EINVAL; + } - dev_dbg(component->dev, "%s set i2s to %u\n", __func__, enable); + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + daifmt = EC_CODEC_I2S_RX_DAIFMT_I2S; + break; + case SND_SOC_DAIFMT_RIGHT_J: + daifmt = EC_CODEC_I2S_RX_DAIFMT_RIGHT_J; + break; + case SND_SOC_DAIFMT_LEFT_J: + daifmt = EC_CODEC_I2S_RX_DAIFMT_LEFT_J; + break; + default: + return -EINVAL; + } - param.cmd = EC_CODEC_I2S_ENABLE; - param.i2s_enable = enable; + dev_dbg(component->dev, "set format to %u\n", daifmt); - return ec_command_no_resp(component, ¶m); + p.cmd = EC_CODEC_I2S_RX_SET_DAIFMT; + p.set_daifmt_param.daifmt = daifmt; + return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, + (uint8_t *)&p, sizeof(p), NULL, 0); } -static int cros_ec_i2s_enable_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +static const struct snd_soc_dai_ops i2s_rx_dai_ops = { + .hw_params = i2s_rx_hw_params, + .set_fmt = i2s_rx_set_fmt, +}; + +static int i2s_rx_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); + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + struct ec_param_ec_codec_i2s_rx p; switch (event) { case SND_SOC_DAPM_PRE_PMU: - dev_dbg(component->dev, - "%s got SND_SOC_DAPM_PRE_PMU event\n", __func__); - return enable_i2s(component, 1); - + dev_dbg(component->dev, "enable I2S RX\n"); + p.cmd = EC_CODEC_I2S_RX_ENABLE; + break; case SND_SOC_DAPM_PRE_PMD: - dev_dbg(component->dev, - "%s got SND_SOC_DAPM_PRE_PMD event\n", __func__); - return enable_i2s(component, 0); + dev_dbg(component->dev, "disable I2S RX\n"); + p.cmd = EC_CODEC_I2S_RX_DISABLE; + break; + default: + return 0; } - return 0; + return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, + (uint8_t *)&p, sizeof(p), NULL, 0); } -/* - * The goal of this DAPM route is to turn on/off I2S using EC - * host command when capture stream is started/stopped. - */ -static const struct snd_soc_dapm_widget cros_ec_codec_dapm_widgets[] = { +static struct snd_soc_dapm_widget i2s_rx_dapm_widgets[] = { SND_SOC_DAPM_INPUT("DMIC"), - - /* - * Control EC to enable/disable I2S. - */ - SND_SOC_DAPM_SUPPLY("I2S Enable", SND_SOC_NOPM, - 0, 0, cros_ec_i2s_enable_event, + SND_SOC_DAPM_SUPPLY("I2S RX Enable", SND_SOC_NOPM, 0, 0, i2s_rx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_AIF_OUT("I2S RX", "I2S Capture", 0, SND_SOC_NOPM, 0, 0), +}; - SND_SOC_DAPM_AIF_OUT("I2STX", "I2S Capture", 0, SND_SOC_NOPM, 0, 0), +static struct snd_soc_dapm_route i2s_rx_dapm_routes[] = { + {"I2S RX", NULL, "DMIC"}, + {"I2S RX", NULL, "I2S RX Enable"}, }; -static const struct snd_soc_dapm_route cros_ec_codec_dapm_routes[] = { - { "I2STX", NULL, "DMIC" }, - { "I2STX", NULL, "I2S Enable" }, +static struct snd_soc_dai_driver i2s_rx_dai_driver = { + .name = "EC Codec I2S RX", + .capture = { + .stream_name = "I2S Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE, + }, + .ops = &i2s_rx_dai_ops, }; -/* - * Read maximum gain from device property and set it to mixer control. - */ -static int cros_ec_set_gain_range(struct device *dev) +static int i2s_rx_probe(struct snd_soc_component *component) { + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + struct device *dev = priv->dev; + int ret, val; struct soc_mixer_control *control; - struct cros_ec_codec_data *codec_data = dev_get_drvdata(dev); - int rc; - rc = device_property_read_u32(dev, "max-dmic-gain", - &codec_data->max_dmic_gain); - if (rc) - return rc; + ret = device_property_read_u32(dev, "max-dmic-gain", &val); + if (ret) { + dev_err(dev, "Failed to read 'max-dmic-gain'\n"); + return ret; + } control = (struct soc_mixer_control *) - mic_gain_control.private_value; - control->max = codec_data->max_dmic_gain; - control->platform_max = codec_data->max_dmic_gain; + dmic_controls[DMIC_CTL_GAIN].private_value; + control->max = val; + control->platform_max = val; - return 0; -} - -static int cros_ec_codec_probe(struct snd_soc_component *component) -{ - int rc; - - struct cros_ec_codec_data *codec_data = - snd_soc_component_get_drvdata(component); - - rc = cros_ec_set_gain_range(codec_data->dev); - if (rc) - return rc; - - return snd_soc_add_component_controls(component, &mic_gain_control, 1); + return snd_soc_add_component_controls(component, + &dmic_controls[DMIC_CTL_GAIN], 1); } -static const struct snd_soc_component_driver cros_ec_component_driver = { - .probe = cros_ec_codec_probe, - .dapm_widgets = cros_ec_codec_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(cros_ec_codec_dapm_widgets), - .dapm_routes = cros_ec_codec_dapm_routes, - .num_dapm_routes = ARRAY_SIZE(cros_ec_codec_dapm_routes), +static const struct snd_soc_component_driver i2s_rx_component_driver = { + .probe = i2s_rx_probe, + .dapm_widgets = i2s_rx_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(i2s_rx_dapm_widgets), + .dapm_routes = i2s_rx_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(i2s_rx_dapm_routes), }; -/* - * Platform device and platform driver fro cros-ec-codec. - */ -static int cros_ec_codec_platform_probe(struct platform_device *pd) +static int cros_ec_codec_platform_probe(struct platform_device *pdev) { - struct device *dev = &pd->dev; - struct cros_ec_device *ec_device = dev_get_drvdata(pd->dev.parent); - struct cros_ec_codec_data *codec_data; + struct device *dev = &pdev->dev; + struct cros_ec_device *ec_device = dev_get_drvdata(pdev->dev.parent); + struct cros_ec_codec_priv *priv; - codec_data = devm_kzalloc(dev, sizeof(struct cros_ec_codec_data), - GFP_KERNEL); - if (!codec_data) + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - codec_data->dev = dev; - codec_data->ec_device = ec_device; + priv->dev = dev; + priv->ec_device = ec_device; - platform_set_drvdata(pd, codec_data); + platform_set_drvdata(pdev, priv); - return devm_snd_soc_register_component(dev, &cros_ec_component_driver, - cros_ec_dai, ARRAY_SIZE(cros_ec_dai)); + return devm_snd_soc_register_component(dev, &i2s_rx_component_driver, + &i2s_rx_dai_driver, 1); } #ifdef CONFIG_OF @@ -427,7 +323,7 @@ MODULE_DEVICE_TABLE(of, cros_ec_codec_of_match); static struct platform_driver cros_ec_codec_platform_driver = { .driver = { - .name = DRV_NAME, + .name = "cros-ec-codec", .of_match_table = of_match_ptr(cros_ec_codec_of_match), }, .probe = cros_ec_codec_platform_probe, @@ -438,4 +334,4 @@ module_platform_driver(cros_ec_codec_platform_driver); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("ChromeOS EC codec driver"); MODULE_AUTHOR("Cheng-Yi Chiang "); -MODULE_ALIAS("platform:" DRV_NAME); +MODULE_ALIAS("platform:cros-ec-codec"); From patchwork Sat Oct 5 05:58:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 11175497 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A19C41709 for ; Sat, 5 Oct 2019 06:02:06 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 353F5222C4 for ; Sat, 5 Oct 2019 06:02:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="ntHDYSRC"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="VE2V9J2w" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 353F5222C4 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 3EDBB167F; Sat, 5 Oct 2019 08:01:14 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 3EDBB167F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1570255324; bh=fPhap3vXycbOM3zqMbUWKI+2R7Tmd6WHa4+XdiVbs5A=; h=Date:In-Reply-To:References:From:To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=ntHDYSRCh2t35sDSuxSc31vhtbr884LvAwPPsFbh7PC9qtx2pHN29T7x5uq7YAJcP +JJ8GRWRW2DDEHatg0UmlZteq9SHw+eMHB/Wz+ug6JTsElgLrQCNu6tpUtoN74AGK0 URxAG1PIuy0nCjY9D2IECf7y5I2k1cB9px42UNak= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id CAC23F80610; Sat, 5 Oct 2019 07:58:54 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 0792AF80633; Sat, 5 Oct 2019 07:58:53 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 Received: from mail-vs1-xe4a.google.com (mail-vs1-xe4a.google.com [IPv6:2607:f8b0:4864:20::e4a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 5EBEFF80610 for ; Sat, 5 Oct 2019 07:58:49 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 5EBEFF80610 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="VE2V9J2w" Received: by mail-vs1-xe4a.google.com with SMTP id t6so773546vsp.22 for ; Fri, 04 Oct 2019 22:58:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=9/Lb2n2Dl1IjlTZEVCLmP5Zb0tuzyhiYP+9l5REQgPI=; b=VE2V9J2wvgbzvv2uTARdYLK/hA9tuQAbpy8mC6mItEySE8rn0FhTLQ6aCFArnU9Slz RvjB5LbDmjy0reHPa4Q96MwYJWYbcCgXoBFsTEjAKJT8KZ4wg+tBg2zVGqV8gakztWir 2x5SQ1A1wEnjB17nBzsTV2cSo/I//7PYwXRwmKk/rWnBi2u1RExLDBKgoJmw7y/gUV3i jajMD5YGplxFHPqre1KnPwXowFTHvGnQ19GFG5YxqrQEma6iFxJsvwJ/H+EMwvcfq5tx dNZFikhwt1iqB6CtzkwqhpJWN9d7jQYRFXVUtym0QlSOGxF5Xwu4Bfo6w4zGKbX+cgza 43cA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=9/Lb2n2Dl1IjlTZEVCLmP5Zb0tuzyhiYP+9l5REQgPI=; b=ubhUkKSRuW8FHeWWHdEePrCb9vqozbNuOBJoj/8m8rJo5FmEtxpCoTOe1B0u03Bify c0DeNgg7z1N2sY7+xF784lM36H7OUtgdBlirpSY8gHCYbZbtTHpgDZwC+sM6oG4TrK1v dMDGoNNfQRoVHDgPGA0O1IhbnIv+W0fu2byreu3uGBwc9GAwH67b7Iq7vMK0dqAJ9tj0 OkaYXWJvt8a7Jhxd7f/8aTNaILsTBQV8dVF2hJtjG1ojWPwRyjXCH9CkLpN1Ybam/AkW Rh03O0F95YMKUT1fOHFdACk3XcsDbwJmylc3j1DsJPjuKcF1mOOvIrHwqj+2Hj8jgdZe 7XyQ== X-Gm-Message-State: APjAAAWPUrA4poXjI2w7WX9IGWVb3vYdpiTQs0qkC/GHLT5HoM1/HaeI vYz14hBlzObosBN5urZFlsTIAEYv0qOj X-Google-Smtp-Source: APXvYqwlUHt1lq0pgugYZYWjF9Twyk4Yq89yfyUzcl4JxflL76u7oWrAja8lHKj9tWYq/UAieJuswUcntX+J X-Received: by 2002:a1f:45d5:: with SMTP id s204mr1968989vka.39.1570255128081; Fri, 04 Oct 2019 22:58:48 -0700 (PDT) Date: Sat, 5 Oct 2019 13:58:01 +0800 In-Reply-To: <20191005055808.249089-1-tzungbi@google.com> Message-Id: <20191005130552.3.I93d9c65964f3c30f85a36d228e31150ff1917706@changeid> Mime-Version: 1.0 References: <20191005055808.249089-1-tzungbi@google.com> X-Mailer: git-send-email 2.23.0.581.g78d2f28ef7-goog From: Tzung-Bi Shih To: broonie@kernel.org Cc: gwendal@google.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, cychiang@google.com, drinkcat@google.com, tzungbi@google.com, robh+dt@kernel.org, enric.balletbo@collabora.com, bleung@google.com, dgreid@google.com Subject: [alsa-devel] [PATCH 03/10] ASoC: cros_ec_codec: extract DMIC EC command from I2S RX 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" Extract DMIC EC command from I2S RX. Setting and getting microphone gains is common features. Signed-off-by: Tzung-Bi Shih --- drivers/platform/chrome/cros_ec_trace.c | 1 + .../linux/platform_data/cros_ec_commands.h | 49 +++++++++++----- sound/soc/codecs/cros_ec_codec.c | 57 ++++++++++--------- 3 files changed, 68 insertions(+), 39 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_trace.c b/drivers/platform/chrome/cros_ec_trace.c index 901850004b2b..e73bb6a8b00e 100644 --- a/drivers/platform/chrome/cros_ec_trace.c +++ b/drivers/platform/chrome/cros_ec_trace.c @@ -98,6 +98,7 @@ TRACE_SYMBOL(EC_CMD_SB_READ_BLOCK), \ TRACE_SYMBOL(EC_CMD_SB_WRITE_BLOCK), \ TRACE_SYMBOL(EC_CMD_BATTERY_VENDOR_PARAM), \ + TRACE_SYMBOL(EC_CMD_EC_CODEC_DMIC), \ TRACE_SYMBOL(EC_CMD_EC_CODEC_I2S_RX), \ TRACE_SYMBOL(EC_CMD_REBOOT_EC), \ TRACE_SYMBOL(EC_CMD_GET_PANIC_INFO), \ diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 261ac83bd007..58e460c015ef 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -4466,18 +4466,48 @@ enum mkbp_cec_event { /*****************************************************************************/ +/* Commands for DMIC on audio codec. */ +#define EC_CMD_EC_CODEC_DMIC 0x00BC + +enum ec_codec_dmic_subcmd { + EC_CODEC_DMIC_SET_GAIN = 0x0, + EC_CODEC_DMIC_GET_GAIN = 0x1, + EC_CODEC_DMIC_SUBCMD_COUNT, +}; + +struct __ec_align1 ec_param_ec_codec_dmic_set_gain { + uint8_t left; + uint8_t right; + uint8_t reserved[2]; +}; + +struct __ec_align4 ec_param_ec_codec_dmic { + uint8_t cmd; /* enum ec_codec_dmic_subcmd */ + uint8_t reserved[3]; + + union { + struct ec_param_ec_codec_dmic_set_gain + set_gain_param; + }; +}; + +struct __ec_align1 ec_response_ec_codec_dmic_get_gain { + uint8_t left; + uint8_t right; +}; + +/*****************************************************************************/ + /* Commands for I2S RX on audio codec. */ -#define EC_CMD_EC_CODEC_I2S_RX 0x00BC +#define EC_CMD_EC_CODEC_I2S_RX 0x00BD enum ec_codec_i2s_rx_subcmd { EC_CODEC_I2S_RX_ENABLE = 0x0, EC_CODEC_I2S_RX_DISABLE = 0x1, - EC_CODEC_I2S_RX_SET_GAIN = 0x2, - EC_CODEC_I2S_RX_GET_GAIN = 0x3, - EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH = 0x4, - EC_CODEC_I2S_RX_SET_DAIFMT = 0x5, - EC_CODEC_I2S_RX_SET_BCLK = 0x6, + EC_CODEC_I2S_RX_SET_SAMPLE_DEPTH = 0x2, + EC_CODEC_I2S_RX_SET_DAIFMT = 0x3, + EC_CODEC_I2S_RX_SET_BCLK = 0x4, EC_CODEC_I2S_RX_SUBCMD_COUNT, }; @@ -4521,8 +4551,6 @@ struct __ec_align4 ec_param_ec_codec_i2s_rx { union { struct ec_param_ec_codec_i2s_rx_set_sample_depth set_sample_depth_param; - struct ec_param_ec_codec_i2s_rx_set_gain - set_gain_param; struct ec_param_ec_codec_i2s_rx_set_daifmt set_daifmt_param; struct ec_param_ec_codec_i2s_rx_set_bclk @@ -4530,11 +4558,6 @@ struct __ec_align4 ec_param_ec_codec_i2s_rx { }; }; -struct __ec_align1 ec_response_ec_codec_i2s_rx_get_gain { - uint8_t left; - uint8_t right; -}; - /*****************************************************************************/ /* System commands */ diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 179fa77291cd..c19c7fe42e2e 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -64,12 +64,12 @@ static int dmic_get_gain(struct snd_kcontrol *kcontrol, snd_soc_kcontrol_component(kcontrol); struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(component); - struct ec_param_ec_codec_i2s_rx p; - struct ec_response_ec_codec_i2s_rx_get_gain r; + struct ec_param_ec_codec_dmic p; + struct ec_response_ec_codec_dmic_get_gain r; int ret; - p.cmd = EC_CODEC_I2S_RX_GET_GAIN; - ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, + p.cmd = EC_CODEC_DMIC_GET_GAIN; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC, (uint8_t *)&p, sizeof(p), (uint8_t *)&r, sizeof(r)); if (ret < 0) @@ -93,17 +93,17 @@ static int dmic_put_gain(struct snd_kcontrol *kcontrol, int max_dmic_gain = control->max; int left = ucontrol->value.integer.value[0]; int right = ucontrol->value.integer.value[1]; - struct ec_param_ec_codec_i2s_rx p; + struct ec_param_ec_codec_dmic p; if (left > max_dmic_gain || right > max_dmic_gain) return -EINVAL; dev_dbg(component->dev, "set mic gain to %u, %u\n", left, right); - p.cmd = EC_CODEC_I2S_RX_SET_GAIN; + p.cmd = EC_CODEC_DMIC_SET_GAIN; p.set_gain_param.left = left; p.set_gain_param.right = right; - return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX, + return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC, (uint8_t *)&p, sizeof(p), NULL, 0); } @@ -120,6 +120,29 @@ static struct snd_kcontrol_new dmic_controls[] = { dmic_gain_tlv), }; +static int dmic_probe(struct snd_soc_component *component) +{ + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + struct device *dev = priv->dev; + int ret, val; + struct soc_mixer_control *control; + + ret = device_property_read_u32(dev, "max-dmic-gain", &val); + if (ret) { + dev_err(dev, "Failed to read 'max-dmic-gain'\n"); + return ret; + } + + control = (struct soc_mixer_control *) + dmic_controls[DMIC_CTL_GAIN].private_value; + control->max = val; + control->platform_max = val; + + return snd_soc_add_component_controls(component, + &dmic_controls[DMIC_CTL_GAIN], 1); +} + static int i2s_rx_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -265,25 +288,7 @@ static struct snd_soc_dai_driver i2s_rx_dai_driver = { static int i2s_rx_probe(struct snd_soc_component *component) { - struct cros_ec_codec_priv *priv = - snd_soc_component_get_drvdata(component); - struct device *dev = priv->dev; - int ret, val; - struct soc_mixer_control *control; - - ret = device_property_read_u32(dev, "max-dmic-gain", &val); - if (ret) { - dev_err(dev, "Failed to read 'max-dmic-gain'\n"); - return ret; - } - - control = (struct soc_mixer_control *) - dmic_controls[DMIC_CTL_GAIN].private_value; - control->max = val; - control->platform_max = val; - - return snd_soc_add_component_controls(component, - &dmic_controls[DMIC_CTL_GAIN], 1); + return dmic_probe(component); } static const struct snd_soc_component_driver i2s_rx_component_driver = { From patchwork Sat Oct 5 05:58:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 11175499 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 45F9F112B for ; Sat, 5 Oct 2019 06:02:34 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id CA1DC222C0 for ; Sat, 5 Oct 2019 06:02:33 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="Ehybddtb"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="gQcVUJ+X" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CA1DC222C0 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 EF3CC1664; Sat, 5 Oct 2019 08:01:41 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz EF3CC1664 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1570255352; bh=fqTy5MERAc/zubfe/oe51WGUO8MQb6O8zYfyfwZMrY0=; h=Date:In-Reply-To:References:From:To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=Ehybddtbhv/Nu6hWO7H2N16zjYXUNyOZh2qcNkiqDosZW3lH38zJpYRextR010miH 5WxTn4iWRARUz2RH097dX51yszKJ/MSpNVcUYuFH5NUKuMepBoU+lUEmgutdABGYu6 IsxvxY18QV6k+9yU58jaxsM2/GY6bo8pW+stdyQs= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id D4421F80636; Sat, 5 Oct 2019 07:58:58 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id A8D9FF80638; Sat, 5 Oct 2019 07:58:57 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 Received: from mail-qk1-x74a.google.com (mail-qk1-x74a.google.com [IPv6:2607:f8b0:4864:20::74a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B7155F80636 for ; Sat, 5 Oct 2019 07:58:54 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz B7155F80636 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="gQcVUJ+X" Received: by mail-qk1-x74a.google.com with SMTP id s28so8794840qkm.5 for ; Fri, 04 Oct 2019 22:58:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=NeC00R2HDPjugyY089WdATWGGggY9LDPrJpjGM7g9N0=; b=gQcVUJ+XpqurKBASnZl+Mwj5bZMVoRMdX5B6KjbbhnrQJscx/JqIIoB045wqSc36BU 5jg9Pr8zuIvWPWim7wW1zai7arWV8cJ8241rjAOiokot5W+TY1BV02dnQIrGuf0GTkdP gBQ3mkXQw5BJojsYPJ2DawQsUehAJFqBTpF2K8ldQSZsdpWLDLGsSnZpaSXL5J4X1Pu4 Eh9f+PgX2EnJpKzwXCpyBqu7VbuQ+0oyhdUgxU6wtGT3jMj4ximqEQO+MYgKZgLwHr1f DmsKfXdZlcccVfHN+Pbyax+3wwWBBHK2g4kJLNWIN21Elr21/esoHgWvMT9nfPMbhwN5 /J2A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=NeC00R2HDPjugyY089WdATWGGggY9LDPrJpjGM7g9N0=; b=fP+HC61F5JuJdevtGMbkVs0GV2KCtJyQFXpHMvRhUTqwk165PpQPUjxUMzjpCf3/HV oonVtyCLuEAKjF5TLwrz4B3PjmuESfSMX2eHZDnkhAyVy/VUqWzOj6z9LGfeSbbJIuUv 0ufWO00Qn4yVHbTsCDNmKFTeJFjK7u08axU+thsBtTW2zb9SLDYnHy9wEjpIeSjBr0MN SpQiAGOikcpHWPSGPIGIZjBvMYccowJUsRQJuKCBUyfm6P9JgCeg7LjGPzI2l4tl+dLW jk8VIVZNolT2EJSahAbmX+PZEEwcyRCzA6/A+4tBsHVFbRBitnSXuqP06r5/NNhBT6bB 8iZw== X-Gm-Message-State: APjAAAWTApUhRxRZfd/ALWo+YWWrU8Qb/PvbCrRC1osKuHEyuwSrRciL xulif1iQNUpYz5wwjYossPGVmiBsnoXf X-Google-Smtp-Source: APXvYqxWeSW1A2QUEGeWYqnxp/i3scGMYhcDvxbpndqqbVhBiuL+kV3G4ctRS9IJDexwFucU9VzAUnBb1/08 X-Received: by 2002:ac8:474c:: with SMTP id k12mr20289760qtp.319.1570255132978; Fri, 04 Oct 2019 22:58:52 -0700 (PDT) Date: Sat, 5 Oct 2019 13:58:02 +0800 In-Reply-To: <20191005055808.249089-1-tzungbi@google.com> Message-Id: <20191005130552.4.Idc3c6e1cd94b70bf010249928d4a93c6c90495b7@changeid> Mime-Version: 1.0 References: <20191005055808.249089-1-tzungbi@google.com> X-Mailer: git-send-email 2.23.0.581.g78d2f28ef7-goog From: Tzung-Bi Shih To: broonie@kernel.org Cc: gwendal@google.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, cychiang@google.com, drinkcat@google.com, tzungbi@google.com, robh+dt@kernel.org, enric.balletbo@collabora.com, bleung@google.com, dgreid@google.com Subject: [alsa-devel] [PATCH 04/10] platform/chrome: cros_ec: add common commands for EC codec 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" Add the following common commands: - GET_CAPABILITIES - GET_SHM_ADDR - SET_SHM_ADDR Signed-off-by: Tzung-Bi Shih --- drivers/platform/chrome/cros_ec_trace.c | 1 + .../linux/platform_data/cros_ec_commands.h | 64 ++++++++++++++++++- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_trace.c b/drivers/platform/chrome/cros_ec_trace.c index e73bb6a8b00e..2ea0d4e0d54d 100644 --- a/drivers/platform/chrome/cros_ec_trace.c +++ b/drivers/platform/chrome/cros_ec_trace.c @@ -98,6 +98,7 @@ TRACE_SYMBOL(EC_CMD_SB_READ_BLOCK), \ TRACE_SYMBOL(EC_CMD_SB_WRITE_BLOCK), \ TRACE_SYMBOL(EC_CMD_BATTERY_VENDOR_PARAM), \ + TRACE_SYMBOL(EC_CMD_EC_CODEC), \ TRACE_SYMBOL(EC_CMD_EC_CODEC_DMIC), \ TRACE_SYMBOL(EC_CMD_EC_CODEC_I2S_RX), \ TRACE_SYMBOL(EC_CMD_REBOOT_EC), \ diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 58e460c015ef..3ca0fa9e92a7 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -4466,8 +4466,68 @@ enum mkbp_cec_event { /*****************************************************************************/ +/* Commands for audio codec. */ +#define EC_CMD_EC_CODEC 0x00BC + +enum ec_codec_subcmd { + EC_CODEC_GET_CAPABILITIES = 0x0, + EC_CODEC_GET_SHM_ADDR = 0x1, + EC_CODEC_SET_SHM_ADDR = 0x2, + EC_CODEC_SUBCMD_COUNT, +}; + +enum ec_codec_cap { + EC_CODEC_CAP_LAST = 32, +}; + +enum ec_codec_shm_id { + EC_CODEC_SHM_ID_LAST, +}; + +enum ec_codec_shm_type { + EC_CODEC_SHM_TYPE_EC_RAM = 0x0, + EC_CODEC_SHM_TYPE_SYSTEM_RAM = 0x1, +}; + +struct __ec_align1 ec_param_ec_codec_get_shm_addr { + uint8_t shm_id; + uint8_t reserved[3]; +}; + +struct __ec_align4 ec_param_ec_codec_set_shm_addr { + uint64_t phys_addr; + uint32_t len; + uint8_t shm_id; + uint8_t reserved[3]; +}; + +struct __ec_align4 ec_param_ec_codec { + uint8_t cmd; /* enum ec_codec_subcmd */ + uint8_t reserved[3]; + + union { + struct ec_param_ec_codec_get_shm_addr + get_shm_addr_param; + struct ec_param_ec_codec_set_shm_addr + set_shm_addr_param; + }; +}; + +struct __ec_align4 ec_response_ec_codec_get_capabilities { + uint32_t capabilities; +}; + +struct __ec_align4 ec_response_ec_codec_get_shm_addr { + uint64_t phys_addr; + uint32_t len; + uint8_t type; + uint8_t reserved[3]; +}; + +/*****************************************************************************/ + /* Commands for DMIC on audio codec. */ -#define EC_CMD_EC_CODEC_DMIC 0x00BC +#define EC_CMD_EC_CODEC_DMIC 0x00BD enum ec_codec_dmic_subcmd { EC_CODEC_DMIC_SET_GAIN = 0x0, @@ -4500,7 +4560,7 @@ struct __ec_align1 ec_response_ec_codec_dmic_get_gain { /* Commands for I2S RX on audio codec. */ -#define EC_CMD_EC_CODEC_I2S_RX 0x00BD +#define EC_CMD_EC_CODEC_I2S_RX 0x00BE enum ec_codec_i2s_rx_subcmd { EC_CODEC_I2S_RX_ENABLE = 0x0, From patchwork Sat Oct 5 05:58:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 11175501 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 286FC112B for ; Sat, 5 Oct 2019 06:03:06 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id B0042222C5 for ; Sat, 5 Oct 2019 06:03:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="NhSVi/ze"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="gFtgMnq8" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B0042222C5 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 E403B1696; Sat, 5 Oct 2019 08:02:13 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz E403B1696 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1570255384; bh=kichENndD22cxYVD2n/LWXM5lb7z5VmL4wprYlDu7Uw=; h=Date:In-Reply-To:References:From:To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=NhSVi/zexJDFjVb7tOmYOzVGVxzoYoYnGoo3Y9mbUfV8uMIhbovJtR5BOqJI/hyR1 /qD7pgBxt5uwyWM+Y1YB2JszpXHh2nz79CiDOFa11UCY8dQX771SSq3xOyIIzPTJx3 YqHstICBz1Go+2iBJhMBnoGX1pq7p4UH0sSDNAKs= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 44697F8063C; Sat, 5 Oct 2019 07:59:04 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 5466BF8063D; Sat, 5 Oct 2019 07:59:02 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 Received: from mail-qk1-x74a.google.com (mail-qk1-x74a.google.com [IPv6:2607:f8b0:4864:20::74a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 663BEF8063B for ; Sat, 5 Oct 2019 07:58:59 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 663BEF8063B Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="gFtgMnq8" Received: by mail-qk1-x74a.google.com with SMTP id v143so8720791qka.21 for ; Fri, 04 Oct 2019 22:58:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=HU4cbOuoYFqXlnJcy/p07LmBMaxvgrbFUK/zvntKxPw=; b=gFtgMnq80CRltdZD2CtDjfFW9fMAbPsJ6Z6QbQC2WlafGF+ynGDGhWpB5ni5F1N+/n 55UQcqwE1AUa1ssuqGP1HE6MaaCd/sAQ39iz8V5ZG2iEtS6rkTWVTTqB1eYzb/gbHroj 6QMGpczoTv+fgvnvGPTT1E41AdH1FKliYhX4JV2o+lSq/B4HNc9quZLrKvZGTxd0wmlU qQQKESBNoAxwzF/fmhfj2cbKTNek0hyP4L2QLiAdOxKZMSLxWeOu8Nix5Q5S9qe49B9U ZdUEtXi8r4bRVWRp/m3BW+eI5LELMKl7Myl8zPXN/xO+++djQcq7b0tv3uSi+MInBr2Y kO6Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=HU4cbOuoYFqXlnJcy/p07LmBMaxvgrbFUK/zvntKxPw=; b=fj5znQ7shxeuJ21vsXLS5uoSlLwgY/48P+bXWSApKjWG2P3HgzsF5/euc3OE53KNUX +VnIfTFRSwxfJS2zj+hGZ0Hqv6MvsvvhoBvJJftydNfGTnQO8peWDBZcU5G3roxu0w+h ObhTir4rTK4sv3gQTrtjFm7aBbF/VQD1JCuqe47cMRiuyqUI+A1JGGigTii/w+irpUZv jJ9gzyQCLAlG2daUrK74LANEA9+Z9BdpDKmpB/onoCKflHU7teKglx3yUc/ptdGdg8gp WimNNVwvLUwmcJfSLJC3jX1HDaJihiZnp6f1br9qgGWoKgiWe7Rdb/jydN7tVe40yg47 uDew== X-Gm-Message-State: APjAAAX9vXG1B+JCeqFcD6rwhadOBbIN7nK8uuujnc48A3qF+mmygS6h v4Rsrl5b3dWAwlSkKZJuyb2V9wh9fT2B X-Google-Smtp-Source: APXvYqznoY2dXLLJ5jKS927F0PwtjR49ho8ZSS218g4wjclzdI0dpLKMD+GFs6AheYXzq4t30F31HUuOQbKY X-Received: by 2002:a0c:f68f:: with SMTP id p15mr17620024qvn.31.1570255137813; Fri, 04 Oct 2019 22:58:57 -0700 (PDT) Date: Sat, 5 Oct 2019 13:58:03 +0800 In-Reply-To: <20191005055808.249089-1-tzungbi@google.com> Message-Id: <20191005130552.5.Id4657c864d544634f2b5c1c9b34fa8232ecba44d@changeid> Mime-Version: 1.0 References: <20191005055808.249089-1-tzungbi@google.com> X-Mailer: git-send-email 2.23.0.581.g78d2f28ef7-goog From: Tzung-Bi Shih To: broonie@kernel.org Cc: gwendal@google.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, cychiang@google.com, drinkcat@google.com, tzungbi@google.com, robh+dt@kernel.org, enric.balletbo@collabora.com, bleung@google.com, dgreid@google.com Subject: [alsa-devel] [PATCH 05/10] ASoC: cros_ec_codec: read max DMIC gain from EC codec 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" Read max DMIC gain from EC codec instead of DTS. Also removes the dt-binding of max-dmic-gain. Signed-off-by: Tzung-Bi Shih --- .../bindings/sound/google,cros-ec-codec.txt | 4 +- .../linux/platform_data/cros_ec_commands.h | 43 +++++++++++---- sound/soc/codecs/cros_ec_codec.c | 53 ++++++++++++++----- 3 files changed, 73 insertions(+), 27 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt index 1084f7f22eea..0ce9fafc78e2 100644 --- a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt +++ b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt @@ -1,4 +1,4 @@ -* Audio codec controlled by ChromeOS EC +Audio codec controlled by ChromeOS EC Google's ChromeOS EC codec is a digital mic codec provided by the Embedded Controller (EC) and is controlled via a host-command interface. @@ -9,7 +9,6 @@ Documentation/devicetree/bindings/mfd/cros-ec.txt). Required properties: - compatible: Must contain "google,cros-ec-codec" - #sound-dai-cells: Should be 1. The cell specifies number of DAIs. -- max-dmic-gain: A number for maximum gain in dB on digital microphone. Example: @@ -21,6 +20,5 @@ cros-ec@0 { cros_ec_codec: ec-codec { compatible = "google,cros-ec-codec"; #sound-dai-cells = <1>; - max-dmic-gain = <43>; }; }; diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 3ca0fa9e92a7..21db0d4d4025 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -4530,30 +4530,53 @@ struct __ec_align4 ec_response_ec_codec_get_shm_addr { #define EC_CMD_EC_CODEC_DMIC 0x00BD enum ec_codec_dmic_subcmd { - EC_CODEC_DMIC_SET_GAIN = 0x0, - EC_CODEC_DMIC_GET_GAIN = 0x1, + EC_CODEC_DMIC_GET_MAX_GAIN = 0x0, + EC_CODEC_DMIC_SET_GAIN_IDX = 0x1, + EC_CODEC_DMIC_GET_GAIN_IDX = 0x2, EC_CODEC_DMIC_SUBCMD_COUNT, }; -struct __ec_align1 ec_param_ec_codec_dmic_set_gain { - uint8_t left; - uint8_t right; +enum ec_codec_dmic_channel { + EC_CODEC_DMIC_CHANNEL_0 = 0x0, + EC_CODEC_DMIC_CHANNEL_1 = 0x1, + EC_CODEC_DMIC_CHANNEL_2 = 0x2, + EC_CODEC_DMIC_CHANNEL_3 = 0x3, + EC_CODEC_DMIC_CHANNEL_4 = 0x4, + EC_CODEC_DMIC_CHANNEL_5 = 0x5, + EC_CODEC_DMIC_CHANNEL_6 = 0x6, + EC_CODEC_DMIC_CHANNEL_7 = 0x7, + EC_CODEC_DMIC_CHANNEL_COUNT, +}; + +struct __ec_align1 ec_param_ec_codec_dmic_set_gain_idx { + uint8_t channel; /* enum ec_codec_dmic_channel */ + uint8_t gain; uint8_t reserved[2]; }; +struct __ec_align1 ec_param_ec_codec_dmic_get_gain_idx { + uint8_t channel; /* enum ec_codec_dmic_channel */ + uint8_t reserved[3]; +}; + struct __ec_align4 ec_param_ec_codec_dmic { uint8_t cmd; /* enum ec_codec_dmic_subcmd */ uint8_t reserved[3]; union { - struct ec_param_ec_codec_dmic_set_gain - set_gain_param; + struct ec_param_ec_codec_dmic_set_gain_idx + set_gain_idx_param; + struct ec_param_ec_codec_dmic_get_gain_idx + get_gain_idx_param; }; }; -struct __ec_align1 ec_response_ec_codec_dmic_get_gain { - uint8_t left; - uint8_t right; +struct __ec_align1 ec_response_ec_codec_dmic_get_max_gain { + uint8_t max_gain; +}; + +struct __ec_align1 ec_response_ec_codec_dmic_get_gain_idx { + uint8_t gain; }; /*****************************************************************************/ diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index c19c7fe42e2e..3d4f9e82d6e9 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -65,18 +65,26 @@ static int dmic_get_gain(struct snd_kcontrol *kcontrol, struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(component); struct ec_param_ec_codec_dmic p; - struct ec_response_ec_codec_dmic_get_gain r; + struct ec_response_ec_codec_dmic_get_gain_idx r; int ret; - p.cmd = EC_CODEC_DMIC_GET_GAIN; + p.cmd = EC_CODEC_DMIC_GET_GAIN_IDX; + p.get_gain_idx_param.channel = EC_CODEC_DMIC_CHANNEL_0; ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC, (uint8_t *)&p, sizeof(p), (uint8_t *)&r, sizeof(r)); if (ret < 0) return ret; + ucontrol->value.integer.value[0] = r.gain; - ucontrol->value.integer.value[0] = r.left; - ucontrol->value.integer.value[1] = r.right; + p.cmd = EC_CODEC_DMIC_GET_GAIN_IDX; + p.get_gain_idx_param.channel = EC_CODEC_DMIC_CHANNEL_1; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC, + (uint8_t *)&p, sizeof(p), + (uint8_t *)&r, sizeof(r)); + if (ret < 0) + return ret; + ucontrol->value.integer.value[1] = r.gain; return 0; } @@ -94,15 +102,24 @@ static int dmic_put_gain(struct snd_kcontrol *kcontrol, int left = ucontrol->value.integer.value[0]; int right = ucontrol->value.integer.value[1]; struct ec_param_ec_codec_dmic p; + int ret; if (left > max_dmic_gain || right > max_dmic_gain) return -EINVAL; dev_dbg(component->dev, "set mic gain to %u, %u\n", left, right); - p.cmd = EC_CODEC_DMIC_SET_GAIN; - p.set_gain_param.left = left; - p.set_gain_param.right = right; + p.cmd = EC_CODEC_DMIC_SET_GAIN_IDX; + p.set_gain_idx_param.channel = EC_CODEC_DMIC_CHANNEL_0; + p.set_gain_idx_param.gain = left; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC, + (uint8_t *)&p, sizeof(p), NULL, 0); + if (ret < 0) + return ret; + + p.cmd = EC_CODEC_DMIC_SET_GAIN_IDX; + p.set_gain_idx_param.channel = EC_CODEC_DMIC_CHANNEL_1; + p.set_gain_idx_param.gain = right; return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC, (uint8_t *)&p, sizeof(p), NULL, 0); } @@ -125,19 +142,27 @@ static int dmic_probe(struct snd_soc_component *component) struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(component); struct device *dev = priv->dev; - int ret, val; struct soc_mixer_control *control; + struct ec_param_ec_codec_dmic p; + struct ec_response_ec_codec_dmic_get_max_gain r; + int ret; - ret = device_property_read_u32(dev, "max-dmic-gain", &val); - if (ret) { - dev_err(dev, "Failed to read 'max-dmic-gain'\n"); - return ret; + p.cmd = EC_CODEC_DMIC_GET_MAX_GAIN; + + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC, + (uint8_t *)&p, sizeof(p), + (uint8_t *)&r, sizeof(r)); + if (ret < 0) { + dev_warn(dev, "get_max_gain() unsupported\n"); + return 0; } + dev_dbg(dev, "max gain = %d\n", r.max_gain); + control = (struct soc_mixer_control *) dmic_controls[DMIC_CTL_GAIN].private_value; - control->max = val; - control->platform_max = val; + control->max = r.max_gain; + control->platform_max = r.max_gain; return snd_soc_add_component_controls(component, &dmic_controls[DMIC_CTL_GAIN], 1); From patchwork Sat Oct 5 05:58:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 11175503 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E4B85112B for ; Sat, 5 Oct 2019 06:03:52 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 73DB52133F for ; Sat, 5 Oct 2019 06:03:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="guYwKd44"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="pwuDtpdQ" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 73DB52133F Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 AFFB81693; Sat, 5 Oct 2019 08:03:00 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz AFFB81693 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1570255430; bh=v0Bdj7/isEnSQYPIhkBS+NGX6VBf1u8wq4N637ca6Kw=; h=Date:In-Reply-To:References:From:To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=guYwKd44E7RQJZrFX8gFRD8rlYhmTmtPaSB+py9T+ibk3siQYcjMooaKZmF2ve+VS NFi587J/ou/jQLno2fEQYtdQXzdRzUTPs0MyPlLQEhaTlv+Pb8GU2jAdTSZLVR45C2 JkTisAAF9ey+DX6dzzVIB59hGoc6LEY3QJrLsnug= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id AAF46F8063A; Sat, 5 Oct 2019 07:59:07 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 9B49FF80659; Sat, 5 Oct 2019 07:59:06 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 Received: from mail-qk1-x749.google.com (mail-qk1-x749.google.com [IPv6:2607:f8b0:4864:20::749]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 14941F8063A for ; Sat, 5 Oct 2019 07:59:03 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 14941F8063A Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="pwuDtpdQ" Received: by mail-qk1-x749.google.com with SMTP id y189so8788916qkb.14 for ; Fri, 04 Oct 2019 22:59:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=kmoQ5EfiuLPugExVdasoEEQ+xSgNc8VlrAlw91YpZWU=; b=pwuDtpdQkUw37uPBkawWEH5UEbyKj/92rsZLEWnMWLxMfJsAhZ9w0XOUMla9UL+ict zwTJ951sb4e9imqEeEaRAqKqbyUKdpUPjfonRAMwhU6n29cI0HDW69Uvn5a03TSrTvLt C0879QsGt9rxTp4jVoYBu64vGTnrB/BrwXDw3x9E1W/6mZkccSQi+fJAKqPWzEUkY8/7 iukTLAEUGlZQm/jIBZREsZ0YcZmrPvfs5qjfFoXn8PeK168mCKeBATVj+Jud/JL0gM1y yYq66LTRfNBzUT4sWo4jigQOdsPTM1xBqZ7SqxJUir6hmFrdERt+j+8hqfYWpmJZc86s Ochg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=kmoQ5EfiuLPugExVdasoEEQ+xSgNc8VlrAlw91YpZWU=; b=BfmticvS1+Tsb/5wfrvBW7IiZLjGqDlysyFyKiA3Fl03F0OX5K3aZG0sVb3PA8kP1l sPoCXkO8y/iN13KUkjxYUZE9voBbw1It6Oav6Sp6Lpimy8sOPKiQpXfrE3u9kNnpq/zm QdBsjI1CGvh8FRowXGWmu/ENyB75ZVfYhnyiskzWfwJKPhgv3aNfw8347loAyVNBd4bR /VEk8+gEVKT6Ick/HeGJWrCeE8RpHOkocNizIa1UAkjf1T9ZkZbfrdfds2tnhUoU7Idj P1EBXfevGStyx4Muie4EOYeNOAIKHpbrEzQvROMYmnk8TUs0XTaSTx+nkM/3RqL8Ye0X DucQ== X-Gm-Message-State: APjAAAUq/VDH5UmihaQ8e49HH3G5qpMh8IbFlR6UaQUgX4lsPMYWON+Q 6/3XDgeXxJNkaoeBT4fHT2EX1o6+KrX8 X-Google-Smtp-Source: APXvYqwJeuGRCNWl0Jv58EQx56XvBq9ESjXplaVSwszfGBRajq9VaPPIgdc6Sw1gP56WuO7IHjsEaEu7Mh72 X-Received: by 2002:a05:6214:1189:: with SMTP id t9mr17900493qvv.89.1570255142531; Fri, 04 Oct 2019 22:59:02 -0700 (PDT) Date: Sat, 5 Oct 2019 13:58:04 +0800 In-Reply-To: <20191005055808.249089-1-tzungbi@google.com> Message-Id: <20191005130552.6.I0df85fe54162426e31f60a589d9b461c65df2faa@changeid> Mime-Version: 1.0 References: <20191005055808.249089-1-tzungbi@google.com> X-Mailer: git-send-email 2.23.0.581.g78d2f28ef7-goog From: Tzung-Bi Shih To: broonie@kernel.org Cc: gwendal@google.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, cychiang@google.com, drinkcat@google.com, tzungbi@google.com, robh+dt@kernel.org, enric.balletbo@collabora.com, bleung@google.com, dgreid@google.com Subject: [alsa-devel] [PATCH 06/10] ASoC: dt-bindings: cros_ec_codec: add SHM bindings 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" - Add "ec-shm" for binding to shared memory exposed by EC. - Add "memory-region" for binding to memory region shared by AP. Signed-off-by: Tzung-Bi Shih --- .../bindings/sound/google,cros-ec-codec.txt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt index 0ce9fafc78e2..cb46bc082b4b 100644 --- a/Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt +++ b/Documentation/devicetree/bindings/sound/google,cros-ec-codec.txt @@ -10,8 +10,26 @@ Required properties: - compatible: Must contain "google,cros-ec-codec" - #sound-dai-cells: Should be 1. The cell specifies number of DAIs. +Optional properties: +- ec-shm: Shared memory region from EC. It contains 3 unsigned 32-bit + integer. The first 2 integers combine to become an unsigned + 64-bit address. The last one integer is length of the shared + memory. +- memory-region: Shared memory region to EC. A "shared-dma-pool". See + ../reserved-memory/reserved-memory.txt for details. + Example: +{ + ... + + reserved_mem: reserved_mem { + compatible = "shared-dma-pool"; + reg = <0 0x52800000 0 0x100000>; + no-map; + }; +} + cros-ec@0 { compatible = "google,cros-ec-spi"; @@ -20,5 +38,7 @@ cros-ec@0 { cros_ec_codec: ec-codec { compatible = "google,cros-ec-codec"; #sound-dai-cells = <1>; + ec-shm = <0x0 0x10500000 0x80000>; + memory-region = <&reserved_mem>; }; }; From patchwork Sat Oct 5 05:58:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 11175505 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9E1C4112B for ; Sat, 5 Oct 2019 06:04:47 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 30F64222C0 for ; Sat, 5 Oct 2019 06:04:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="dtyb31pU"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="vsk3Wg7m" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 30F64222C0 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 668A7167A; Sat, 5 Oct 2019 08:03:55 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz 668A7167A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1570255485; bh=JCHpl13qVcWRk0ZMtjDVev0p4XdfPtVHVNe7UkmVsBM=; h=Date:In-Reply-To:References:From:To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=dtyb31pUrjKhU59w1NqnLBttp1jSuz1kL3jS9C3mUk5K/CY59DdvA6XCm9nehyFgV 0hegwp0zz/H0A4wIhikcAD83pCc4lhLSByLmiZwkK6LgJEuGboQr56it8pLaAZAqMV ifcK5Mtb4P851xw4ryMQjyXBT2ibbIkQbuzf17tA= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id B266AF80675; Sat, 5 Oct 2019 07:59:13 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id B2F3EF80676; Sat, 5 Oct 2019 07:59:12 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id 1B81BF80671 for ; Sat, 5 Oct 2019 07:59:08 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz 1B81BF80671 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="vsk3Wg7m" Received: by mail-qt1-x84a.google.com with SMTP id o34so8940636qtf.22 for ; Fri, 04 Oct 2019 22:59:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=d1mgFuVV3hGsTpNJmcL0PoyHw4b7/AgA6VqHmRcyh9U=; b=vsk3Wg7mwpheLTEc9ZNyxUWqt+GM8HSXCqC7qaG+mi852AKB8MfpAIOyJtqyaZhRZ3 jVjUkPM4K8WAIgRkMH85rHBw20dWgLlWWTFWFpvzaEtqJka5y/3eyXN6uxip3cWS0umt hnuAg9nysAroEekBOxcGWbr8q99DfzjIAYVS8L2xXvfzlDuFssU1cdtNDJyMdLQ7tHbe tQfFKtuvM5FNQzUddIQqGRT8GJU/BdGl7gJVjCa6kV/PQ7WfVqTgTOVEvRYyN5kQ/T2C b5UUJvhhliuv/bQ0HzbZeYzys4oaXLZwXGcOzb+TOYP66Zy642vRb72SY1ARZLUlEl5z KzBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=d1mgFuVV3hGsTpNJmcL0PoyHw4b7/AgA6VqHmRcyh9U=; b=gCRPTlCm/bUIvkgBGKVLYiv9H9m885c655DnKwJa5zy31FgNEko9fIwyOfaVy7EQrL qj07bK6+L/yuNPzjnwPdSLfpc0qvLAhDf5bufjBewDfCKjkqK/B9B4w4IYKlCzluGh4d syDNrkdV3dvf12ZI2qnmtgOoKvBA4ZJcVaSK4udOwk+gn2YTP03i3Ju0Fe1lxwgJfiId ORqGas2cenokli4f1fUEKQtO7BsViifZTcTCu9AzQdRnoKN4/x0ORenxFm2IveV07nex EbZgUU8QYRFUqznnuLpryzMJQzPTVnHQqasRvfmj5AdJypQA2WQbu3iEIkm0epAOo1+J 7BVQ== X-Gm-Message-State: APjAAAXZEqwSFWTpiffzj3nuMN6CCEWSxuKzK4cEJ6Jg8WUaP+RWiSxo R5PzozTBt76KjSCGNhsbZ/hoJmPJt2p7 X-Google-Smtp-Source: APXvYqwDDIRdvQSFi85ukvbH0VPlF1GXnCYyAdNTa4WBPUhX7Tp3oJh7ldFZbWhELowOBAXpxn4nuUl0iOts X-Received: by 2002:ad4:4cc6:: with SMTP id i6mr17934881qvz.166.1570255147430; Fri, 04 Oct 2019 22:59:07 -0700 (PDT) Date: Sat, 5 Oct 2019 13:58:05 +0800 In-Reply-To: <20191005055808.249089-1-tzungbi@google.com> Message-Id: <20191005130552.7.I5388b69a7a9c551078fed216a77440cee6dedf49@changeid> Mime-Version: 1.0 References: <20191005055808.249089-1-tzungbi@google.com> X-Mailer: git-send-email 2.23.0.581.g78d2f28ef7-goog From: Tzung-Bi Shih To: broonie@kernel.org Cc: gwendal@google.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, cychiang@google.com, drinkcat@google.com, tzungbi@google.com, robh+dt@kernel.org, enric.balletbo@collabora.com, bleung@google.com, dgreid@google.com Subject: [alsa-devel] [PATCH 07/10] ASoC: cros_ec_codec: support WoV 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" 1. Get EC codec's capabilities. 2. Get and set SHM address if any. 3. Transmit language model to EC codec if needed. 4. Start to read audio data from EC codec if receives host event. Signed-off-by: Tzung-Bi Shih --- drivers/platform/chrome/cros_ec_trace.c | 1 + .../linux/platform_data/cros_ec_commands.h | 69 ++ sound/soc/codecs/cros_ec_codec.c | 695 +++++++++++++++++- 3 files changed, 763 insertions(+), 2 deletions(-) diff --git a/drivers/platform/chrome/cros_ec_trace.c b/drivers/platform/chrome/cros_ec_trace.c index 2ea0d4e0d54d..5af1d66d9eca 100644 --- a/drivers/platform/chrome/cros_ec_trace.c +++ b/drivers/platform/chrome/cros_ec_trace.c @@ -101,6 +101,7 @@ TRACE_SYMBOL(EC_CMD_EC_CODEC), \ TRACE_SYMBOL(EC_CMD_EC_CODEC_DMIC), \ TRACE_SYMBOL(EC_CMD_EC_CODEC_I2S_RX), \ + TRACE_SYMBOL(EC_CMD_EC_CODEC_WOV), \ TRACE_SYMBOL(EC_CMD_REBOOT_EC), \ TRACE_SYMBOL(EC_CMD_GET_PANIC_INFO), \ TRACE_SYMBOL(EC_CMD_ACPI_READ), \ diff --git a/include/linux/platform_data/cros_ec_commands.h b/include/linux/platform_data/cros_ec_commands.h index 21db0d4d4025..69210881ebac 100644 --- a/include/linux/platform_data/cros_ec_commands.h +++ b/include/linux/platform_data/cros_ec_commands.h @@ -556,6 +556,9 @@ enum host_event_code { /* Keyboard recovery combo with hardware reinitialization */ EC_HOST_EVENT_KEYBOARD_RECOVERY_HW_REINIT = 30, + /* WoV */ + EC_HOST_EVENT_WOV = 31, + /* * The high bit of the event mask is not used as a host event code. If * it reads back as set, then the entire event mask should be @@ -4477,10 +4480,14 @@ enum ec_codec_subcmd { }; enum ec_codec_cap { + EC_CODEC_CAP_WOV_AUDIO_SHM = 0, + EC_CODEC_CAP_WOV_LANG_SHM = 1, EC_CODEC_CAP_LAST = 32, }; enum ec_codec_shm_id { + EC_CODEC_SHM_ID_WOV_AUDIO = 0x0, + EC_CODEC_SHM_ID_WOV_LANG = 0x1, EC_CODEC_SHM_ID_LAST, }; @@ -4641,6 +4648,68 @@ struct __ec_align4 ec_param_ec_codec_i2s_rx { }; }; +/*****************************************************************************/ +/* Commands for WoV on audio codec. */ + +#define EC_CMD_EC_CODEC_WOV 0x00BF + +enum ec_codec_wov_subcmd { + EC_CODEC_WOV_SET_LANG = 0x0, + EC_CODEC_WOV_SET_LANG_SHM = 0x1, + EC_CODEC_WOV_GET_LANG = 0x2, + EC_CODEC_WOV_ENABLE = 0x3, + EC_CODEC_WOV_DISABLE = 0x4, + EC_CODEC_WOV_READ_AUDIO = 0x5, + EC_CODEC_WOV_READ_AUDIO_SHM = 0x6, + EC_CODEC_WOV_SUBCMD_COUNT, +}; + +/* + * @hash is SHA256 of the whole language model. + * @total_len indicates the length of whole language model. + * @offset is the cursor from the beginning of the model. + * @buf is the packet buffer. + * @len denotes how many bytes in the buf. + */ +struct __ec_align4 ec_param_ec_codec_wov_set_lang { + uint8_t hash[32]; + uint32_t total_len; + uint32_t offset; + uint8_t buf[128]; + uint32_t len; +}; + +struct __ec_align4 ec_param_ec_codec_wov_set_lang_shm { + uint8_t hash[32]; + uint32_t total_len; +}; + +struct __ec_align4 ec_param_ec_codec_wov { + uint8_t cmd; /* enum ec_codec_wov_subcmd */ + uint8_t reserved[3]; + + union { + struct ec_param_ec_codec_wov_set_lang + set_lang_param; + struct ec_param_ec_codec_wov_set_lang_shm + set_lang_shm_param; + }; +}; + +struct __ec_align4 ec_response_ec_codec_wov_get_lang { + uint8_t hash[32]; +}; + +struct __ec_align4 ec_response_ec_codec_wov_read_audio { + uint8_t buf[128]; + uint32_t len; +}; + +struct __ec_align4 ec_response_ec_codec_wov_read_audio_shm { + uint32_t offset; + uint32_t len; +}; + /*****************************************************************************/ /* System commands */ diff --git a/sound/soc/codecs/cros_ec_codec.c b/sound/soc/codecs/cros_ec_codec.c index 3d4f9e82d6e9..3b51fd5a2a63 100644 --- a/sound/soc/codecs/cros_ec_codec.c +++ b/sound/soc/codecs/cros_ec_codec.c @@ -8,10 +8,15 @@ * EC for audio function. */ +#include +#include #include #include +#include +#include #include #include +#include #include #include #include @@ -23,8 +28,45 @@ struct cros_ec_codec_priv { struct device *dev; struct cros_ec_device *ec_device; + + /* common */ + uint32_t ec_capabilities; + + uint64_t ec_shm_addr; + uint32_t ec_shm_len; + + uint64_t ap_shm_phys_addr; + uint32_t ap_shm_len; + uint64_t ap_shm_addr; + uint64_t ap_shm_last_alloc; + + /* DMIC */ + atomic_t dmic_probed; + + /* WoV */ + bool wov_enabled; + uint8_t *wov_audio_shm_p; + uint32_t wov_audio_shm_len; + uint8_t wov_audio_shm_type; + uint8_t *wov_lang_shm_p; + uint32_t wov_lang_shm_len; + uint8_t wov_lang_shm_type; + + struct mutex wov_dma_lock; + uint8_t wov_buf[64000]; + uint32_t wov_rp, wov_wp; + size_t wov_dma_offset; + bool wov_burst_read; + struct snd_pcm_substream *wov_substream; + struct delayed_work wov_copy_work; + struct notifier_block wov_notifier; }; +static int ec_codec_capable(struct cros_ec_codec_priv *priv, uint8_t cap) +{ + return priv->ec_capabilities & BIT(cap); +} + static int send_ec_host_command(struct cros_ec_device *ec_dev, uint32_t cmd, uint8_t *out, size_t outsize, uint8_t *in, size_t insize) @@ -57,6 +99,42 @@ static int send_ec_host_command(struct cros_ec_device *ec_dev, uint32_t cmd, return ret; } +static int calculate_sha256(struct cros_ec_codec_priv *priv, + uint8_t *buf, uint32_t size, uint8_t *digest) +{ + struct crypto_shash *tfm; + + tfm = crypto_alloc_shash("sha256", CRYPTO_ALG_TYPE_SHASH, 0); + if (IS_ERR(tfm)) { + dev_err(priv->dev, "can't alloc shash\n"); + return PTR_ERR(tfm); + } + + { + SHASH_DESC_ON_STACK(desc, tfm); + + desc->tfm = tfm; + desc->flags = 0x0; + + crypto_shash_digest(desc, buf, size, digest); + shash_desc_zero(desc); + } + + crypto_free_shash(tfm); + +#ifdef DEBUG + { + char digest_str[65]; + + bin2hex(digest_str, digest, 32); + digest_str[64] = 0; + dev_dbg(priv->dev, "hash=%s\n", digest_str); + } +#endif + + return 0; +} + static int dmic_get_gain(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -147,6 +225,9 @@ static int dmic_probe(struct snd_soc_component *component) struct ec_response_ec_codec_dmic_get_max_gain r; int ret; + if (!atomic_add_unless(&priv->dmic_probed, 1, 1)) + return 0; + p.cmd = EC_CODEC_DMIC_GET_MAX_GAIN; ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_DMIC, @@ -324,23 +405,633 @@ static const struct snd_soc_component_driver i2s_rx_component_driver = { .num_dapm_routes = ARRAY_SIZE(i2s_rx_dapm_routes), }; +static void *wov_map_shm(struct cros_ec_codec_priv *priv, + uint8_t shm_id, uint32_t *len, uint8_t *type) +{ + struct ec_param_ec_codec p; + struct ec_response_ec_codec_get_shm_addr r; + uint32_t req, offset; + + p.cmd = EC_CODEC_GET_SHM_ADDR; + p.get_shm_addr_param.shm_id = shm_id; + if (send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC, + (uint8_t *)&p, sizeof(p), + (uint8_t *)&r, sizeof(r)) < 0) { + dev_err(priv->dev, "failed to EC_CODEC_GET_SHM_ADDR\n"); + return NULL; + } + + dev_dbg(priv->dev, "phys_addr=%#llx, len=%#x\n", r.phys_addr, r.len); + + *len = r.len; + *type = r.type; + + switch (r.type) { + case EC_CODEC_SHM_TYPE_EC_RAM: + return devm_ioremap_wc(priv->dev, + r.phys_addr + priv->ec_shm_addr, r.len); + case EC_CODEC_SHM_TYPE_SYSTEM_RAM: + if (r.phys_addr) { + dev_err(priv->dev, "unknown status\n"); + return NULL; + } + + req = round_up(r.len, PAGE_SIZE); + dev_dbg(priv->dev, "round up from %u to %u\n", r.len, req); + + if (priv->ap_shm_last_alloc + req > + priv->ap_shm_phys_addr + priv->ap_shm_len) { + dev_err(priv->dev, "insufficient space for AP SHM\n"); + return NULL; + } + + dev_dbg(priv->dev, "alloc AP SHM addr=%#llx, len=%#x\n", + priv->ap_shm_last_alloc, req); + + p.cmd = EC_CODEC_SET_SHM_ADDR; + p.set_shm_addr_param.phys_addr = priv->ap_shm_last_alloc; + p.set_shm_addr_param.len = req; + p.set_shm_addr_param.shm_id = shm_id; + if (send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC, + (uint8_t *)&p, sizeof(p), + NULL, 0) < 0) { + dev_err(priv->dev, "failed to EC_CODEC_SET_SHM_ADDR\n"); + return NULL; + } + + /* + * Note: EC codec only requests for `r.len' but we allocate + * round up PAGE_SIZE `req'. + */ + offset = priv->ap_shm_last_alloc - priv->ap_shm_phys_addr; + priv->ap_shm_last_alloc += req; + + return (void *)(priv->ap_shm_addr + offset); + default: + return NULL; + } +} + +static bool wov_queue_full(struct cros_ec_codec_priv *priv) +{ + return ((priv->wov_wp + 1) % sizeof(priv->wov_buf)) == priv->wov_rp; +} + +static size_t wov_queue_size(struct cros_ec_codec_priv *priv) +{ + if (priv->wov_wp >= priv->wov_rp) + return priv->wov_wp - priv->wov_rp; + else + return sizeof(priv->wov_buf) - priv->wov_rp + priv->wov_wp; +} + +static void wov_queue_dequeue(struct cros_ec_codec_priv *priv, size_t len) +{ + struct snd_pcm_runtime *runtime = priv->wov_substream->runtime; + size_t req; + + while (len) { + req = min(len, runtime->dma_bytes - priv->wov_dma_offset); + if (priv->wov_wp >= priv->wov_rp) + req = min(req, (size_t)priv->wov_wp - priv->wov_rp); + else + req = min(req, sizeof(priv->wov_buf) - priv->wov_rp); + + memcpy(runtime->dma_area + priv->wov_dma_offset, + priv->wov_buf + priv->wov_rp, req); + + priv->wov_dma_offset += req; + if (priv->wov_dma_offset == runtime->dma_bytes) + priv->wov_dma_offset = 0; + + priv->wov_rp += req; + if (priv->wov_rp == sizeof(priv->wov_buf)) + priv->wov_rp = 0; + + len -= req; + } + + snd_pcm_period_elapsed(priv->wov_substream); +} + +static void wov_queue_try_dequeue(struct cros_ec_codec_priv *priv) +{ + size_t period_bytes = snd_pcm_lib_period_bytes(priv->wov_substream); + + while (period_bytes && wov_queue_size(priv) >= period_bytes) { + wov_queue_dequeue(priv, period_bytes); + period_bytes = snd_pcm_lib_period_bytes(priv->wov_substream); + } +} + +static void wov_queue_enqueue(struct cros_ec_codec_priv *priv, + uint8_t *addr, size_t len, bool iomem) +{ + size_t req; + + while (len) { + if (wov_queue_full(priv)) { + wov_queue_try_dequeue(priv); + + if (wov_queue_full(priv)) { + dev_err(priv->dev, "overrun detected\n"); + return; + } + } + + if (priv->wov_wp >= priv->wov_rp) + req = sizeof(priv->wov_buf) - priv->wov_wp; + else + /* Note: waste 1-byte to differentiate full and empty */ + req = priv->wov_rp - priv->wov_wp - 1; + req = min(req, len); + + if (iomem) + memcpy_fromio(priv->wov_buf + priv->wov_wp, addr, req); + else + memcpy(priv->wov_buf + priv->wov_wp, addr, req); + + priv->wov_wp += req; + if (priv->wov_wp == sizeof(priv->wov_buf)) + priv->wov_wp = 0; + + addr += req; + len -= req; + } + + wov_queue_try_dequeue(priv); +} + +static int wov_read_audio_shm(struct cros_ec_codec_priv *priv) +{ + struct ec_param_ec_codec_wov p; + struct ec_response_ec_codec_wov_read_audio_shm r; + int ret; + + p.cmd = EC_CODEC_WOV_READ_AUDIO_SHM; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV, + (uint8_t *)&p, sizeof(p), + (uint8_t *)&r, sizeof(r)); + if (ret) { + dev_err(priv->dev, "failed to EC_CODEC_WOV_READ_AUDIO_SHM\n"); + return ret; + } + + if (!r.len) + dev_dbg(priv->dev, "no data, sleep\n"); + else + wov_queue_enqueue(priv, priv->wov_audio_shm_p + r.offset, r.len, + priv->wov_audio_shm_type == EC_CODEC_SHM_TYPE_EC_RAM); + return -EAGAIN; +} + +static int wov_read_audio(struct cros_ec_codec_priv *priv) +{ + struct ec_param_ec_codec_wov p; + struct ec_response_ec_codec_wov_read_audio r; + int remain = priv->wov_burst_read ? 16000 : 320; + int ret; + + while (remain >= 0) { + p.cmd = EC_CODEC_WOV_READ_AUDIO; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV, + (uint8_t *)&p, sizeof(p), + (uint8_t *)&r, sizeof(r)); + if (ret) { + dev_err(priv->dev, + "failed to EC_CODEC_WOV_READ_AUDIO\n"); + return ret; + } + + if (!r.len) { + dev_dbg(priv->dev, "no data, sleep\n"); + priv->wov_burst_read = false; + break; + } + + wov_queue_enqueue(priv, r.buf, r.len, false); + remain -= r.len; + } + + return -EAGAIN; +} + +static void wov_copy_work(struct work_struct *w) +{ + struct cros_ec_codec_priv *priv = + container_of(w, struct cros_ec_codec_priv, wov_copy_work.work); + int ret; + + mutex_lock(&priv->wov_dma_lock); + if (!priv->wov_substream) { + dev_warn(priv->dev, "no pcm substream\n"); + goto leave; + } + + if (ec_codec_capable(priv, EC_CODEC_CAP_WOV_AUDIO_SHM)) + ret = wov_read_audio_shm(priv); + else + ret = wov_read_audio(priv); + + if (ret == -EAGAIN) + schedule_delayed_work(&priv->wov_copy_work, + msecs_to_jiffies(10)); + else if (ret) + dev_err(priv->dev, "failed to read audio data\n"); +leave: + mutex_unlock(&priv->wov_dma_lock); +} + +static int wov_enable_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol); + struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(c); + + ucontrol->value.integer.value[0] = priv->wov_enabled; + return 0; +} + +static int wov_enable_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol); + struct cros_ec_codec_priv *priv = snd_soc_component_get_drvdata(c); + int enabled = ucontrol->value.integer.value[0]; + struct ec_param_ec_codec_wov p; + int ret; + + if (priv->wov_enabled != enabled) { + if (enabled) + p.cmd = EC_CODEC_WOV_ENABLE; + else + p.cmd = EC_CODEC_WOV_DISABLE; + + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV, + (uint8_t *)&p, sizeof(p), NULL, 0); + if (ret) { + dev_err(priv->dev, "failed to %s wov\n", + enabled ? "enable" : "disable"); + return ret; + } + + priv->wov_enabled = enabled; + } + + return 0; +} + +static int wov_set_lang_shm(struct cros_ec_codec_priv *priv, + uint8_t *buf, size_t size, uint8_t *digest) +{ + struct ec_param_ec_codec_wov p; + struct ec_param_ec_codec_wov_set_lang_shm *pp = &p.set_lang_shm_param; + int ret; + + if (size > priv->wov_lang_shm_len) { + dev_err(priv->dev, "no enough SHM size: %d\n", + priv->wov_lang_shm_len); + return -EIO; + } + + switch (priv->wov_lang_shm_type) { + case EC_CODEC_SHM_TYPE_EC_RAM: + memcpy_toio(priv->wov_lang_shm_p, buf, size); + memset_io(priv->wov_lang_shm_p + size, 0, + priv->wov_lang_shm_len - size); + break; + case EC_CODEC_SHM_TYPE_SYSTEM_RAM: + memcpy(priv->wov_lang_shm_p, buf, size); + memset(priv->wov_lang_shm_p + size, 0, + priv->wov_lang_shm_len - size); + + /* make sure write to memory before calling host command */ + wmb(); + break; + } + + p.cmd = EC_CODEC_WOV_SET_LANG_SHM; + memcpy(pp->hash, digest, SHA256_DIGEST_SIZE); + pp->total_len = size; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV, + (uint8_t *)&p, sizeof(p), NULL, 0); + if (ret) { + dev_err(priv->dev, "failed to EC_CODEC_WOV_SET_LANG_SHM\n"); + return ret; + } + + return 0; +} + +static int wov_set_lang(struct cros_ec_codec_priv *priv, + uint8_t *buf, size_t size, uint8_t *digest) +{ + struct ec_param_ec_codec_wov p; + struct ec_param_ec_codec_wov_set_lang *pp = &p.set_lang_param; + size_t i, req; + int ret; + + for (i = 0; i < size; i += req) { + req = min(size - i, ARRAY_SIZE(pp->buf)); + + p.cmd = EC_CODEC_WOV_SET_LANG; + memcpy(pp->hash, digest, SHA256_DIGEST_SIZE); + pp->total_len = size; + pp->offset = i; + memcpy(pp->buf, buf + i, req); + pp->len = req; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV, + (uint8_t *)&p, sizeof(p), NULL, 0); + if (ret) { + dev_err(priv->dev, "failed to EC_CODEC_WOV_SET_LANG\n"); + return ret; + } + } + + return 0; +} + +static int wov_hotword_model_put(struct snd_kcontrol *kcontrol, + const unsigned int __user *bytes, + unsigned int size) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + struct ec_param_ec_codec_wov p; + struct ec_response_ec_codec_wov_get_lang r; + uint8_t digest[SHA256_DIGEST_SIZE]; + uint8_t *buf; + int ret; + + /* Skips the TLV header. */ + bytes += 2; + size -= 8; + + dev_dbg(priv->dev, "%s: size=%d\n", __func__, size); + + buf = kmalloc(size, GFP_KERNEL); + if (!buf) + return -ENOMEM; + + if (copy_from_user(buf, bytes, size)) { + ret = -EFAULT; + goto leave; + } + + ret = calculate_sha256(priv, buf, size, digest); + if (ret) + goto leave; + + p.cmd = EC_CODEC_WOV_GET_LANG; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_WOV, + (uint8_t *)&p, sizeof(p), + (uint8_t *)&r, sizeof(r)); + if (ret) + goto leave; + + if (memcmp(digest, r.hash, SHA256_DIGEST_SIZE) == 0) { + dev_dbg(priv->dev, "not updated"); + goto leave; + } + + if (ec_codec_capable(priv, EC_CODEC_CAP_WOV_LANG_SHM)) + ret = wov_set_lang_shm(priv, buf, size, digest); + else + ret = wov_set_lang(priv, buf, size, digest); + +leave: + kfree(buf); + return ret; +} + +static struct snd_kcontrol_new wov_controls[] = { + SOC_SINGLE_BOOL_EXT("Wake-on-Voice Switch", 0, + wov_enable_get, wov_enable_put), + SND_SOC_BYTES_TLV("Hotword Model", 0x11000, NULL, + wov_hotword_model_put), +}; + +static struct snd_soc_dai_driver wov_dai_driver = { + .name = "Wake on Voice", + .capture = { + .stream_name = "WoV Capture", + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_16000, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + }, +}; + +static int wov_host_event(struct notifier_block *nb, + unsigned long queued_during_suspend, void *notify) +{ + struct cros_ec_codec_priv *priv = + container_of(nb, struct cros_ec_codec_priv, wov_notifier); + u32 host_event; + + dev_dbg(priv->dev, "%s\n", __func__); + + host_event = cros_ec_get_host_event(priv->ec_device); + if (host_event & EC_HOST_EVENT_MASK(EC_HOST_EVENT_WOV)) { + schedule_delayed_work(&priv->wov_copy_work, 0); + return NOTIFY_OK; + } else { + return NOTIFY_DONE; + } +} + +static int wov_probe(struct snd_soc_component *component) +{ + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + int ret; + + mutex_init(&priv->wov_dma_lock); + INIT_DELAYED_WORK(&priv->wov_copy_work, wov_copy_work); + + priv->wov_notifier.notifier_call = wov_host_event; + ret = blocking_notifier_chain_register( + &priv->ec_device->event_notifier, &priv->wov_notifier); + if (ret) + return ret; + + if (ec_codec_capable(priv, EC_CODEC_CAP_WOV_LANG_SHM)) { + priv->wov_lang_shm_p = wov_map_shm(priv, + EC_CODEC_SHM_ID_WOV_LANG, + &priv->wov_lang_shm_len, + &priv->wov_lang_shm_type); + if (!priv->wov_lang_shm_p) + return -EFAULT; + } + + if (ec_codec_capable(priv, EC_CODEC_CAP_WOV_AUDIO_SHM)) { + priv->wov_audio_shm_p = wov_map_shm(priv, + EC_CODEC_SHM_ID_WOV_AUDIO, + &priv->wov_audio_shm_len, + &priv->wov_audio_shm_type); + if (!priv->wov_audio_shm_p) + return -EFAULT; + } + + return dmic_probe(component); +} + +static void wov_remove(struct snd_soc_component *component) +{ + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + + blocking_notifier_chain_unregister( + &priv->ec_device->event_notifier, &priv->wov_notifier); +} + +static int wov_pcm_open(struct snd_pcm_substream *substream) +{ + static const struct snd_pcm_hardware hw_param = { + .info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = SNDRV_PCM_RATE_16000, + .channels_min = 1, + .channels_max = 1, + .period_bytes_min = PAGE_SIZE, + .period_bytes_max = 0x20000 / 8, + .periods_min = 8, + .periods_max = 8, + .buffer_bytes_max = 0x20000, + }; + + return snd_soc_set_runtime_hwparams(substream, &hw_param); +} + +static int wov_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *hw_params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_component *component = rtd->codec_dai->component; + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + + mutex_lock(&priv->wov_dma_lock); + priv->wov_substream = substream; + priv->wov_rp = priv->wov_wp = 0; + priv->wov_dma_offset = 0; + priv->wov_burst_read = true; + mutex_unlock(&priv->wov_dma_lock); + + return snd_pcm_lib_alloc_vmalloc_buffer(substream, + params_buffer_bytes(hw_params)); +} + +static int wov_pcm_hw_free(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_component *component = rtd->codec_dai->component; + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + + mutex_lock(&priv->wov_dma_lock); + wov_queue_dequeue(priv, wov_queue_size(priv)); + priv->wov_substream = NULL; + mutex_unlock(&priv->wov_dma_lock); + + cancel_delayed_work_sync(&priv->wov_copy_work); + + return snd_pcm_lib_free_vmalloc_buffer(substream); +} + +static snd_pcm_uframes_t wov_pcm_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_component *component = rtd->codec_dai->component; + struct cros_ec_codec_priv *priv = + snd_soc_component_get_drvdata(component); + + return bytes_to_frames(runtime, priv->wov_dma_offset); +} + +static const struct snd_pcm_ops wov_pcm_ops = { + .open = wov_pcm_open, + .hw_params = wov_pcm_hw_params, + .hw_free = wov_pcm_hw_free, + .pointer = wov_pcm_pointer, + .page = snd_pcm_lib_get_vmalloc_page, +}; + +static const struct snd_soc_component_driver wov_component_driver = { + .probe = wov_probe, + .remove = wov_remove, + .controls = wov_controls, + .num_controls = ARRAY_SIZE(wov_controls), + .ops = &wov_pcm_ops, +}; + static int cros_ec_codec_platform_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct cros_ec_device *ec_device = dev_get_drvdata(pdev->dev.parent); struct cros_ec_codec_priv *priv; + uint32_t val[3]; + struct device_node *node; + struct resource res; + struct ec_param_ec_codec p; + struct ec_response_ec_codec_get_capabilities r; + int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + if (device_property_read_u32_array(dev, "ec-shm", val, 3) == 0) { + priv->ec_shm_addr = (uint64_t)val[0] << 32 | val[1]; + priv->ec_shm_len = val[2]; + + dev_dbg(dev, "ec_shm_addr=%#llx len=%#x\n", + priv->ec_shm_addr, priv->ec_shm_len); + } + + node = of_parse_phandle(dev->of_node, "memory-region", 0); + if (node) { + ret = of_address_to_resource(node, 0, &res); + if (!ret) { + priv->ap_shm_phys_addr = res.start; + priv->ap_shm_len = resource_size(&res); + priv->ap_shm_addr = (uint64_t)devm_ioremap_wc( + dev, priv->ap_shm_phys_addr, + priv->ap_shm_len); + priv->ap_shm_last_alloc = priv->ap_shm_phys_addr; + + dev_dbg(dev, "ap_shm_phys_addr=%#llx len=%#x\n", + priv->ap_shm_phys_addr, priv->ap_shm_len); + } + } + priv->dev = dev; priv->ec_device = ec_device; + atomic_set(&priv->dmic_probed, 0); + + p.cmd = EC_CODEC_GET_CAPABILITIES; + ret = send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC, + (uint8_t *)&p, sizeof(p), + (uint8_t *)&r, sizeof(r)); + if (ret) { + dev_err(dev, "failed to EC_CODEC_GET_CAPABILITIES\n"); + return ret; + } + priv->ec_capabilities = r.capabilities; platform_set_drvdata(pdev, priv); - return devm_snd_soc_register_component(dev, &i2s_rx_component_driver, - &i2s_rx_dai_driver, 1); + ret = devm_snd_soc_register_component(dev, &i2s_rx_component_driver, + &i2s_rx_dai_driver, 1); + if (ret) + return ret; + + return devm_snd_soc_register_component(dev, &wov_component_driver, + &wov_dai_driver, 1); } #ifdef CONFIG_OF From patchwork Sat Oct 5 05:58:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 11175507 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DDD5213BD for ; Sat, 5 Oct 2019 06:05:23 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 7124E222C0 for ; Sat, 5 Oct 2019 06:05:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="GJ4tJkm5"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="RXbvqfEc" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7124E222C0 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 B46EE1682; Sat, 5 Oct 2019 08:04:31 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz B46EE1682 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1570255521; bh=6eWYki9xHrUbqgEpjJp63sI+i3zMaFVCVx3y+dP24Ac=; h=Date:In-Reply-To:References:From:To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=GJ4tJkm5pYe284rxFgU3j/ubo5D/7h7/PGvPEQMPeH5kXRzcqB/AWOjS/cYDeKQ4O LIeQnuTxm8+RSNPHq5lAyrz+CDQVH+DqWIJgQghfvDxg/ynC4lQPnf6FtKCQmIYgs2 HhM2/G6/3V+JAe0T56hi+Qfe7Hbi6eUJC+4ZKiA4= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 21922F8067A; Sat, 5 Oct 2019 07:59:17 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4065EF8067B; Sat, 5 Oct 2019 07:59:16 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 Received: from mail-qk1-x74a.google.com (mail-qk1-x74a.google.com [IPv6:2607:f8b0:4864:20::74a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id B311BF80678 for ; Sat, 5 Oct 2019 07:59:13 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz B311BF80678 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="RXbvqfEc" Received: by mail-qk1-x74a.google.com with SMTP id 11so8768217qkh.15 for ; Fri, 04 Oct 2019 22:59:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=K+dnMsm9RETMWR/Ic3MlJaLBL0zg9YMOTI1WVgS/WPk=; b=RXbvqfEcqwB0bqT13FzQLhQE6NicbE4kgLFKwuYgJfzT7TEx86tS/QWNEoicxz6u11 JWqk4btRQFgBLXQi/HoGUkUTpFQOkXeRvNBUE/NlwvJywjaVpooUUXQ+UlVprbar/4DM rQp21KHZxxLCxxjZBi+2e5qz/ycbs0dH0Y9ovTXTS4rKBFCNwuGa46s2j3MgIxmGXIq+ 6ywqN0NpfWsCbqJfOql4EDcfoRkdtogUt/5zngEIteZo9TCb6ls+xu9GTfFqFeaCI+aK yRnS0RZF1E7adVSwsUeIeJvCWpiKPtiJPLk6rMPIOd2HYdtMcXtJVKi+/eRiyqgOaF4i 6Q1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=K+dnMsm9RETMWR/Ic3MlJaLBL0zg9YMOTI1WVgS/WPk=; b=VAeGfCHEHut+gPo6wf2YipoHSw2Qj1JZfsBnwuKnLLeuNLqJdslXsIAVb2Koukc+jP Zlgnw1mtielU4EXXspLCZeCcorvyMGW4HvTtA2xoCfoFzVUMGQB8pxNQyTUY3H6l76Vt Uwg86WTqNITMbsrZDhyuXw0v8k1PyfQDOIiT9NKWMSPF4DDoJN2STcfKni0jNMAMzdCr 6tPwHuYN/h3O0nV2V/WEqMzhLn2UXjT95EJHfuXLxV9pq6fNmRWhc28CQ0Oulad1/h70 McImeqlrp6YAKE5mhqPZKBav7ahFq7z6avIgzr57LTSUTrok1eHzDnbzz3DeTv0FL4EO +TbA== X-Gm-Message-State: APjAAAWqHu8zW71am/xnA/qh1e7OZ11uNEUESi3ZtdMIC4WvURvNFSLV GV/Thd8ccd1/qd3EXMoTJvU22WiHvRd7 X-Google-Smtp-Source: APXvYqy1dqHH+joNcrM/ZH5ZfAuiymv83lKRDawb1HjpL1VFPmvXg5zGdpWE5M9doj/Sg2Yzvaqm4i7a2xjI X-Received: by 2002:a37:660c:: with SMTP id a12mr13986039qkc.70.1570255152479; Fri, 04 Oct 2019 22:59:12 -0700 (PDT) Date: Sat, 5 Oct 2019 13:58:06 +0800 In-Reply-To: <20191005055808.249089-1-tzungbi@google.com> Message-Id: <20191005130552.8.I57266d36564f393e9d701c9db648cc2efb0346fc@changeid> Mime-Version: 1.0 References: <20191005055808.249089-1-tzungbi@google.com> X-Mailer: git-send-email 2.23.0.581.g78d2f28ef7-goog From: Tzung-Bi Shih To: broonie@kernel.org Cc: gwendal@google.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, cychiang@google.com, drinkcat@google.com, tzungbi@google.com, robh+dt@kernel.org, enric.balletbo@collabora.com, bleung@google.com, dgreid@google.com Subject: [alsa-devel] [PATCH 08/10] ASoC: mediatek: mt6358: support WoV 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" Switch mono DMIC on to support wake-on-voice. Signed-off-by: Tzung-Bi Shih --- sound/soc/codecs/mt6358.c | 105 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/sound/soc/codecs/mt6358.c b/sound/soc/codecs/mt6358.c index bb737fd678cc..1b830ea4f6ed 100644 --- a/sound/soc/codecs/mt6358.c +++ b/sound/soc/codecs/mt6358.c @@ -93,6 +93,8 @@ struct mt6358_priv { int mtkaif_protocol; struct regulator *avdd_reg; + + int wov_enabled; }; int mt6358_set_mtkaif_protocol(struct snd_soc_component *cmpnt, @@ -464,6 +466,106 @@ static int mt6358_put_volsw(struct snd_kcontrol *kcontrol, return ret; } +static void mt6358_restore_pga(struct mt6358_priv *priv); + +static int mt6358_enable_wov_phase2(struct mt6358_priv *priv) +{ + /* analog */ + regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13, + 0xffff, 0x0000); + regmap_update_bits(priv->regmap, MT6358_DCXO_CW14, 0xffff, 0xa2b5); + regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1, + 0xffff, 0x0800); + mt6358_restore_pga(priv); + + regmap_update_bits(priv->regmap, MT6358_DCXO_CW13, 0xffff, 0x9929); + regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON9, + 0xffff, 0x0025); + regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON8, + 0xffff, 0x0005); + + /* digital */ + regmap_update_bits(priv->regmap, MT6358_AUD_TOP_CKPDN_CON0, + 0xffff, 0x0000); + regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3, 0xffff, 0x0120); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG0, 0xffff, 0xffff); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG1, 0xffff, 0x0200); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG2, 0xffff, 0x2424); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG3, 0xffff, 0xdbac); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG4, 0xffff, 0x029e); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG5, 0xffff, 0x0000); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_POSDIV_CFG0, + 0xffff, 0x0000); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_HPF_CFG0, + 0xffff, 0x0451); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_TOP, 0xffff, 0x68d1); + + return 0; +} + +static int mt6358_disable_wov_phase2(struct mt6358_priv *priv) +{ + /* digital */ + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_TOP, 0xffff, 0xc000); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_HPF_CFG0, + 0xffff, 0x0450); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_POSDIV_CFG0, + 0xffff, 0x0c00); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG5, 0xffff, 0x0100); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG4, 0xffff, 0x006c); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG3, 0xffff, 0xa879); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG2, 0xffff, 0x2323); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG1, 0xffff, 0x0400); + regmap_update_bits(priv->regmap, MT6358_AFE_VOW_CFG0, 0xffff, 0x0000); + regmap_update_bits(priv->regmap, MT6358_GPIO_MODE3, 0xffff, 0x02d8); + regmap_update_bits(priv->regmap, MT6358_AUD_TOP_CKPDN_CON0, + 0xffff, 0x0000); + + /* analog */ + regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON8, + 0xffff, 0x0004); + regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON9, + 0xffff, 0x0000); + regmap_update_bits(priv->regmap, MT6358_DCXO_CW13, 0xffff, 0x9829); + regmap_update_bits(priv->regmap, MT6358_AUDENC_ANA_CON1, + 0xffff, 0x0000); + mt6358_restore_pga(priv); + regmap_update_bits(priv->regmap, MT6358_DCXO_CW14, 0xffff, 0xa2b5); + regmap_update_bits(priv->regmap, MT6358_AUDDEC_ANA_CON13, + 0xffff, 0x0010); + + return 0; +} + +static int mt6358_get_wov(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol); + struct mt6358_priv *priv = snd_soc_component_get_drvdata(c); + + ucontrol->value.integer.value[0] = priv->wov_enabled; + return 0; +} + +static int mt6358_put_wov(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *c = snd_soc_kcontrol_component(kcontrol); + struct mt6358_priv *priv = snd_soc_component_get_drvdata(c); + int enabled = ucontrol->value.integer.value[0]; + + if (priv->wov_enabled != enabled) { + if (enabled) + mt6358_enable_wov_phase2(priv); + else + mt6358_disable_wov_phase2(priv); + + priv->wov_enabled = enabled; + } + + return 0; +} + static const DECLARE_TLV_DB_SCALE(playback_tlv, -1000, 100, 0); static const DECLARE_TLV_DB_SCALE(pga_tlv, 0, 600, 0); @@ -483,6 +585,9 @@ static const struct snd_kcontrol_new mt6358_snd_controls[] = { MT6358_AUDENC_ANA_CON0, MT6358_AUDENC_ANA_CON1, 8, 4, 0, snd_soc_get_volsw, mt6358_put_volsw, pga_tlv), + + SOC_SINGLE_BOOL_EXT("Wake-on-Voice Phase2 Switch", 0, + mt6358_get_wov, mt6358_put_wov), }; /* MUX */ From patchwork Sat Oct 5 05:58:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 11175509 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EAEA71599 for ; Sat, 5 Oct 2019 06:06:11 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 7E7C3222C5 for ; Sat, 5 Oct 2019 06:06:11 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="tU5AgW4B"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="hrALEg/H" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7E7C3222C5 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 C2683168B; Sat, 5 Oct 2019 08:05:19 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz C2683168B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1570255569; bh=dgMBczG8n4eX59NRcsNeTAzspGgIHXeUjDFry49lhoo=; h=Date:In-Reply-To:References:From:To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=tU5AgW4BroegCt2STlCoLo4RhSn9gQLKgXgmQZVZLij4bJaf/9p6GKO5fIikopozD 0bCNt5UwBQ+auYLPNHfy2Unqzt9bJOZLh/lNCsNwEOnssALNG1ygtoT2gcN6lb74lP i4ptmifghdIBPC01aZBQ8vG7PY/94uUJ7rriLxNU= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id D67CEF806EF; Sat, 5 Oct 2019 07:59:21 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 2DC73F806F7; Sat, 5 Oct 2019 07:59:21 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 Received: from mail-qt1-x84a.google.com (mail-qt1-x84a.google.com [IPv6:2607:f8b0:4864:20::84a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id CDE2AF806F0 for ; Sat, 5 Oct 2019 07:59:18 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz CDE2AF806F0 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="hrALEg/H" Received: by mail-qt1-x84a.google.com with SMTP id n4so8982107qtp.19 for ; Fri, 04 Oct 2019 22:59:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=qa8lzqL1R0bb0ynaHlYSrIGdb8PV3M5EMBcQMQXD2v8=; b=hrALEg/HmJ+RBF4lWI2dLrqiBrrs7sZA/d7m0qrc+yGchyARzfncsLzaSzGBuIU8ZL UWpgcF3zP14DCRh/RWgRZG15US8Z6o5hnN8Sk60a5IufhHdiwY40G0e5VO6nALCLFBn+ tSi0AWFUgslLrus5/5P3Je4gX0nLD96IGzBMvmDl3z8MRz9yDjFStJHjlSzbFBOovRwQ GdbNRZxFQxlvwUsTNTeLUrpN2vT1tdvfPoRdsAxpqNrBB4ch9vDvf01x20MIneIkhAlt /sLojDnfpPo45316rmbmfvE/MS3iTPke10abVjbfp90b9gVwBWPlSDWsM13wJIWfnOcC AUBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=qa8lzqL1R0bb0ynaHlYSrIGdb8PV3M5EMBcQMQXD2v8=; b=VnObjV59imcKWQXomNfHqYzNsbg/L5RhsBnrjbdCDdHz31cWzzs/6h9LaTIl5BkolU w6JQNwxPDJqRhnrE1xqkno1/uyL8HIXCv6mBVeLIJulg2WmQJT+SXv2A+47+e2uFNd4f ppGqwJwEAANuEfhvIeq70xbOYv7Mf2+xps0hz+CztwWhZOKKvbVXsbEV0OHoaJmdz8i6 KY6EuWZs6BiBoiilexjfmNdj1OfSjOT1Mh5PUwy7fQ0ETERQKC+xH+5fuGRUGvmL6JwV D56S8/cUV0Eg7mbk4XbZfx+xxDDXr42eTtwxlX/Yf/QVuYwU3QoD7R3sIX4yJn4OLvYO Gr2g== X-Gm-Message-State: APjAAAWv0ZUn5YFgmLI5YNYsds5jcEXXftF+fspCKWqKWTeCvkaI18Q9 n9DRhM9C0aGJ/3Xw+F6VnpF7lBr9f6V1 X-Google-Smtp-Source: APXvYqyADdkh+lHP8dRTBId0QoDCr/3kdmcRfZKzwDNBV8JzuoHxl6Bb9Z5JmrP7olAejzPd8rI8yjA0rUL/ X-Received: by 2002:a37:6789:: with SMTP id b131mr13603933qkc.314.1570255157630; Fri, 04 Oct 2019 22:59:17 -0700 (PDT) Date: Sat, 5 Oct 2019 13:58:07 +0800 In-Reply-To: <20191005055808.249089-1-tzungbi@google.com> Message-Id: <20191005130552.9.Iec97a3f137148cdf316056612590b3e0b302f5f3@changeid> Mime-Version: 1.0 References: <20191005055808.249089-1-tzungbi@google.com> X-Mailer: git-send-email 2.23.0.581.g78d2f28ef7-goog From: Tzung-Bi Shih To: broonie@kernel.org Cc: gwendal@google.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, cychiang@google.com, drinkcat@google.com, tzungbi@google.com, robh+dt@kernel.org, enric.balletbo@collabora.com, bleung@google.com, dgreid@google.com Subject: [alsa-devel] [PATCH 09/10] ASoC: dt-bindings: mt8183: add ec-codec 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" Add an optional property "ec-codec". If specified, mt8183 could use the "wake on voice" feature offered by EC codec. Signed-off-by: Tzung-Bi Shih --- .../bindings/sound/mt8183-mt6358-ts3a227-max98357.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/mt8183-mt6358-ts3a227-max98357.txt b/Documentation/devicetree/bindings/sound/mt8183-mt6358-ts3a227-max98357.txt index 17ff3892f439..decaa013a07e 100644 --- a/Documentation/devicetree/bindings/sound/mt8183-mt6358-ts3a227-max98357.txt +++ b/Documentation/devicetree/bindings/sound/mt8183-mt6358-ts3a227-max98357.txt @@ -6,12 +6,15 @@ Required properties: Optional properties: - mediatek,headset-codec: the phandles of ts3a227 codecs +- mediatek,ec-codec: the phandle of EC codecs. + See google,cros-ec-codec.txt for more details. Example: sound { compatible = "mediatek,mt8183_mt6358_ts3a227_max98357"; mediatek,headset-codec = <&ts3a227>; + mediatek,ec-codec = <&ec_codec>; mediatek,platform = <&afe>; }; From patchwork Sat Oct 5 05:58:08 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tzung-Bi Shih X-Patchwork-Id: 11175511 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2E2361599 for ; Sat, 5 Oct 2019 06:06:43 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id B7320222C0 for ; Sat, 5 Oct 2019 06:06:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=alsa-project.org header.i=@alsa-project.org header.b="AWeb6elA"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=google.com header.i=@google.com header.b="BX8Y/5Zn" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B7320222C0 Authentication-Results: mail.kernel.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=alsa-devel-bounces@alsa-project.org 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 D41601685; Sat, 5 Oct 2019 08:05:50 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa0.perex.cz D41601685 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=alsa-project.org; s=default; t=1570255600; bh=MkoGuavGoOYmDb1rQq9CogQgljWl2JKKzQcfgJJWMxE=; h=Date:In-Reply-To:References:From:To:Cc:Subject:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From; b=AWeb6elA7Nvbrc5izN//I30wOxcIqrXdMv7VasjmDDZY5EMJW6wTE157Guwnu8d+3 MlC0UrlGo239TiRRiZ7kUDRRtHrM16DvzSCOEAdMjHuu4f/vN/qx/N/SYNzZD5jO1c laoBgEDFzSuK8chzh6BeP6U60+y110c/RQfZBnM0= Received: from alsa1.perex.cz (localhost.localdomain [127.0.0.1]) by alsa1.perex.cz (Postfix) with ESMTP id 1AED5F8070B; Sat, 5 Oct 2019 07:59:28 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa1.perex.cz (Postfix, from userid 50401) id 4A869F8070C; Sat, 5 Oct 2019 07:59:27 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on alsa1.perex.cz X-Spam-Level: X-Spam-Status: No, score=-7.6 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,SPF_HELO_NONE,SPF_PASS,USER_IN_DEF_DKIM_WL autolearn=disabled version=3.4.0 Received: from mail-vk1-xa4a.google.com (mail-vk1-xa4a.google.com [IPv6:2607:f8b0:4864:20::a4a]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by alsa1.perex.cz (Postfix) with ESMTPS id AF6D4F80709 for ; Sat, 5 Oct 2019 07:59:24 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 alsa1.perex.cz AF6D4F80709 Authentication-Results: alsa1.perex.cz; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="BX8Y/5Zn" Received: by mail-vk1-xa4a.google.com with SMTP id x128so3662531vkx.16 for ; Fri, 04 Oct 2019 22:59:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=wFKIOToRbdu3m60b5e+tQ6dn8L8Tfr3EeQzYLtHUnvY=; b=BX8Y/5ZnAVOwdwTaaOj3xlZG9yaLNx/lWLp0xCiJ+YAQbzLO1/H7MWVfOS9zyVn2Hq 6DmJsbHEAYHSI5ykSn+SF/fLa7J/pbS0JTn6ozAxgAQv+g6EaWidIvhS2PvZTNkadvNW kBwAY+QMO0ZuEQHuKI3MH+ydudPLul3Z2tfllT1Za97JZI36sI+YN4rnuJnmWDXyA9w0 JfR9PcI0Qiy/j6r0PjQkoiXJFT0SVCH+J/6QoT8zNo8U5tpXQ8e1CZuZpdR3J/cO9Pow xFI8hY9w2ambpomcFxlD1eHaOo4gRWdnCXaim60GnlzdFp7WHOAwe4LUWsWE0FJ4XU8l 1F4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=wFKIOToRbdu3m60b5e+tQ6dn8L8Tfr3EeQzYLtHUnvY=; b=kz/vArKEEqRE57eeoPb3KFWqSCfy2njhdjTf0Q0+CpUaQe6kuycf4Gwi3iU0nJROis IbJin88Q2donVCHAnHej/gOIQ/gVggzIlkkQ6/2AjLAKXNtaytbsst9SQRigx2LG9tez e6n49GHcTlSw250yt6KVVxFwOrI/tpteeMk+ug9NxGxJXndj0fSB9M9KzLeIQM/T2YU9 uqLHRfzo5JX59o6soMWr5m3C4LTiJgZ/wDV9ZYJYUvAi1zyxt79lhdQwONEDhVsGgxUF YwdYxp3XhLAP3GheWhf/01hpHQe1rhqSrp3YnCHgF1oiU05tSPm30Ksg8PrutUX7e7YQ rEUA== X-Gm-Message-State: APjAAAWHvzHaOIoeD2gxxiNifJeAjPa3izi6ks8L2WS7obBzEHAfFEZz yFLyaf5DR4/DZ3uIS0C1AcQyaHyUkb84 X-Google-Smtp-Source: APXvYqyoB3OHuRFIyy3n6oDmCcP3tbotAm1PNN/nfJ/Sjg3TJ9YV+pkvlVVzUuCrfqFFRw6Y4K/Xin44PkWY X-Received: by 2002:ab0:658a:: with SMTP id v10mr2608199uam.73.1570255162880; Fri, 04 Oct 2019 22:59:22 -0700 (PDT) Date: Sat, 5 Oct 2019 13:58:08 +0800 In-Reply-To: <20191005055808.249089-1-tzungbi@google.com> Message-Id: <20191005130552.10.Ibf012d0cd8679d846213606dc5f426aea1ff590a@changeid> Mime-Version: 1.0 References: <20191005055808.249089-1-tzungbi@google.com> X-Mailer: git-send-email 2.23.0.581.g78d2f28ef7-goog From: Tzung-Bi Shih To: broonie@kernel.org Cc: gwendal@google.com, devicetree@vger.kernel.org, alsa-devel@alsa-project.org, cychiang@google.com, drinkcat@google.com, tzungbi@google.com, robh+dt@kernel.org, enric.balletbo@collabora.com, bleung@google.com, dgreid@google.com Subject: [alsa-devel] [PATCH 10/10] ASoC: mediatek: mt8183: support WoV 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" Add DAI link and pin muxing for wake on voice. Signed-off-by: Tzung-Bi Shih --- sound/soc/mediatek/Kconfig | 1 + .../mt8183/mt8183-mt6358-ts3a227-max98357.c | 70 ++++++++++++++++++- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 111e44b64b38..8b29f3979899 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -125,6 +125,7 @@ config SND_SOC_MT8183_MT6358_TS3A227E_MAX98357A select SND_SOC_MAX98357A select SND_SOC_BT_SCO select SND_SOC_TS3A227E + select SND_SOC_CROS_EC_CODEC help This adds ASoC driver for Mediatek MT8183 boards with the MT6358 TS3A227E MAX98357A audio codec. diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c index bb9cdc0d6552..0555f7d73d05 100644 --- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c +++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c @@ -19,11 +19,12 @@ enum PINCTRL_PIN_STATE { PIN_STATE_DEFAULT = 0, PIN_TDM_OUT_ON, PIN_TDM_OUT_OFF, + PIN_WOV, PIN_STATE_MAX }; static const char * const mt8183_pin_str[PIN_STATE_MAX] = { - "default", "aud_tdm_out_on", "aud_tdm_out_off", + "default", "aud_tdm_out_on", "aud_tdm_out_off", "wov", }; struct mt8183_mt6358_ts3a227_max98357_priv { @@ -142,6 +143,11 @@ SND_SOC_DAILINK_DEFS(playback_hdmi, DAILINK_COMP_ARRAY(COMP_DUMMY()), DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(wake_on_voice, + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + /* BE */ SND_SOC_DAILINK_DEFS(primary_codec, DAILINK_COMP_ARRAY(COMP_CPU("ADDA")), @@ -229,6 +235,41 @@ static struct snd_soc_ops mt8183_mt6358_tdm_ops = { .shutdown = mt8183_mt6358_tdm_shutdown, }; +static int +mt8183_mt6358_ts3a227_max98357_wov_startup( + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct mt8183_mt6358_ts3a227_max98357_priv *priv = + snd_soc_card_get_drvdata(card); + + return pinctrl_select_state(priv->pinctrl, + priv->pin_states[PIN_WOV]); +} + +static void +mt8183_mt6358_ts3a227_max98357_wov_shutdown( + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct mt8183_mt6358_ts3a227_max98357_priv *priv = + snd_soc_card_get_drvdata(card); + int ret; + + ret = pinctrl_select_state(priv->pinctrl, + priv->pin_states[PIN_STATE_DEFAULT]); + if (ret) + dev_err(card->dev, "%s failed to select state %d\n", + __func__, ret); +} + +static const struct snd_soc_ops mt8183_mt6358_ts3a227_max98357_wov_ops = { + .startup = mt8183_mt6358_ts3a227_max98357_wov_startup, + .shutdown = mt8183_mt6358_ts3a227_max98357_wov_shutdown, +}; + static struct snd_soc_dai_link mt8183_mt6358_ts3a227_max98357_dai_links[] = { /* FE */ @@ -306,6 +347,15 @@ mt8183_mt6358_ts3a227_max98357_dai_links[] = { .dpcm_playback = 1, SND_SOC_DAILINK_REG(playback_hdmi), }, + { + .name = "Wake on Voice", + .stream_name = "Wake on Voice", + .ignore_suspend = 1, + .ignore = 1, + SND_SOC_DAILINK_REG(wake_on_voice), + .ops = &mt8183_mt6358_ts3a227_max98357_wov_ops, + }, + /* BE */ { .name = "Primary Codec", @@ -429,7 +479,7 @@ static int mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) { struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card; - struct device_node *platform_node; + struct device_node *platform_node, *ec_codec; struct snd_soc_dai_link *dai_link; struct mt8183_mt6358_ts3a227_max98357_priv *priv; int ret; @@ -444,10 +494,24 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) return -EINVAL; } + ec_codec = of_parse_phandle(pdev->dev.of_node, "mediatek,ec-codec", 0); + for_each_card_prelinks(card, i, dai_link) { if (dai_link->platforms->name) continue; - dai_link->platforms->of_node = platform_node; + + if (ec_codec && strcmp(dai_link->name, "Wake on Voice") == 0) { + dai_link->cpus[0].name = NULL; + dai_link->cpus[0].of_node = ec_codec; + dai_link->cpus[0].dai_name = NULL; + dai_link->codecs[0].name = NULL; + dai_link->codecs[0].of_node = ec_codec; + dai_link->codecs[0].dai_name = "Wake on Voice"; + dai_link->platforms[0].of_node = ec_codec; + dai_link->ignore = 0; + } else { + dai_link->platforms->of_node = platform_node; + } } mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node =