From patchwork Wed Nov 8 15:47:09 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 118285 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp5448605qgn; Wed, 8 Nov 2017 07:47:26 -0800 (PST) X-Google-Smtp-Source: ABhQp+TddvqHFein4w+QB7wZvrXuTGJWmtC53A60q2zZntxNktJrYqg5erTQPuo9f4Y7XkZ6bf75 X-Received: by 10.101.100.24 with SMTP id a24mr900775pgv.316.1510156046279; Wed, 08 Nov 2017 07:47:26 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510156046; cv=none; d=google.com; s=arc-20160816; b=1DKDjjwOD67tokFMe1Zqwtijk1JzPa6jVXDSKz7nim3jADw3ibmjn7GOl9kRJFu2RB tz0rciMiiSMkZMrfig/1W5wdjDy+OZMcNobxUbZQfBU8qbVGC9D7uijdGoDbBIP+of/+ UnnrinAMNlvp4CSqXqq6Clgm2p6UZyE0qKFRSKOf6+JJT8SFpokhTGWSQoUe5708CtmN 26lfv8e4ByfBoGKt1wYDfa51a0cI6vANRUGZTJTicIECGIVvt3g8cU14n/T1tZ9dXex4 1GDYoI8qZhXE48/iKg1CI0tHOocMnlT9KxkNiignN7cexQyLD4aGt7yz2eo5r173At7t xUUQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=tO3aKou+3UZ5gXuM0NtVRJsCUhGBKMKpQxE88gb3rFw=; b=sMx5lr1EpIYn6iorE4iUeizoINvJwGRl6eNw+LgGAnL1SQeL0ZoulK9AMcGjFFIPtp 9CZSxa7oHQtoWyrpoGFB7VvcHLgxgLpZUg5TAOmtpHYXtnF/kb6lmOfaaVCLqSc8zds7 LfktvBOZB0sxFdSWdhrZF+T5KBE+YiWwZYem2PC2809TMotv7ce1zNIqyEPe49h7DOlQ PNfWGl1gsUlB9RoD9/PyOeVH6/fgu/MxU7y8pLqD/8sef8H/o3f+LMgTl9gDDpTuRYB0 HZh3OUITjyP0yf7bxXsvghQk+bxDMGY648AGAV9/upKskZ7i5WmO5YPDgUQOSoVOh5A+ +Flg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m6si4025896pgu.691.2017.11.08.07.47.24; Wed, 08 Nov 2017 07:47:26 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752692AbdKHPrX (ORCPT + 9 others); Wed, 8 Nov 2017 10:47:23 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:44589 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752690AbdKHPrU (ORCPT ); Wed, 8 Nov 2017 10:47:20 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id D14FC208CF; Wed, 8 Nov 2017 16:47:18 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.free-electrons.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT, URIBL_BLOCKED shortcircuit=ham autolearn=disabled version=3.4.0 Received: from localhost (LStLambert-657-1-97-87.w90-63.abo.wanadoo.fr [90.63.216.87]) by mail.free-electrons.com (Postfix) with ESMTPSA id A68C62068C; Wed, 8 Nov 2017 16:47:18 +0100 (CET) From: Maxime Ripard To: broonie@kernel.org, lgirdwood@gmail.com, Chen-Yu Tsai , Maxime Ripard Cc: Mylene Josserand , linux-arm-kernel@lists.infradead.org, alsa-devel@alsa-project.org, Thomas Petazzoni , codekipper@gmail.com, stable@vger.kernel.org Subject: [PATCH 2/3] ASoC: sun8i-codec: Set the BCLK divider Date: Wed, 8 Nov 2017 16:47:09 +0100 Message-Id: <20171108154710.16407-3-maxime.ripard@free-electrons.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20171108154710.16407-1-maxime.ripard@free-electrons.com> References: <20171108154710.16407-1-maxime.ripard@free-electrons.com> Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org While the current code was reporting to be able to work in master mode, it failed to do so because the BCLK divider wasn't programmed, meaning that the BCLK would run at the PLL's frequency no matter the sample rate. It was obviously a bit too fast. Add support to retrieve the divider to use, and set it. Since our PLL is not always able to generate a perfect multiple of the sample rate, we'll have to choose the closest divider that matches our setup. Fixes: 36c684936fae ("ASoC: Add sun8i digital audio codec") Cc: Signed-off-by: Maxime Ripard --- sound/soc/sunxi/sun8i-codec.c | 53 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) -- 2.14.3 Reviewed-by: Chen-Yu Tsai diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 038107baf414..522546e6b153 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -73,6 +73,7 @@ #define SUN8I_SYS_SR_CTRL_AIF2_FS_MASK GENMASK(11, 8) #define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_MASK GENMASK(5, 4) #define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK GENMASK(8, 6) +#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK GENMASK(12, 9) struct sun8i_codec { struct device *dev; @@ -226,12 +227,57 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return 0; } +struct sun8i_codec_clk_div { + u8 div; + u8 val; +}; + +static const struct sun8i_codec_clk_div sun8i_codec_bclk_div[] = { + { .div = 1, .val = 0 }, + { .div = 2, .val = 1 }, + { .div = 4, .val = 2 }, + { .div = 6, .val = 3 }, + { .div = 8, .val = 4 }, + { .div = 12, .val = 5 }, + { .div = 16, .val = 6 }, + { .div = 24, .val = 7 }, + { .div = 32, .val = 8 }, + { .div = 48, .val = 9 }, + { .div = 64, .val = 10 }, + { .div = 96, .val = 11 }, + { .div = 128, .val = 12 }, + { .div = 192, .val = 13 }, +}; + +static u8 sun8i_codec_get_bclk_div(struct sun8i_codec *scodec, + unsigned int rate, + unsigned int word_size) +{ + unsigned long clk_rate = clk_get_rate(scodec->clk_module); + unsigned int div = clk_rate / rate / word_size / 2; + unsigned int best_val = 0, best_diff = ~0; + int i; + + for (i = 0; i < ARRAY_SIZE(sun8i_codec_bclk_div); i++) { + const struct sun8i_codec_clk_div *bdiv = &sun8i_codec_bclk_div[i]; + unsigned int diff = abs(bdiv->div - div); + + if (diff < best_diff) { + best_diff = diff; + best_val = bdiv->val; + } + } + + return best_val; +} + static int sun8i_codec_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct sun8i_codec *scodec = snd_soc_codec_get_drvdata(dai->codec); int sample_rate; + u8 bclk_div; /* * The CPU DAI handles only a sample of 16 bits. Configure the @@ -241,6 +287,13 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream, SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_MASK, SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_16); + bclk_div = sun8i_codec_get_bclk_div(scodec, params_rate(params), + params_width(params)); + + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL, + SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK, + bclk_div << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV); + regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL, SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK, SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_16);