From patchwork Tue Jul 30 10:18:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Russell King X-Patchwork-Id: 2835475 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id EA4F39F9C8 for ; Tue, 30 Jul 2013 10:22:15 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id DB73E20362 for ; Tue, 30 Jul 2013 10:22:14 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6B62F20347 for ; Tue, 30 Jul 2013 10:22:13 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V474B-0007xP-BC; Tue, 30 Jul 2013 10:22:07 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1V4748-0000a4-VV; Tue, 30 Jul 2013 10:22:04 +0000 Received: from caramon.arm.linux.org.uk ([78.32.30.218]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1V4742-0000V0-Ax for linux-arm-kernel@lists.infradead.org; Tue, 30 Jul 2013 10:22:02 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=arm.linux.org.uk; s=caramon; h=Date:Sender:Message-Id:Subject:Cc:To:From; bh=JveqWUJIftNPemAxvxmOuta+ZwSOQ8TCuE9ZwM8CIEY=; b=iRfsJQOKPX4nHR0yHYMaUux68OsiKpfhAjfTadsC6ycZuIL+nguCV1wgM8CKM0U8nT/k7GU3uHgJgPcfc/B0QH+jSAV7g+sVNLB1gT4WMxnDNwOFGblu8FVbtVOQCBds2A9MSi7haHdqboWHC8y7JzRV7M0pK/frAk3vQEPSjP4=; Received: from e0022681537dd.dyn.arm.linux.org.uk ([2002:4e20:1eda:1:222:68ff:fe15:37dd]:35575 helo=rmk-PC.arm.linux.org.uk) by caramon.arm.linux.org.uk with esmtpsa (TLSv1:AES256-SHA:256) (Exim 4.76) (envelope-from ) id 1V4713-0006Ah-0k; Tue, 30 Jul 2013 11:18:53 +0100 Received: from rmk by rmk-PC.arm.linux.org.uk with local (Exim 4.76) (envelope-from ) id 1V4712-0007sg-Dw; Tue, 30 Jul 2013 11:18:52 +0100 From: Russell King To: linux-arm-kernel@lists.infradead.org, alsa-devel@alsa-project.org, Mark Brown Subject: [PATCH] ALSA: ASoC: uda134x: fix codec driver Message-Id: Date: Tue, 30 Jul 2013 11:18:52 +0100 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130730_062201_010711_655ABF7E X-CRM114-Status: GOOD ( 19.59 ) X-Spam-Score: -5.8 (-----) Cc: Takashi Iwai , Liam Girdwood , Jaroslav Kysela X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.6 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP For some reason, the DAC/ADCs are not being powered up when I try and use the UDA1341 driver; this used to work. Looking back in the git history, I don't see anything obvious which would cause this regression. However, from dumping the register writes, it seems that the codec is powered down, and nothing calls set_bias_level to wake the codec up. Moreover, this driver hasn't had DAPM support added to it, which prevents platform drivers from taking advantage of DAPMs facilities. So, let's add DAPM support to the driver. As we move the power control for the DAC/ADC into DAPM, we no longer need it in set_bias_level() - this function just becomes a way to manipulate the power control and sync the register cache with the hardware at the appropriate point. Signed-off-by: Russell King --- I noticed this while checking the Assabet audio, which uses the UDA1341. I've also added the corresponding support to my Assabet audio driver. If this looks like the correct thing to do to fix this, please apply. sound/soc/codecs/uda134x.c | 88 ++++++++++++++++++++++++++----------------- 1 files changed, 53 insertions(+), 35 deletions(-) diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 6d0aa44..c94d4c1 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -325,7 +325,6 @@ static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai, static int uda134x_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u8 reg; struct uda134x_platform_data *pd = codec->control_data; int i; u8 *cache = codec->reg_cache; @@ -334,23 +333,6 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec, switch (level) { case SND_SOC_BIAS_ON: - /* ADC, DAC on */ - switch (pd->model) { - case UDA134X_UDA1340: - case UDA134X_UDA1344: - case UDA134X_UDA1345: - reg = uda134x_read_reg_cache(codec, UDA134X_DATA011); - uda134x_write(codec, UDA134X_DATA011, reg | 0x03); - break; - case UDA134X_UDA1341: - reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1); - uda134x_write(codec, UDA134X_STATUS1, reg | 0x03); - break; - default: - printk(KERN_ERR "UDA134X SoC codec: " - "unsupported model %d\n", pd->model); - return -EINVAL; - } break; case SND_SOC_BIAS_PREPARE: /* power on */ @@ -362,23 +344,6 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec, } break; case SND_SOC_BIAS_STANDBY: - /* ADC, DAC power off */ - switch (pd->model) { - case UDA134X_UDA1340: - case UDA134X_UDA1344: - case UDA134X_UDA1345: - reg = uda134x_read_reg_cache(codec, UDA134X_DATA011); - uda134x_write(codec, UDA134X_DATA011, reg & ~(0x03)); - break; - case UDA134X_UDA1341: - reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1); - uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03)); - break; - default: - printk(KERN_ERR "UDA134X SoC codec: " - "unsupported model %d\n", pd->model); - return -EINVAL; - } break; case SND_SOC_BIAS_OFF: /* power off */ @@ -450,6 +415,37 @@ SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]), SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0), }; +/* UDA1341 has the DAC/ADC power down in STATUS1 */ +static const struct snd_soc_dapm_widget uda1341_dapm_widgets[] = { + SND_SOC_DAPM_DAC("DAC", "Playback", UDA134X_STATUS1, 0, 0), + SND_SOC_DAPM_ADC("ADC", "Capture", UDA134X_STATUS1, 1, 0), +}; + +/* UDA1340/4/5 has the DAC/ADC pwoer down in DATA0 11 */ +static const struct snd_soc_dapm_widget uda1340_dapm_widgets[] = { + SND_SOC_DAPM_DAC("DAC", "Playback", UDA134X_DATA011, 0, 0), + SND_SOC_DAPM_ADC("ADC", "Capture", UDA134X_DATA011, 1, 0), +}; + +/* Common DAPM widgets */ +static const struct snd_soc_dapm_widget uda134x_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("VINL1"), + SND_SOC_DAPM_INPUT("VINR1"), + SND_SOC_DAPM_INPUT("VINL2"), + SND_SOC_DAPM_INPUT("VINR2"), + SND_SOC_DAPM_OUTPUT("VOUTL"), + SND_SOC_DAPM_OUTPUT("VOUTR"), +}; + +static const struct snd_soc_dapm_route uda134x_dapm_routes[] = { + { "ADC", NULL, "VINL1" }, + { "ADC", NULL, "VINR1" }, + { "ADC", NULL, "VINL2" }, + { "ADC", NULL, "VINR2" }, + { "VOUTL", NULL, "DAC" }, + { "VOUTR", NULL, "DAC" }, +}; + static const struct snd_soc_dai_ops uda134x_dai_ops = { .startup = uda134x_startup, .shutdown = uda134x_shutdown, @@ -485,6 +481,8 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) { struct uda134x_priv *uda134x; struct uda134x_platform_data *pd = codec->card->dev->platform_data; + const struct snd_soc_dapm_widget *widgets; + unsigned num_widgets; int ret; @@ -526,6 +524,22 @@ static int uda134x_soc_probe(struct snd_soc_codec *codec) else uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + if (pd->model == UDA134X_UDA1341) { + widgets = uda1341_dapm_widgets; + num_widgets = ARRAY_SIZE(uda1341_dapm_widgets); + } else { + widgets = uda1340_dapm_widgets; + num_widgets = ARRAY_SIZE(uda1340_dapm_widgets); + } + + ret = snd_soc_dapm_new_controls(&codec->dapm, widgets, num_widgets); + if (ret) { + printk(KERN_ERR "%s failed to register dapm controls: %d", + __func__, ret); + kfree(uda134x); + return ret; + } + switch (pd->model) { case UDA134X_UDA1340: case UDA134X_UDA1344: @@ -599,6 +613,10 @@ static struct snd_soc_codec_driver soc_codec_dev_uda134x = { .read = uda134x_read_reg_cache, .write = uda134x_write, .set_bias_level = uda134x_set_bias_level, + .dapm_widgets = uda134x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(uda134x_dapm_widgets), + .dapm_routes = uda134x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(uda134x_dapm_routes), }; static int uda134x_codec_probe(struct platform_device *pdev)