From patchwork Mon Apr 20 09:12:03 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pascal Huerst X-Patchwork-Id: 6241131 Return-Path: X-Original-To: patchwork-alsa-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 09676BF4A6 for ; Mon, 20 Apr 2015 09:12:43 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id E0CF420361 for ; Mon, 20 Apr 2015 09:12:41 +0000 (UTC) Received: from alsa0.perex.cz (alsa0.perex.cz [77.48.224.243]) by mail.kernel.org (Postfix) with ESMTP id 5B49120221 for ; Mon, 20 Apr 2015 09:12:40 +0000 (UTC) Received: by alsa0.perex.cz (Postfix, from userid 1000) id 95211265680; Mon, 20 Apr 2015 11:12:38 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Status: No, score=-1.8 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, NO_DNS_FOR_FROM, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=no version=3.3.1 Received: from alsa0.perex.cz (localhost [IPv6:::1]) by alsa0.perex.cz (Postfix) with ESMTP id A14532654BA; Mon, 20 Apr 2015 11:12:29 +0200 (CEST) X-Original-To: alsa-devel@alsa-project.org Delivered-To: alsa-devel@alsa-project.org Received: by alsa0.perex.cz (Postfix, from userid 1000) id C2BF52654BE; Mon, 20 Apr 2015 11:12:27 +0200 (CEST) Received: from mail-wi0-f177.google.com (mail-wi0-f177.google.com [209.85.212.177]) by alsa0.perex.cz (Postfix) with ESMTP id 8D6F7265487; Mon, 20 Apr 2015 11:12:20 +0200 (CEST) Received: by wiax7 with SMTP id x7so78434917wia.0; Mon, 20 Apr 2015 02:12:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=gTQPqL+ZOlqkNXrztPQN/mN1hbUHROXGPhJjVvWVQKo=; b=rkiHJfjePWc2otlSzygTxwPfLyUaokWfq9k+ULcCwOnIRZxiNLP0vI++AieVpphefp cOXNRfWVhbSS3XzhPdLgrxIpWDWBzRm+qbZ0BVht0kkWwZf56QJDZDaghU+Deb5p82OE 3oGq8OO5wa4QlIwdgX9FPRG3Hqhs2nzS1qysB8Tw9VfZ4oSQh/jobP9dHpL4oiV1AQQY 8ewXydPKyglEMI4uAXb69HRGmH432M0mfGtDpKRYbaZHTMo5oayUR/qhp0ZNPL2awfnx 06k2gsobHqBBMSr6BrFPYPVqZ8c011hoTooKpy9qJjzKmXjqaX8XDVp9fJZ2qirSSvQM g6+w== X-Received: by 10.194.121.68 with SMTP id li4mr29692328wjb.84.1429521138228; Mon, 20 Apr 2015 02:12:18 -0700 (PDT) Received: from localhost.localdomain ([178.19.216.75]) by mx.google.com with ESMTPSA id fs9sm26349231wjc.34.2015.04.20.02.12.17 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 20 Apr 2015 02:12:17 -0700 (PDT) From: pascal.huerst@gmail.com To: lars@metafoo.de Date: Mon, 20 Apr 2015 11:12:03 +0200 Message-Id: <1429521123-12764-1-git-send-email-pascal.huerst@gmail.com> X-Mailer: git-send-email 1.9.3 Cc: alsa-devel@alsa-project.org, patch@alsa-project.org, tiwai@suse.de, lgirdwood@gmail.com, broonie@kernel.org, Pascal Huerst Subject: [alsa-devel] [PATCH resend] ASoC: adau1701: add regulator consumer support X-BeenThere: alsa-devel@alsa-project.org X-Mailman-Version: 2.1.14 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: , MIME-Version: 1.0 Errors-To: alsa-devel-bounces@alsa-project.org Sender: alsa-devel-bounces@alsa-project.org X-Virus-Scanned: ClamAV using ClamSMTP From: Pascal Huerst The adau1701 has two power domains, DVDD and AVDD. Enable them both as long as the codec is in use. Signed-off-by: Pascal Huerst Acked-by: Lars-Peter Clausen --- .../devicetree/bindings/sound/adi,adau1701.txt | 4 + sound/soc/codecs/adau1701.c | 125 ++++++++++++++++++--- 2 files changed, 114 insertions(+), 15 deletions(-) -- 1.9.3 diff --git a/Documentation/devicetree/bindings/sound/adi,adau1701.txt b/Documentation/devicetree/bindings/sound/adi,adau1701.txt index 547a49b..0d1128c 100644 --- a/Documentation/devicetree/bindings/sound/adi,adau1701.txt +++ b/Documentation/devicetree/bindings/sound/adi,adau1701.txt @@ -20,6 +20,8 @@ Optional properties: pin configurations as described in the datasheet, table 53. Note that the value of this property has to be prefixed with '/bits/ 8'. + - avdd-supply: Power supply for AVDD, providing 3.3V + - dvdd-supply: Power supply for DVDD, providing 3.3V Examples: @@ -28,6 +30,8 @@ Examples: compatible = "adi,adau1701"; reg = <0x34>; reset-gpio = <&gpio 23 0>; + avdd-supply = <&vdd_3v3_reg>; + dvdd-supply = <&vdd_3v3_reg>; adi,pll-mode-gpios = <&gpio 24 0 &gpio 25 0>; adi,pin-config = /bits/ 8 <0x4 0x7 0x5 0x5 0x4 0x4 0x4 0x4 0x4 0x4 0x4 0x4>; diff --git a/sound/soc/codecs/adau1701.c b/sound/soc/codecs/adau1701.c index d4e219b..ca94ae8 100644 --- a/sound/soc/codecs/adau1701.c +++ b/sound/soc/codecs/adau1701.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -101,6 +102,10 @@ #define ADAU1701_FIRMWARE "adau1701.bin" +static const char * const supply_names[] = { + "dvdd", "avdd" +}; + struct adau1701 { int gpio_nreset; int gpio_pll_mode[2]; @@ -112,6 +117,7 @@ struct adau1701 { u8 pin_config[12]; struct sigmadsp *sigmadsp; + struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; }; static const struct snd_kcontrol_new adau1701_controls[] = { @@ -669,6 +675,13 @@ static int adau1701_probe(struct snd_soc_codec *codec) if (ret) return ret; + ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies), + adau1701->supplies); + if (ret < 0) { + dev_err(codec->dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + /* * Let the pll_clkdiv variable default to something that won't happen * at runtime. That way, we can postpone the firmware download from @@ -680,7 +693,7 @@ static int adau1701_probe(struct snd_soc_codec *codec) /* initalize with pre-configured pll mode settings */ ret = adau1701_reset(codec, adau1701->pll_clkdiv, 0); if (ret < 0) - return ret; + goto exit_regulators_disable; /* set up pin config */ val = 0; @@ -696,10 +709,60 @@ static int adau1701_probe(struct snd_soc_codec *codec) regmap_write(adau1701->regmap, ADAU1701_PINCONF_1, val); return 0; + +exit_regulators_disable: + + regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies); + return ret; } +static int adau1701_remove(struct snd_soc_codec *codec) +{ + struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); + + if (gpio_is_valid(adau1701->gpio_nreset)) + gpio_set_value_cansleep(adau1701->gpio_nreset, 0); + + regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies); + + return 0; +} + +#ifdef CONFIG_PM +static int adau1701_suspend(struct snd_soc_codec *codec) +{ + struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); + + regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), + adau1701->supplies); + + return 0; +} + +static int adau1701_resume(struct snd_soc_codec *codec) +{ + struct adau1701 *adau1701 = snd_soc_codec_get_drvdata(codec); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies), + adau1701->supplies); + if (ret < 0) { + dev_err(codec->dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + + return adau1701_reset(codec, adau1701->pll_clkdiv, 0); +} +#else +#define adau1701_resume NULL +#define adau1701_suspend NULL +#endif /* CONFIG_PM */ + static struct snd_soc_codec_driver adau1701_codec_drv = { .probe = adau1701_probe, + .remove = adau1701_remove, + .resume = adau1701_resume, + .suspend = adau1701_suspend, .set_bias_level = adau1701_set_bias_level, .idle_bias_off = true, @@ -730,32 +793,58 @@ static int adau1701_i2c_probe(struct i2c_client *client, struct device *dev = &client->dev; int gpio_nreset = -EINVAL; int gpio_pll_mode[2] = { -EINVAL, -EINVAL }; - int ret; + int ret, i; adau1701 = devm_kzalloc(dev, sizeof(*adau1701), GFP_KERNEL); if (!adau1701) return -ENOMEM; + for (i = 0; i < ARRAY_SIZE(supply_names); i++) + adau1701->supplies[i].supply = supply_names[i]; + + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(adau1701->supplies), + adau1701->supplies); + if (ret < 0) { + dev_err(dev, "Failed to get regulators: %d\n", ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(adau1701->supplies), + adau1701->supplies); + if (ret < 0) { + dev_err(dev, "Failed to enable regulators: %d\n", ret); + return ret; + } + adau1701->client = client; adau1701->regmap = devm_regmap_init(dev, NULL, client, &adau1701_regmap); - if (IS_ERR(adau1701->regmap)) - return PTR_ERR(adau1701->regmap); + if (IS_ERR(adau1701->regmap)) { + ret = PTR_ERR(adau1701->regmap); + goto exit_regulators_disable; + } + if (dev->of_node) { gpio_nreset = of_get_named_gpio(dev->of_node, "reset-gpio", 0); - if (gpio_nreset < 0 && gpio_nreset != -ENOENT) - return gpio_nreset; + if (gpio_nreset < 0 && gpio_nreset != -ENOENT) { + ret = gpio_nreset; + goto exit_regulators_disable; + } gpio_pll_mode[0] = of_get_named_gpio(dev->of_node, "adi,pll-mode-gpios", 0); - if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT) - return gpio_pll_mode[0]; + if (gpio_pll_mode[0] < 0 && gpio_pll_mode[0] != -ENOENT) { + ret = gpio_pll_mode[0]; + goto exit_regulators_disable; + } gpio_pll_mode[1] = of_get_named_gpio(dev->of_node, "adi,pll-mode-gpios", 1); - if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT) - return gpio_pll_mode[1]; + if (gpio_pll_mode[1] < 0 && gpio_pll_mode[1] != -ENOENT) { + ret = gpio_pll_mode[1]; + goto exit_regulators_disable; + } of_property_read_u32(dev->of_node, "adi,pll-clkdiv", &adau1701->pll_clkdiv); @@ -769,7 +858,7 @@ static int adau1701_i2c_probe(struct i2c_client *client, ret = devm_gpio_request_one(dev, gpio_nreset, GPIOF_OUT_INIT_LOW, "ADAU1701 Reset"); if (ret < 0) - return ret; + goto exit_regulators_disable; } if (gpio_is_valid(gpio_pll_mode[0]) && @@ -778,13 +867,13 @@ static int adau1701_i2c_probe(struct i2c_client *client, GPIOF_OUT_INIT_LOW, "ADAU1701 PLL mode 0"); if (ret < 0) - return ret; + goto exit_regulators_disable; ret = devm_gpio_request_one(dev, gpio_pll_mode[1], GPIOF_OUT_INIT_LOW, "ADAU1701 PLL mode 1"); if (ret < 0) - return ret; + goto exit_regulators_disable; } adau1701->gpio_nreset = gpio_nreset; @@ -795,11 +884,17 @@ static int adau1701_i2c_probe(struct i2c_client *client, adau1701->sigmadsp = devm_sigmadsp_init_i2c(client, &adau1701_sigmadsp_ops, ADAU1701_FIRMWARE); - if (IS_ERR(adau1701->sigmadsp)) - return PTR_ERR(adau1701->sigmadsp); + if (IS_ERR(adau1701->sigmadsp)) { + ret = PTR_ERR(adau1701->sigmadsp); + goto exit_regulators_disable; + } ret = snd_soc_register_codec(&client->dev, &adau1701_codec_drv, &adau1701_dai, 1); + +exit_regulators_disable: + + regulator_bulk_disable(ARRAY_SIZE(adau1701->supplies), adau1701->supplies); return ret; }