From patchwork Mon Mar 5 12:32:13 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Srinivas Kandagatla X-Patchwork-Id: 130634 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp2633269lja; Mon, 5 Mar 2018 04:34:25 -0800 (PST) X-Google-Smtp-Source: AG47ELt3O+NMLy8xfxxSZM4T7slqox6KCpZL++cUrXHpHdCAcOMYNldvEZsPElP4arMCX5pK2HLP X-Received: by 2002:a17:902:ab8c:: with SMTP id f12-v6mr12816352plr.171.1520253265594; Mon, 05 Mar 2018 04:34:25 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520253265; cv=none; d=google.com; s=arc-20160816; b=JSPb521TbAsKF4KAreEd3mSOS4Jjmqlc68pasv1DRVKnAfKNS8CcG6qWwb3wUzUWQr ICLC+ClWXcyF18vZy7sqY/gGK59gz5aYncbRn8VwXSPWdwmP7btxE3b87sWuvTw4eC3u Nelk38jnOwaXbVDtKziKgqfUwvuC+Ll/WL+CX6ru+moseCe1nrbISpAhjjBCfDeoFYxd zBdL3Yv1IiFDIFA/ZBUu3Ka7EyOIEZ+T89RMrl7cw00UtbGX3tPjFuGbRliCifRqwBI8 q+Kylv99uNnGt+59txsc1KtCsUU/10UiWIcSebkxR3KEJOrM80qMuZLdyCpbU2PdTTME AaFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature:arc-authentication-results; bh=42jOa4efiGbeEFQ7rQXtrXcDiBzNC9QAHlkRC4sgMqo=; b=nOwcWbmk7b9KhwB+UDW7LJSyZcc5xizBGLeJZj0W0i9lwU3q9kvsCjIzoSWWGHjyVH 4/xBw4j/kH0DL6ZV/8wZV/4yymybpGdrrV7KsnIHTrBylwIi1YnzRKwwa7ZU9XTTyEVJ M8KQVTMIzAcEfdrQq9LE3gwC7vMhrpyZpW6NNsEHqlhmkWr7Czkmw0XO5Jmw8cW06DBQ Ul7kySTH2yR3RDGIToXe0f2/WVRjWnuo4Dea1pT/cQmHITlZ9g69GQ5bPO2pDQzhfiVi mkqus8I9nYik4Cd3nerpvbVFjUnk1ut5vo0SiEQF/2ICfLwSqlmC3G0Bq9DjcxkiOphL Ichg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MRdDG/vl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r13-v6si9566033plj.141.2018.03.05.04.34.25; Mon, 05 Mar 2018 04:34:25 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=MRdDG/vl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933959AbeCEMeW (ORCPT + 28 others); Mon, 5 Mar 2018 07:34:22 -0500 Received: from mail-wr0-f195.google.com ([209.85.128.195]:34574 "EHLO mail-wr0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932864AbeCEMeU (ORCPT ); Mon, 5 Mar 2018 07:34:20 -0500 Received: by mail-wr0-f195.google.com with SMTP id o8so5573617wra.1 for ; Mon, 05 Mar 2018 04:34:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=42jOa4efiGbeEFQ7rQXtrXcDiBzNC9QAHlkRC4sgMqo=; b=MRdDG/vlQ/WBxhIbmkt3G2TJJ1Nbdpwc2TC3CctqjLy38bIwlDi5wh/G6mXN5HhCFC WUBpwCxSzlRWavZT15E5B9spSqWcvOZf/1sFAnX4i9dABa1IVuRVyL0nisUZkT4nMjQi prEBqb1VCJNYxWO/nh5cZF8cEqo9Lnt9G5yMk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=42jOa4efiGbeEFQ7rQXtrXcDiBzNC9QAHlkRC4sgMqo=; b=Oi9nEvhtuE5l2lmO8YsCBpkCT9WQ7OJR90fy6NXy60+uWLDxntf4kzTdxC5l+5P/H9 1vPDPbrhF3tLppPdTnFkJhK/d/d4K7GHH3qdfW/X0PEUnYhmtVB3I/5sBE8vUoYhAP9Q GtX17oE94ubxtekJ11/01aLgab7YO+q8VQ8XQsgOl/Lj5R8VYNx48dmeyTeuFOby65Ho mngk40u2wzsfdQIdfrXA/GCk3ghqOFq35i7fWNkS+pDji3B00ZPWUo/O0wHgFmRG1IFg pgpHWC0dcapJ8x9Zd9Fo6IW/BXngkvmaR9u8W//nmCs3n1PUZ1nK4o7YnWA9y/zkS1F+ k48A== X-Gm-Message-State: APf1xPBBxwuONC776L5gVXRrtEP2fOHkg7w5LQclZ4J+NLjGAVHoNGOm 8bb+DJZl9GmvEvLUUFcEyVn6kg== X-Received: by 10.223.168.46 with SMTP id l43mr13503242wrc.118.1520253258942; Mon, 05 Mar 2018 04:34:18 -0800 (PST) Received: from localhost.localdomain (cpc90716-aztw32-2-0-cust92.18-1.cable.virginm.net. [86.26.100.93]) by smtp.gmail.com with ESMTPSA id o12sm20486080wrb.15.2018.03.05.04.34.17 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 05 Mar 2018 04:34:18 -0800 (PST) From: srinivas.kandagatla@linaro.org To: Mark Brown , Liam Girdwood , Takashi Iwai Cc: Jaroslav Kysela , alsa-devel@alsa-project.org, linux-kernel@vger.kernel.org, Srinivas Kandagatla Subject: [RFC PATCH] ASoC: dapm: add support to pinctrl dapm Date: Mon, 5 Mar 2018 12:32:13 +0000 Message-Id: <20180305123213.2045-1-srinivas.kandagatla@linaro.org> X-Mailer: git-send-email 2.15.1 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Srinivas Kandagatla Purpose of having pinctrl dapm is to dynamically put the pins in low power state when they are not actively used by the audio and saving power. Without this each driver has to set the pinctrl states, either during probe or dynamically depending on the callbacks received from ASoC core. This patch adds a single macro SND_SOC_DAPM_PINCTRL which takes, widget, active and sleep state names, and the dapm would use active and sleep state pinctrl names to put the pins in active and sleep state respectively. Signed-off-by: Srinivas Kandagatla --- Hi All, Purpose of this patch is to discuss the idea of having pinctrl part of dapm. As an example on Qualcomm SoCs there are multiple I2S Interfaces, each of these interfaces have there own pinctrls setting, It does not make sense for the machine/platform/componet driver to put them in default/active state durning probe/init as it would waste power. If we make these pinctrl part of the dapm sequence, these would only become active when the stream is active which would save power. This patch adds a single macro SND_SOC_DAPM_PINCTRL which takes, widget, active and sleep state names, and the dapm would use active and sleep state pinctrl names to put the pins in active and sleep state respectively. Thanks, Srini include/sound/soc-dapm.h | 16 ++++++++++++++++ sound/soc/soc-dapm.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) -- 2.15.1 diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 344b96c206a3..a6ce2de4e20a 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -269,6 +269,13 @@ struct device; .reg = SND_SOC_NOPM, .shift = wdelay, .event = dapm_regulator_event, \ .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD, \ .on_val = wflags} +#define SND_SOC_DAPM_PINCTRL(wname, active, sleep) \ +{ .id = snd_soc_dapm_pinctrl, .name = wname, \ + .priv = (&(struct snd_soc_dapm_pinctrl_priv) \ + { .active_state = active, .sleep_state = sleep,}), \ + .reg = SND_SOC_NOPM, .event = dapm_pinctrl_event, \ + .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD } + /* dapm kcontrol types */ @@ -374,6 +381,8 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); int dapm_clock_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); +int dapm_pinctrl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); /* dapm controls */ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, @@ -500,6 +509,7 @@ enum snd_soc_dapm_type { snd_soc_dapm_pre, /* machine specific pre widget - exec first */ snd_soc_dapm_post, /* machine specific post widget - exec last */ snd_soc_dapm_supply, /* power/clock supply */ + snd_soc_dapm_pinctrl, /* pinctrl */ snd_soc_dapm_regulator_supply, /* external regulator */ snd_soc_dapm_clock_supply, /* external clock */ snd_soc_dapm_aif_in, /* audio interface input */ @@ -581,6 +591,7 @@ struct snd_soc_dapm_widget { void *priv; /* widget specific data */ struct regulator *regulator; /* attached regulator */ + struct pinctrl *pinctrl; /* attached pinctrl */ const struct snd_soc_pcm_stream *params; /* params for dai links */ unsigned int num_params; /* number of params for dai links */ unsigned int params_select; /* currently selected param for dai link */ @@ -683,6 +694,11 @@ struct snd_soc_dapm_stats { int neighbour_checks; }; +struct snd_soc_dapm_pinctrl_priv { + const char *active_state; + const char *sleep_state; +}; + /** * snd_soc_dapm_init_bias_level() - Initialize DAPM bias level * @dapm: The DAPM context to initialize diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 40085a4c8f92..babff1cd2849 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -72,6 +73,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, static int dapm_up_seq[] = { [snd_soc_dapm_pre] = 0, [snd_soc_dapm_regulator_supply] = 1, + [snd_soc_dapm_pinctrl] = 1, [snd_soc_dapm_clock_supply] = 1, [snd_soc_dapm_supply] = 2, [snd_soc_dapm_micbias] = 3, @@ -119,6 +121,7 @@ static int dapm_down_seq[] = { [snd_soc_dapm_dai_link] = 11, [snd_soc_dapm_supply] = 12, [snd_soc_dapm_clock_supply] = 13, + [snd_soc_dapm_pinctrl] = 13, [snd_soc_dapm_regulator_supply] = 13, [snd_soc_dapm_post] = 14, }; @@ -1287,6 +1290,33 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, } EXPORT_SYMBOL_GPL(dapm_regulator_event); +/* + * Handler for pinctrl widget. + */ +int dapm_pinctrl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_dapm_pinctrl_priv *priv = w->priv; + struct pinctrl *p = w->pinctrl; + struct pinctrl_state *s; + + if (!p || !priv) + return -EIO; + + soc_dapm_async_complete(w->dapm); + + if (SND_SOC_DAPM_EVENT_ON(event)) + s = pinctrl_lookup_state(p, priv->active_state); + else + s = pinctrl_lookup_state(p, priv->sleep_state); + + if (IS_ERR(s)) + return PTR_ERR(s); + + return pinctrl_select_state(p, s); +} +EXPORT_SYMBOL_GPL(dapm_pinctrl_event); + /* * Handler for clock supply widget. */ @@ -1900,6 +1930,7 @@ static int dapm_power_widgets(struct snd_soc_card *card, int event) break; case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_pinctrl: case snd_soc_dapm_clock_supply: case snd_soc_dapm_micbias: if (d->target_bias_level < SND_SOC_BIAS_STANDBY) @@ -2313,6 +2344,7 @@ static ssize_t dapm_widget_show_component(struct snd_soc_component *cmpnt, case snd_soc_dapm_mixer_named_ctl: case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_pinctrl: case snd_soc_dapm_clock_supply: if (w->name) count += sprintf(buf + count, "%s: %s\n", @@ -3462,6 +3494,17 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, w->name, ret); } break; + case snd_soc_dapm_pinctrl: + w->pinctrl = devm_pinctrl_get(dapm->dev); + if (IS_ERR_OR_NULL(w->pinctrl)) { + ret = PTR_ERR(w->pinctrl); + if (ret == -EPROBE_DEFER) + return ERR_PTR(ret); + dev_err(dapm->dev, "ASoC: Failed to request %s: %d\n", + w->name, ret); + return NULL; + } + break; case snd_soc_dapm_clock_supply: #ifdef CONFIG_CLKDEV_LOOKUP w->clk = devm_clk_get(dapm->dev, w->name); @@ -3541,6 +3584,7 @@ snd_soc_dapm_new_control_unlocked(struct snd_soc_dapm_context *dapm, break; case snd_soc_dapm_supply: case snd_soc_dapm_regulator_supply: + case snd_soc_dapm_pinctrl: case snd_soc_dapm_clock_supply: case snd_soc_dapm_kcontrol: w->is_supply = 1;