From patchwork Thu Nov 9 09:39:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxime Ripard X-Patchwork-Id: 118420 Delivered-To: patch@linaro.org Received: by 10.140.22.164 with SMTP id 33csp6368169qgn; Thu, 9 Nov 2017 01:41:59 -0800 (PST) X-Google-Smtp-Source: ABhQp+QZvjov+5OE7oGXoRTjYL6ssFRvmixpH9Y6uqZDXYOERWl/Tk/yI/g0QvllraFkxCzOm5GV X-Received: by 10.84.134.34 with SMTP id 31mr3330935plg.154.1510220519915; Thu, 09 Nov 2017 01:41:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1510220519; cv=none; d=google.com; s=arc-20160816; b=lsHDox0ThZH4B4vZjBPf3HUbSDTuzH+7M1NRXvZYGHVidU+3Llz+6tyVNcsYNZZuEb WED7dJ5vZA8BF1eOJbs5nMvpJvdI9HIOMs+JOAaIl5CqSEm+VXBARFFyqV4Zw1KcoHol zJ6mEFXyt0XctJoj0gHlmsrR/FBYTFzmaCgMXaGaXaCnx4h253Te6BjLio43uVwEJiSb 84iir5LRTf1QaFw2iRH5FSDHKHiPyPGvKKIAY2TanWt2O8JM/vfIOGBtbIOffVeBVrJV LI/3jXbmPTrBBkj2RIt47PBePxSBPAtYem7h3LtSJ6F9Oa06kmxaPs2jzDzSz7k6WdVa kh7g== 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 :arc-authentication-results; bh=RtZI3Rc1VF7q0nTJnmsH7W63tW4Ra0YCFcPJRBWz4h4=; b=zJ2jZGLm45eXTcHS7hT1NlLISGKvVqMW9IlnzMFi20Pn8OKD9oabcwpuq8Av2kh8r3 vlOdYWvlC2ndXWJ+PfKzqTKnBEcrYyPVK85eH4JDTUzKUbhQAvJluAhqm0KthyDOv/2l JQemQql8Q98878GHgDZbbmT/TE7xetY5s0ttHUPabDIpru0oczvDquh9OyzzrFGdr69V fIGGyiKY9DkjBQf614tOBDa81j+xkIaXwQJFK7wN+7roymCKb0697G6eosU/ZdssvrNL F2no4Ez9jttSkG1sFEFWANsltq3iNEMRPff4kNS0IU9tlm6jzDRqSdAVPIKJOUgvGcA7 abFA== 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 x4si5695679pln.635.2017.11.09.01.41.59; Thu, 09 Nov 2017 01:41:59 -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 S1753089AbdKIJjq (ORCPT + 9 others); Thu, 9 Nov 2017 04:39:46 -0500 Received: from mail.free-electrons.com ([62.4.15.54]:35428 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751190AbdKIJjh (ORCPT ); Thu, 9 Nov 2017 04:39:37 -0500 Received: by mail.free-electrons.com (Postfix, from userid 110) id 59002208C0; Thu, 9 Nov 2017 10:39:35 +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 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 243BD20390; Thu, 9 Nov 2017 10:39:25 +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, stable@vger.kernel.org Subject: [PATCH v2] ASoC: sun8i-codec: Set the BCLK divider Date: Thu, 9 Nov 2017 10:39:24 +0100 Message-Id: <20171109093924.12803-1-maxime.ripard@free-electrons.com> X-Mailer: git-send-email 2.14.3 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: Reviewed-by: Chen-Yu Tsai Signed-off-by: Maxime Ripard --- Changes from v1: - Hardcoded the bit width to remain consistent with the rest of the driver --- sound/soc/sunxi/sun8i-codec.c | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) -- 2.14.3 diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index c2ceca485d6a..7a312168f864 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,11 @@ 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), 16); + 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);