Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp3116911ybl; Mon, 19 Aug 2019 12:29:43 -0700 (PDT) X-Google-Smtp-Source: APXvYqy5oduJKDtN+n2Myvvo2R5MJEW53x61AxkAWAA/CN9+X5oQsJBO4SO4ed0MzTtCXXNbP14Y X-Received: by 2002:a65:6891:: with SMTP id e17mr21912110pgt.305.1566242983129; Mon, 19 Aug 2019 12:29:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566242983; cv=none; d=google.com; s=arc-20160816; b=ooKhRgf3glTUUQFaJtA64zQ5v4qdYQaqHnSWjjVw2oJsjk3IUYmyn8N6Pwycd4vE95 eCF9nuRC/rHRIlvZAjBbpKd2XWqRmRjJfKvtNpf3Kj+5b5LGhX3eFIxjgxzJR6IcVsJb jgobCBvfeKg9n9t6TUEJ4pSgtGzDoPe1zerQ+xsK9AjswyK6s4CoiYZk0qeJayscGlDq owqMa+/qGx5yRIqlkxIVZKkLkh+GqnZfVaPzJCXBPL0HI88++p9WZ+VB5KMqZKkk1cGx FR2EBzYNYUv4/o4F/06XUNXNu/Nyb2nn0PcJU5DRDgARCAo2GGCF70OJarDmRZ5t4Q1o bRQg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=2xHdDO1l7ZiHJ3QCKnt/y0VOIa64usE18Z+M8SwPUOI=; b=fuWwulKgJvX+9BJC2g5jrpUdOHuxFKUM4fS36DRa+CT3pM50Aqie4nBYvzveRiKJ1o /MHqcjUlSx79CEVAepIkBdp636DxT6bP7OCEqrr+HsCrPRM1Srt44U3LTR9NJGyS94PG zP1edY1duYyjQCsHr/iJu5QD/k6kPy1jWD7PaeHGBYoAq+v2Dh8IVjdVkCSqkFw4x8IJ Ltn1ndFAZEHWfUg93KInoSi7n5PqM/vf0PfF6nPGnk3efMes0PTB+jgzVL0HovNpGuAM Sm1iDUoGfKUss6mabssT36kZ+6wgKo2sV3qUzQ/kZ6LUKVPExY3gkVHv3zsgl8hqSePN 7GUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=uYcrwy9I; 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=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x125si10422800pgx.332.2019.08.19.12.29.27; Mon, 19 Aug 2019 12:29:43 -0700 (PDT) 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=@kernel.org header.s=default header.b=uYcrwy9I; 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=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728909AbfHST1t (ORCPT + 99 others); Mon, 19 Aug 2019 15:27:49 -0400 Received: from mail.kernel.org ([198.145.29.99]:41696 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728625AbfHST0B (ORCPT ); Mon, 19 Aug 2019 15:26:01 -0400 Received: from localhost (lfbn-1-10718-76.w90-89.abo.wanadoo.fr [90.89.68.76]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id EDE4C22CF4; Mon, 19 Aug 2019 19:25:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1566242760; bh=9rMZb4q2bdfCTKfWemEGoIofP27WGA2FridZFPHSHiw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uYcrwy9IoELec7iFGPHMjohkhJGNmU7OevYiT4yqBATpGY+KPiJ2sGpjFduuqIaJl aPMGWlRWKCyuyEbLCUON3jhCSzb5Xqj9Ifo6Nt1S0SCN9G1nz4dd37j82N9qBS2Mb3 xYu+YMCkSOHGuRXK4aJoZp/xekbodE1ijTCNIv68= From: Maxime Ripard To: Chen-Yu Tsai , Maxime Ripard , lgirdwood@gmail.com, broonie@kernel.org Cc: alsa-devel@alsa-project.org, linux-arm-kernel@lists.infradead.org, codekipper@gmail.com, linux-kernel@vger.kernel.org Subject: [PATCH 09/21] ASoC: sun4i-i2s: Fix the MCLK and BCLK dividers on newer SoCs Date: Mon, 19 Aug 2019 21:25:16 +0200 Message-Id: <0e5b4abf06cd3202354315201c6af44caeb20236.1566242458.git-series.maxime.ripard@bootlin.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Maxime Ripard From: Marcus Cooper The clock division dividers have changed between the older (A10/A31) and newer (H3, A64, etc) SoCs. While this was addressed through an offset on some SoCs, it was missing some dividers as well, so the support wasn't perfect. Let's introduce a pointer in the quirk structure for the divider calculation functions to use so we can have the proper range now. Signed-off-by: Marcus Cooper [Maxime: Fix the commit log, use a field in the quirk structure] Signed-off-by: Maxime Ripard --- sound/soc/sunxi/sun4i-i2s.c | 63 +++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 14 deletions(-) diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c index 51be395102b2..8d49ee7d2a95 100644 --- a/sound/soc/sunxi/sun4i-i2s.c +++ b/sound/soc/sunxi/sun4i-i2s.c @@ -129,8 +129,6 @@ struct sun4i_i2s; * @has_fmt_set_lrck_period: SoC requires lrclk period to be set. * @reg_offset_txdata: offset of the tx fifo. * @sun4i_i2s_regmap: regmap config to use. - * @mclk_offset: Value by which mclkdiv needs to be adjusted. - * @bclk_offset: Value by which bclkdiv needs to be adjusted. * @field_clkdiv_mclk_en: regmap field to enable mclk output. * @field_fmt_wss: regmap field to set word select size. * @field_fmt_sr: regmap field to set sample resolution. @@ -142,8 +140,6 @@ struct sun4i_i2s_quirks { bool has_fmt_set_lrck_period; unsigned int reg_offset_txdata; /* TX FIFO */ const struct regmap_config *sun4i_i2s_regmap; - unsigned int mclk_offset; - unsigned int bclk_offset; /* Register fields for i2s */ struct reg_field field_clkdiv_mclk_en; @@ -152,6 +148,11 @@ struct sun4i_i2s_quirks { struct reg_field field_fmt_bclk; struct reg_field field_fmt_lrclk; + const struct sun4i_i2s_clk_div *bclk_dividers; + unsigned int num_bclk_dividers; + const struct sun4i_i2s_clk_div *mclk_dividers; + unsigned int num_mclk_dividers; + unsigned long (*get_bclk_parent_rate)(const struct sun4i_i2s *); s8 (*get_sr)(const struct sun4i_i2s *, int); s8 (*get_wss)(const struct sun4i_i2s *, int); @@ -208,6 +209,24 @@ static const struct sun4i_i2s_clk_div sun4i_i2s_mclk_div[] = { /* TODO - extend divide ratio supported by newer SoCs */ }; +static const struct sun4i_i2s_clk_div sun8i_i2s_clk_div[] = { + { .div = 1, .val = 1 }, + { .div = 2, .val = 2 }, + { .div = 4, .val = 3 }, + { .div = 6, .val = 4 }, + { .div = 8, .val = 5 }, + { .div = 12, .val = 6 }, + { .div = 16, .val = 7 }, + { .div = 24, .val = 8 }, + { .div = 32, .val = 9 }, + { .div = 48, .val = 10 }, + { .div = 64, .val = 11 }, + { .div = 96, .val = 12 }, + { .div = 128, .val = 13 }, + { .div = 176, .val = 14 }, + { .div = 192, .val = 15 }, +}; + static unsigned long sun4i_i2s_get_bclk_parent_rate(const struct sun4i_i2s *i2s) { return i2s->mclk_freq; @@ -223,11 +242,12 @@ static int sun4i_i2s_get_bclk_div(struct sun4i_i2s *i2s, unsigned int sampling_rate, unsigned int word_size) { + const struct sun4i_i2s_clk_div *dividers = i2s->variant->bclk_dividers; int div = parent_rate / sampling_rate / word_size / 2; int i; - for (i = 0; i < ARRAY_SIZE(sun4i_i2s_bclk_div); i++) { - const struct sun4i_i2s_clk_div *bdiv = &sun4i_i2s_bclk_div[i]; + for (i = 0; i < i2s->variant->num_bclk_dividers; i++) { + const struct sun4i_i2s_clk_div *bdiv = ÷rs[i]; if (bdiv->div == div) return bdiv->val; @@ -240,11 +260,12 @@ static int sun4i_i2s_get_mclk_div(struct sun4i_i2s *i2s, unsigned long parent_rate, unsigned long mclk_rate) { + const struct sun4i_i2s_clk_div *dividers = i2s->variant->mclk_dividers; int div = parent_rate / mclk_rate; int i; - for (i = 0; i < ARRAY_SIZE(sun4i_i2s_mclk_div); i++) { - const struct sun4i_i2s_clk_div *mdiv = &sun4i_i2s_mclk_div[i]; + for (i = 0; i < i2s->variant->num_mclk_dividers; i++) { + const struct sun4i_i2s_clk_div *mdiv = ÷rs[i]; if (mdiv->div == div) return mdiv->val; @@ -326,10 +347,6 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai, return -EINVAL; } - /* Adjust the clock division values if needed */ - bclk_div += i2s->variant->bclk_offset; - mclk_div += i2s->variant->mclk_offset; - regmap_write(i2s->regmap, SUN4I_I2S_CLK_DIV_REG, SUN4I_I2S_CLK_DIV_BCLK(bclk_div) | SUN4I_I2S_CLK_DIV_MCLK(mclk_div)); @@ -969,6 +986,10 @@ static const struct sun4i_i2s_quirks sun4i_a10_i2s_quirks = { .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .bclk_dividers = sun4i_i2s_bclk_div, + .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div), + .mclk_dividers = sun4i_i2s_mclk_div, + .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div), .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate, .get_sr = sun4i_i2s_get_sr, .get_wss = sun4i_i2s_get_wss, @@ -985,6 +1006,10 @@ static const struct sun4i_i2s_quirks sun6i_a31_i2s_quirks = { .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .bclk_dividers = sun4i_i2s_bclk_div, + .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div), + .mclk_dividers = sun4i_i2s_mclk_div, + .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div), .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate, .get_sr = sun4i_i2s_get_sr, .get_wss = sun4i_i2s_get_wss, @@ -1001,6 +1026,10 @@ static const struct sun4i_i2s_quirks sun8i_a83t_i2s_quirks = { .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .bclk_dividers = sun8i_i2s_clk_div, + .num_bclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div), + .mclk_dividers = sun8i_i2s_clk_div, + .num_mclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div), .get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate, .get_sr = sun8i_i2s_get_sr_wss, .get_wss = sun8i_i2s_get_sr_wss, @@ -1012,14 +1041,16 @@ static const struct sun4i_i2s_quirks sun8i_h3_i2s_quirks = { .has_reset = true, .reg_offset_txdata = SUN8I_I2S_FIFO_TX_REG, .sun4i_i2s_regmap = &sun8i_i2s_regmap_config, - .mclk_offset = 1, - .bclk_offset = 2, .has_fmt_set_lrck_period = true, .field_clkdiv_mclk_en = REG_FIELD(SUN4I_I2S_CLK_DIV_REG, 8, 8), .field_fmt_wss = REG_FIELD(SUN4I_I2S_FMT0_REG, 0, 2), .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 6), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 19, 19), + .bclk_dividers = sun8i_i2s_clk_div, + .num_bclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div), + .mclk_dividers = sun8i_i2s_clk_div, + .num_mclk_dividers = ARRAY_SIZE(sun8i_i2s_clk_div), .get_bclk_parent_rate = sun8i_i2s_get_bclk_parent_rate, .get_sr = sun8i_i2s_get_sr_wss, .get_wss = sun8i_i2s_get_sr_wss, @@ -1036,6 +1067,10 @@ static const struct sun4i_i2s_quirks sun50i_a64_codec_i2s_quirks = { .field_fmt_sr = REG_FIELD(SUN4I_I2S_FMT0_REG, 4, 5), .field_fmt_bclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 6, 6), .field_fmt_lrclk = REG_FIELD(SUN4I_I2S_FMT0_REG, 7, 7), + .bclk_dividers = sun4i_i2s_bclk_div, + .num_bclk_dividers = ARRAY_SIZE(sun4i_i2s_bclk_div), + .mclk_dividers = sun4i_i2s_mclk_div, + .num_mclk_dividers = ARRAY_SIZE(sun4i_i2s_mclk_div), .get_bclk_parent_rate = sun4i_i2s_get_bclk_parent_rate, .get_sr = sun4i_i2s_get_sr, .get_wss = sun4i_i2s_get_wss, -- git-series 0.9.1