All of lore.kernel.org
 help / color / mirror / Atom feed
From: Charles Keepax <ckeepax@opensource.cirrus.com>
To: <broonie@kernel.org>
Cc: patches@opensource.cirrus.com, alsa-devel@alsa-project.org,
	james.schulman@cirrus.com, lgirdwood@gmail.com,
	david.rhodes@cirrus.com
Subject: [PATCH 3/6] ASoC: cs35l41: Combine adjacent register writes
Date: Tue, 14 Sep 2021 15:13:46 +0100	[thread overview]
Message-ID: <20210914141349.30218-3-ckeepax@opensource.cirrus.com> (raw)
In-Reply-To: <20210914141349.30218-1-ckeepax@opensource.cirrus.com>

cs35l41 is often connected over I2C which is a very slow bus, as such
timings can be greatly improved combining writes where acceptable.
Update several points where the driver does multiple register writes
when a single one would suffice.

Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
---
 sound/soc/codecs/cs35l41.c | 146 +++++++++++++++------------------------------
 sound/soc/codecs/cs35l41.h |   1 +
 2 files changed, 49 insertions(+), 98 deletions(-)

diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
index 8c2c695813cd7..ce652a454dfc8 100644
--- a/sound/soc/codecs/cs35l41.c
+++ b/sound/soc/codecs/cs35l41.c
@@ -712,24 +712,29 @@ static int cs35l41_set_channel_map(struct snd_soc_dai *dai, unsigned int tx_num,
 {
 	struct cs35l41_private *cs35l41 =
 			snd_soc_component_get_drvdata(dai->component);
+	unsigned int val, mask;
 	int i;
 
 	if (tx_num > 4 || rx_num > 2)
 		return -EINVAL;
 
+	val = 0;
+	mask = 0;
 	for (i = 0; i < rx_num; i++) {
-		dev_dbg(cs35l41->dev, "%s: rx slot %d position = %d\n",
-				__func__, i, rx_slot[i]);
-		regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT,
-				0x3F << (i * 8), rx_slot[i] << (i * 8));
+		dev_dbg(cs35l41->dev, "rx slot %d position = %d\n", i, rx_slot[i]);
+		val |= rx_slot[i] << (i * 8);
+		mask |= 0x3F << (i * 8);
 	}
+	regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_RX_SLOT, mask, val);
 
+	val = 0;
+	mask = 0;
 	for (i = 0; i < tx_num; i++) {
-		dev_dbg(cs35l41->dev, "%s: tx slot %d position = %d\n",
-				__func__, i, tx_slot[i]);
-		regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT,
-				0x3F << (i * 8), tx_slot[i] << (i * 8));
+		dev_dbg(cs35l41->dev, "tx slot %d position = %d\n", i, tx_slot[i]);
+		val |= tx_slot[i] << (i * 8);
+		mask |= 0x3F << (i * 8);
 	}
+	regmap_update_bits(cs35l41->regmap, CS35L41_SP_FRAME_TX_SLOT, mask, val);
 
 	return 0;
 }
@@ -738,14 +743,13 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 {
 	struct cs35l41_private *cs35l41 =
 			snd_soc_component_get_drvdata(codec_dai->component);
-	unsigned int asp_fmt, lrclk_fmt, sclk_fmt, clock_provider;
+	unsigned int daifmt = 0;
 
 	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
 	case SND_SOC_DAIFMT_CBP_CFP:
-		clock_provider = 1;
+		daifmt |= CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK;
 		break;
 	case SND_SOC_DAIFMT_CBC_CFC:
-		clock_provider = 0;
 		break;
 	default:
 		dev_warn(cs35l41->dev,
@@ -754,19 +758,11 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
-				CS35L41_SCLK_MSTR_MASK,
-				clock_provider << CS35L41_SCLK_MSTR_SHIFT);
-	regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
-				CS35L41_LRCLK_MSTR_MASK,
-				clock_provider << CS35L41_LRCLK_MSTR_SHIFT);
-
 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
 	case SND_SOC_DAIFMT_DSP_A:
-		asp_fmt = 0;
 		break;
 	case SND_SOC_DAIFMT_I2S:
-		asp_fmt = 2;
+		daifmt |= 2 << CS35L41_ASP_FMT_SHIFT;
 		break;
 	default:
 		dev_warn(cs35l41->dev,
@@ -774,26 +770,17 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
-					CS35L41_ASP_FMT_MASK,
-					asp_fmt << CS35L41_ASP_FMT_SHIFT);
-
 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
 	case SND_SOC_DAIFMT_NB_IF:
-		lrclk_fmt = 1;
-		sclk_fmt = 0;
+		daifmt |= CS35L41_LRCLK_INV_MASK;
 		break;
 	case SND_SOC_DAIFMT_IB_NF:
-		lrclk_fmt = 0;
-		sclk_fmt = 1;
+		daifmt |= CS35L41_SCLK_INV_MASK;
 		break;
 	case SND_SOC_DAIFMT_IB_IF:
-		lrclk_fmt = 1;
-		sclk_fmt = 1;
+		daifmt |= CS35L41_LRCLK_INV_MASK | CS35L41_SCLK_INV_MASK;
 		break;
 	case SND_SOC_DAIFMT_NB_NF:
-		lrclk_fmt = 0;
-		sclk_fmt = 0;
 		break;
 	default:
 		dev_warn(cs35l41->dev,
@@ -801,14 +788,10 @@ static int cs35l41_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
 		return -EINVAL;
 	}
 
-	regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
-				CS35L41_LRCLK_INV_MASK,
-				lrclk_fmt << CS35L41_LRCLK_INV_SHIFT);
-	regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
-				CS35L41_SCLK_INV_MASK,
-				sclk_fmt << CS35L41_SCLK_INV_SHIFT);
-
-	return 0;
+	return regmap_update_bits(cs35l41->regmap, CS35L41_SP_FORMAT,
+				  CS35L41_SCLK_MSTR_MASK | CS35L41_LRCLK_MSTR_MASK |
+				  CS35L41_ASP_FMT_MASK | CS35L41_LRCLK_INV_MASK |
+				  CS35L41_SCLK_INV_MASK, daifmt);
 }
 
 struct cs35l41_global_fs_config {
@@ -1041,37 +1024,23 @@ static int cs35l41_boost_config(struct cs35l41_private *cs35l41,
 	}
 
 	ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF,
-			CS35L41_BST_K1_MASK,
-			cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range]
-				<< CS35L41_BST_K1_SHIFT);
-	if (ret) {
-		dev_err(dev, "Failed to write boost K1 coefficient\n");
-		return ret;
-	}
-
-	ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF,
-			CS35L41_BST_K2_MASK,
-			cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range]
-				<< CS35L41_BST_K2_SHIFT);
-	if (ret) {
-		dev_err(dev, "Failed to write boost K2 coefficient\n");
-		return ret;
-	}
-
-	ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST,
-			CS35L41_BST_SLOPE_MASK,
-			cs35l41_bst_slope_table[bst_lbst_val]
-				<< CS35L41_BST_SLOPE_SHIFT);
+				 CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK,
+				 cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range]
+					<< CS35L41_BST_K1_SHIFT |
+				 cs35l41_bst_k2_table[bst_lbst_val][bst_cbst_range]
+					<< CS35L41_BST_K2_SHIFT);
 	if (ret) {
-		dev_err(dev, "Failed to write boost slope coefficient\n");
+		dev_err(dev, "Failed to write boost coefficients: %d\n", ret);
 		return ret;
 	}
 
 	ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_SLOPE_LBST,
-			CS35L41_BST_LBST_VAL_MASK,
-			bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT);
+				 CS35L41_BST_SLOPE_MASK | CS35L41_BST_LBST_VAL_MASK,
+				 cs35l41_bst_slope_table[bst_lbst_val]
+					<< CS35L41_BST_SLOPE_SHIFT |
+				 bst_lbst_val << CS35L41_BST_LBST_VAL_SHIFT);
 	if (ret) {
-		dev_err(dev, "Failed to write boost inductor value\n");
+		dev_err(dev, "Failed to write boost slope/inductor value: %d\n", ret);
 		return ret;
 	}
 
@@ -1129,39 +1098,20 @@ static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41)
 	struct cs35l41_irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2;
 	int irq_pol = IRQF_TRIGGER_NONE;
 
-	if (irq_gpio_cfg1->irq_pol_inv)
-		regmap_update_bits(cs35l41->regmap,
-					CS35L41_GPIO1_CTRL1,
-					CS35L41_GPIO_POL_MASK,
-					CS35L41_GPIO_POL_MASK);
-	if (irq_gpio_cfg1->irq_out_en)
-		regmap_update_bits(cs35l41->regmap,
-					CS35L41_GPIO1_CTRL1,
-					CS35L41_GPIO_DIR_MASK,
-					0);
-	if (irq_gpio_cfg1->irq_src_sel)
-		regmap_update_bits(cs35l41->regmap,
-					CS35L41_GPIO_PAD_CONTROL,
-					CS35L41_GPIO1_CTRL_MASK,
-					irq_gpio_cfg1->irq_src_sel <<
-					CS35L41_GPIO1_CTRL_SHIFT);
-
-	if (irq_gpio_cfg2->irq_pol_inv)
-		regmap_update_bits(cs35l41->regmap,
-					CS35L41_GPIO2_CTRL1,
-					CS35L41_GPIO_POL_MASK,
-					CS35L41_GPIO_POL_MASK);
-	if (irq_gpio_cfg2->irq_out_en)
-		regmap_update_bits(cs35l41->regmap,
-					CS35L41_GPIO2_CTRL1,
-					CS35L41_GPIO_DIR_MASK,
-					0);
-	if (irq_gpio_cfg2->irq_src_sel)
-		regmap_update_bits(cs35l41->regmap,
-					CS35L41_GPIO_PAD_CONTROL,
-					CS35L41_GPIO2_CTRL_MASK,
-					irq_gpio_cfg2->irq_src_sel <<
-					CS35L41_GPIO2_CTRL_SHIFT);
+	regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1,
+			   CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
+			   irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT |
+			   !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT);
+
+	regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1,
+			   CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
+			   irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT |
+			   !irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT);
+
+	regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
+			   CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK,
+			   irq_gpio_cfg1->irq_src_sel << CS35L41_GPIO1_CTRL_SHIFT |
+			   irq_gpio_cfg2->irq_src_sel << CS35L41_GPIO2_CTRL_SHIFT);
 
 	if ((irq_gpio_cfg2->irq_src_sel ==
 			(CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) ||
diff --git a/sound/soc/codecs/cs35l41.h b/sound/soc/codecs/cs35l41.h
index 7a25430182f84..ec1b00b47d5dd 100644
--- a/sound/soc/codecs/cs35l41.h
+++ b/sound/soc/codecs/cs35l41.h
@@ -697,6 +697,7 @@
 #define CS35L41_INT1_UNMASK_PDN		0xFF7FFFFF
 
 #define CS35L41_GPIO_DIR_MASK		0x80000000
+#define CS35L41_GPIO_DIR_SHIFT		31
 #define CS35L41_GPIO1_CTRL_MASK		0x00030000
 #define CS35L41_GPIO1_CTRL_SHIFT	16
 #define CS35L41_GPIO2_CTRL_MASK		0x07000000
-- 
2.11.0


  parent reply	other threads:[~2021-09-14 14:15 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-14 14:13 [PATCH 1/6] ASoC: cs35l41: Fix use of an uninitialised variable Charles Keepax
2021-09-14 14:13 ` [PATCH 2/6] ASoC: cs35l41: Use regmap_read_poll_timeout to wait for OTP boot Charles Keepax
2021-09-14 14:13 ` Charles Keepax [this message]
2021-09-14 14:13 ` [PATCH 4/6] ASoC: cs35l41: Don't overwrite returned error code Charles Keepax
2021-09-14 14:13 ` [PATCH 5/6] ASoC: cs35l41: Fixup the error messages Charles Keepax
2021-09-14 14:13 ` [PATCH 6/6] ASoC: cs35l41: Fix a bunch of trivial code formating/style issues Charles Keepax
2021-09-14 14:23   ` Mark Brown
2021-09-15 10:53     ` Charles Keepax
2021-09-15 11:38       ` Mark Brown
2021-09-15 15:21 ` [PATCH 1/6] ASoC: cs35l41: Fix use of an uninitialised variable Mark Brown

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210914141349.30218-3-ckeepax@opensource.cirrus.com \
    --to=ckeepax@opensource.cirrus.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=broonie@kernel.org \
    --cc=david.rhodes@cirrus.com \
    --cc=james.schulman@cirrus.com \
    --cc=lgirdwood@gmail.com \
    --cc=patches@opensource.cirrus.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.