linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers
@ 2021-11-03 13:52 Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF Sameer Pujar
                   ` (9 more replies)
  0 siblings, 10 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

This series fixes kcontrol put callback in some of the Tegra drivers
which are used on platforms based on Tegra210 and later. The callback
is expected to return 1 whenever the HW update is done.

This idea is suggested by Jaroslav. Similar suggestion came from
Mark during review of series [0] and drivers under this were updated
to return 1, but missed to take care of duplicate updates. This series
updates all concerned drivers to return proper values and duplicate
updates are filtered out. I have added 'Suggested-by" tags accordingly.

[0] https://lore.kernel.org/linux-arm-kernel/20210913142307.GF4283@sirena.org.uk/



Changelog
=========
 v1->v2:
 -------
   * ADMAIF, I2S, DMIC and DSPK drivers updated to take care of
     duplicate updates.
   * Similarly new patches are added for AHUB, MVC, SFC, AMX, ADX
     and Mixer drivers.

Sameer Pujar (10):
  ASoC: tegra: Fix kcontrol put callback in ADMAIF
  ASoC: tegra: Fix kcontrol put callback in I2S
  ASoC: tegra: Fix kcontrol put callback in DMIC
  ASoC: tegra: Fix kcontrol put callback in DSPK
  ASoC: tegra: Fix kcontrol put callback in AHUB
  ASoC: tegra: Fix kcontrol put callback in MVC
  ASoC: tegra: Fix kcontrol put callback in SFC
  ASoC: tegra: Fix kcontrol put callback in AMX
  ASoC: tegra: Fix kcontrol put callback in ADX
  ASoC: tegra: Fix kcontrol put callback in Mixer

 sound/soc/tegra/tegra186_dspk.c   | 33 ++++++++++++++++++++++++++-------
 sound/soc/tegra/tegra210_admaif.c | 23 ++++++++++++++++++-----
 sound/soc/tegra/tegra210_adx.c    |  3 +++
 sound/soc/tegra/tegra210_ahub.c   | 11 +++++++----
 sound/soc/tegra/tegra210_amx.c    |  3 +++
 sound/soc/tegra/tegra210_dmic.c   | 35 +++++++++++++++++++++++++++--------
 sound/soc/tegra/tegra210_i2s.c    | 26 +++++++++++++++++++++++++-
 sound/soc/tegra/tegra210_mixer.c  |  3 +++
 sound/soc/tegra/tegra210_mvc.c    | 18 ++++++++++++++++--
 sound/soc/tegra/tegra210_sfc.c    | 23 +++++++++++++++++------
 10 files changed, 145 insertions(+), 33 deletions(-)

-- 
2.7.4


^ permalink raw reply	[flat|nested] 17+ messages in thread

* [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF
  2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
@ 2021-11-03 13:52 ` Sameer Pujar
  2021-11-03 14:16   ` Takashi Iwai
  2021-11-03 13:52 ` [PATCH v2 02/10] ASoC: tegra: Fix kcontrol put callback in I2S Sameer Pujar
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Update
the ADMAIF driver accordingly

Fixes: f74028e159bb ("ASoC: tegra: Add Tegra210 based ADMAIF driver")
Suggested-by: Jaroslav Kysela <perex@perex.cz>
Suggested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
---
 sound/soc/tegra/tegra210_admaif.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c
index bcccdf3..dc71075 100644
--- a/sound/soc/tegra/tegra210_admaif.c
+++ b/sound/soc/tegra/tegra210_admaif.c
@@ -452,16 +452,29 @@ static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol,
 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
 	int value = ucontrol->value.integer.value[0];
 
-	if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
+	if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) {
+		if (admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] == value)
+			return 0;
+
 		admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
-	else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
+	} else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) {
+		if (admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] == value)
+			return 0;
+
 		admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
-	else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
+	} else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) {
+		if (admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] == value)
+			return 0;
+
 		admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
-	else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
+	} else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) {
+		if (admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] == value)
+			return 0;
+
 		admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
+	}
 
-	return 0;
+	return 1;
 }
 
 static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 02/10] ASoC: tegra: Fix kcontrol put callback in I2S
  2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF Sameer Pujar
@ 2021-11-03 13:52 ` Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 03/10] ASoC: tegra: Fix kcontrol put callback in DMIC Sameer Pujar
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Update
the I2S driver accordingly.

Fixes: c0bfa98349d1 ("ASoC: tegra: Add Tegra210 based I2S driver")
Suggested-by: Jaroslav Kysela <perex@perex.cz>
Suggested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
---
 sound/soc/tegra/tegra210_i2s.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/sound/soc/tegra/tegra210_i2s.c b/sound/soc/tegra/tegra210_i2s.c
index 45f31cc..70505b5 100644
--- a/sound/soc/tegra/tegra210_i2s.c
+++ b/sound/soc/tegra/tegra210_i2s.c
@@ -347,6 +347,9 @@ static int tegra210_i2s_put_control(struct snd_kcontrol *kcontrol,
 	int value = ucontrol->value.integer.value[0];
 
 	if (strstr(kcontrol->id.name, "Loopback")) {
+		if (i2s->loopback == value)
+			return 0;
+
 		i2s->loopback = value;
 
 		regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL,
@@ -362,6 +365,9 @@ static int tegra210_i2s_put_control(struct snd_kcontrol *kcontrol,
 		 * cases mixer control is used to update custom values. A value
 		 * of "N" here means, width is "N + 1" bit clock wide.
 		 */
+		if (i2s->fsync_width == value)
+			return 0;
+
 		i2s->fsync_width = value;
 
 		regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL,
@@ -369,20 +375,38 @@ static int tegra210_i2s_put_control(struct snd_kcontrol *kcontrol,
 				   i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT);
 
 	} else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) {
+		if (i2s->stereo_to_mono[I2S_TX_PATH] == value)
+			return 0;
+
 		i2s->stereo_to_mono[I2S_TX_PATH] = value;
 	} else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) {
+		if (i2s->mono_to_stereo[I2S_TX_PATH] == value)
+			return 0;
+
 		i2s->mono_to_stereo[I2S_TX_PATH] = value;
 	} else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) {
+		if (i2s->stereo_to_mono[I2S_RX_PATH] == value)
+			return 0;
+
 		i2s->stereo_to_mono[I2S_RX_PATH] = value;
 	} else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) {
+		if (i2s->mono_to_stereo[I2S_RX_PATH] == value)
+			return 0;
+
 		i2s->mono_to_stereo[I2S_RX_PATH] = value;
 	} else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) {
+		if (i2s->rx_fifo_th == value)
+			return 0;
+
 		i2s->rx_fifo_th = value;
 	} else if (strstr(kcontrol->id.name, "BCLK Ratio")) {
+		if (i2s->bclk_ratio == value)
+			return 0;
+
 		i2s->bclk_ratio = value;
 	}
 
-	return 0;
+	return 1;
 }
 
 static int tegra210_i2s_set_timing_params(struct device *dev,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 03/10] ASoC: tegra: Fix kcontrol put callback in DMIC
  2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 02/10] ASoC: tegra: Fix kcontrol put callback in I2S Sameer Pujar
@ 2021-11-03 13:52 ` Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 04/10] ASoC: tegra: Fix kcontrol put callback in DSPK Sameer Pujar
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Update
the DMIC driver accordingly.

Fixes: 8c8ff982e9e2 ("ASoC: tegra: Add Tegra210 based DMIC driver")
Suggested-by: Jaroslav Kysela <perex@perex.cz>
Suggested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
---
 sound/soc/tegra/tegra210_dmic.c | 35 +++++++++++++++++++++++++++--------
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/sound/soc/tegra/tegra210_dmic.c b/sound/soc/tegra/tegra210_dmic.c
index b096478..39a63ed 100644
--- a/sound/soc/tegra/tegra210_dmic.c
+++ b/sound/soc/tegra/tegra210_dmic.c
@@ -185,20 +185,39 @@ static int tegra210_dmic_put_control(struct snd_kcontrol *kcontrol,
 	struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp);
 	int value = ucontrol->value.integer.value[0];
 
-	if (strstr(kcontrol->id.name, "Boost Gain Volume"))
+	if (strstr(kcontrol->id.name, "Boost Gain Volume")) {
+		if (dmic->boost_gain == value)
+			return 0;
+
 		dmic->boost_gain = value;
-	else if (strstr(kcontrol->id.name, "Channel Select"))
-		dmic->ch_select = ucontrol->value.integer.value[0];
-	else if (strstr(kcontrol->id.name, "Mono To Stereo"))
+	} else if (strstr(kcontrol->id.name, "Channel Select")) {
+		if (dmic->ch_select == value)
+			return 0;
+
+		dmic->ch_select = value;
+	} else if (strstr(kcontrol->id.name, "Mono To Stereo")) {
+		if (dmic->mono_to_stereo == value)
+			return 0;
+
 		dmic->mono_to_stereo = value;
-	else if (strstr(kcontrol->id.name, "Stereo To Mono"))
+	} else if (strstr(kcontrol->id.name, "Stereo To Mono")) {
+		if (dmic->stereo_to_mono == value)
+			return 0;
+
 		dmic->stereo_to_mono = value;
-	else if (strstr(kcontrol->id.name, "OSR Value"))
+	} else if (strstr(kcontrol->id.name, "OSR Value")) {
+		if (dmic->osr_val == value)
+			return 0;
+
 		dmic->osr_val = value;
-	else if (strstr(kcontrol->id.name, "LR Polarity Select"))
+	} else if (strstr(kcontrol->id.name, "LR Polarity Select")) {
+		if (dmic->lrsel == value)
+			return 0;
+
 		dmic->lrsel = value;
+	}
 
-	return 0;
+	return 1;
 }
 
 static const struct snd_soc_dai_ops tegra210_dmic_dai_ops = {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 04/10] ASoC: tegra: Fix kcontrol put callback in DSPK
  2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
                   ` (2 preceding siblings ...)
  2021-11-03 13:52 ` [PATCH v2 03/10] ASoC: tegra: Fix kcontrol put callback in DMIC Sameer Pujar
@ 2021-11-03 13:52 ` Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 05/10] ASoC: tegra: Fix kcontrol put callback in AHUB Sameer Pujar
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Update
the DSPK driver accordingly.

Fixes: 327ef6470266 ("ASoC: tegra: Add Tegra186 based DSPK driver")
Suggested-by: Jaroslav Kysela <perex@perex.cz>
Suggested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
---
 sound/soc/tegra/tegra186_dspk.c | 33 ++++++++++++++++++++++++++-------
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/sound/soc/tegra/tegra186_dspk.c b/sound/soc/tegra/tegra186_dspk.c
index 8ee9a77..4cc06e9 100644
--- a/sound/soc/tegra/tegra186_dspk.c
+++ b/sound/soc/tegra/tegra186_dspk.c
@@ -55,20 +55,39 @@ static int tegra186_dspk_put_control(struct snd_kcontrol *kcontrol,
 	struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec);
 	int val = ucontrol->value.integer.value[0];
 
-	if (strstr(kcontrol->id.name, "FIFO Threshold"))
+	if (strstr(kcontrol->id.name, "FIFO Threshold")) {
+		if (dspk->rx_fifo_th == val)
+			return 0;
+
 		dspk->rx_fifo_th = val;
-	else if (strstr(kcontrol->id.name, "OSR Value"))
+	} else if (strstr(kcontrol->id.name, "OSR Value")) {
+		if (dspk->osr_val == val)
+			return 0;
+
 		dspk->osr_val = val;
-	else if (strstr(kcontrol->id.name, "LR Polarity Select"))
+	} else if (strstr(kcontrol->id.name, "LR Polarity Select")) {
+		if (dspk->lrsel == val)
+			return 0;
+
 		dspk->lrsel = val;
-	else if (strstr(kcontrol->id.name, "Channel Select"))
+	} else if (strstr(kcontrol->id.name, "Channel Select")) {
+		if (dspk->ch_sel == val)
+			return 0;
+
 		dspk->ch_sel = val;
-	else if (strstr(kcontrol->id.name, "Mono To Stereo"))
+	} else if (strstr(kcontrol->id.name, "Mono To Stereo")) {
+		if (dspk->mono_to_stereo == val)
+			return 0;
+
 		dspk->mono_to_stereo = val;
-	else if (strstr(kcontrol->id.name, "Stereo To Mono"))
+	} else if (strstr(kcontrol->id.name, "Stereo To Mono")) {
+		if (dspk->stereo_to_mono == val)
+			return 0;
+
 		dspk->stereo_to_mono = val;
+	}
 
-	return 0;
+	return 1;
 }
 
 static int __maybe_unused tegra186_dspk_runtime_suspend(struct device *dev)
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 05/10] ASoC: tegra: Fix kcontrol put callback in AHUB
  2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
                   ` (3 preceding siblings ...)
  2021-11-03 13:52 ` [PATCH v2 04/10] ASoC: tegra: Fix kcontrol put callback in DSPK Sameer Pujar
@ 2021-11-03 13:52 ` Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 06/10] ASoC: tegra: Fix kcontrol put callback in MVC Sameer Pujar
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Update
the AHUB driver accordingly.

Fixes: 16e1bcc2caf4 ("ASoC: tegra: Add Tegra210 based AHUB driver")
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Suggested-by: Jaroslav Kysela <perex@perex.cz>
Suggested-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/tegra/tegra210_ahub.c | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/sound/soc/tegra/tegra210_ahub.c b/sound/soc/tegra/tegra210_ahub.c
index a1989ea..388b815 100644
--- a/sound/soc/tegra/tegra210_ahub.c
+++ b/sound/soc/tegra/tegra210_ahub.c
@@ -62,6 +62,7 @@ static int tegra_ahub_put_value_enum(struct snd_kcontrol *kctl,
 	unsigned int *item = uctl->value.enumerated.item;
 	unsigned int value = e->values[item[0]];
 	unsigned int i, bit_pos, reg_idx = 0, reg_val = 0;
+	int change = 0;
 
 	if (item[0] >= e->items)
 		return -EINVAL;
@@ -86,12 +87,14 @@ static int tegra_ahub_put_value_enum(struct snd_kcontrol *kctl,
 
 		/* Update widget power if state has changed */
 		if (snd_soc_component_test_bits(cmpnt, update[i].reg,
-						update[i].mask, update[i].val))
-			snd_soc_dapm_mux_update_power(dapm, kctl, item[0], e,
-						      &update[i]);
+						update[i].mask,
+						update[i].val))
+			change |= snd_soc_dapm_mux_update_power(dapm, kctl,
+								item[0], e,
+								&update[i]);
 	}
 
-	return 0;
+	return change;
 }
 
 static struct snd_soc_dai_driver tegra210_ahub_dais[] = {
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 06/10] ASoC: tegra: Fix kcontrol put callback in MVC
  2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
                   ` (4 preceding siblings ...)
  2021-11-03 13:52 ` [PATCH v2 05/10] ASoC: tegra: Fix kcontrol put callback in AHUB Sameer Pujar
@ 2021-11-03 13:52 ` Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 07/10] ASoC: tegra: Fix kcontrol put callback in SFC Sameer Pujar
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Filter
out duplicate updates in MVC driver.

Fixes: e539891f9687 ("ASoC: tegra: Add Tegra210 based MVC driver")
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Suggested-by: Jaroslav Kysela <perex@perex.cz>
Suggested-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/tegra/tegra210_mvc.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/sound/soc/tegra/tegra210_mvc.c b/sound/soc/tegra/tegra210_mvc.c
index 7b9c700..380686c 100644
--- a/sound/soc/tegra/tegra210_mvc.c
+++ b/sound/soc/tegra/tegra210_mvc.c
@@ -136,7 +136,7 @@ static int tegra210_mvc_put_mute(struct snd_kcontrol *kcontrol,
 	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
 	struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt);
 	unsigned int value;
-	u8 mute_mask;
+	u8 mute_mask, old_mask;
 	int err;
 
 	pm_runtime_get_sync(cmpnt->dev);
@@ -148,8 +148,16 @@ static int tegra210_mvc_put_mute(struct snd_kcontrol *kcontrol,
 	if (err < 0)
 		goto end;
 
+	regmap_read(mvc->regmap, TEGRA210_MVC_CTRL, &value);
+
+	old_mask = (value >> TEGRA210_MVC_MUTE_SHIFT) & TEGRA210_MUTE_MASK_EN;
 	mute_mask = ucontrol->value.integer.value[0];
 
+	if (mute_mask == old_mask) {
+		err = 0;
+		goto end;
+	}
+
 	err = regmap_update_bits(mvc->regmap, mc->reg,
 				 TEGRA210_MVC_MUTE_MASK,
 				 mute_mask << TEGRA210_MVC_MUTE_SHIFT);
@@ -195,7 +203,7 @@ static int tegra210_mvc_put_vol(struct snd_kcontrol *kcontrol,
 	unsigned int reg = mc->reg;
 	unsigned int value;
 	u8 chan;
-	int err;
+	int err, old_volume;
 
 	pm_runtime_get_sync(cmpnt->dev);
 
@@ -207,10 +215,16 @@ static int tegra210_mvc_put_vol(struct snd_kcontrol *kcontrol,
 		goto end;
 
 	chan = (reg - TEGRA210_MVC_TARGET_VOL) / REG_SIZE;
+	old_volume = mvc->volume[chan];
 
 	tegra210_mvc_conv_vol(mvc, chan,
 			      ucontrol->value.integer.value[0]);
 
+	if (mvc->volume[chan] == old_volume) {
+		err = 0;
+		goto end;
+	}
+
 	/* Configure init volume same as target volume */
 	regmap_write(mvc->regmap,
 		TEGRA210_MVC_REG_OFFSET(TEGRA210_MVC_INIT_VOL, chan),
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 07/10] ASoC: tegra: Fix kcontrol put callback in SFC
  2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
                   ` (5 preceding siblings ...)
  2021-11-03 13:52 ` [PATCH v2 06/10] ASoC: tegra: Fix kcontrol put callback in MVC Sameer Pujar
@ 2021-11-03 13:52 ` Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 08/10] ASoC: tegra: Fix kcontrol put callback in AMX Sameer Pujar
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Filter
out duplicate updates in SFC driver.

Fixes: b2f74ec53a6c ("ASoC: tegra: Add Tegra210 based SFC driver")
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Suggested-by: Jaroslav Kysela <perex@perex.cz>
Suggested-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/tegra/tegra210_sfc.c | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/sound/soc/tegra/tegra210_sfc.c b/sound/soc/tegra/tegra210_sfc.c
index dc477ee..ac24980 100644
--- a/sound/soc/tegra/tegra210_sfc.c
+++ b/sound/soc/tegra/tegra210_sfc.c
@@ -3273,16 +3273,27 @@ static int tegra210_sfc_put_control(struct snd_kcontrol *kcontrol,
 	struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt);
 	int value = ucontrol->value.integer.value[0];
 
-	if (strstr(kcontrol->id.name, "Input Stereo To Mono"))
+	if (strstr(kcontrol->id.name, "Input Stereo To Mono")) {
+		if (sfc->stereo_to_mono[SFC_RX_PATH] == value)
+			return 0;
+
 		sfc->stereo_to_mono[SFC_RX_PATH] = value;
-	else if (strstr(kcontrol->id.name, "Input Mono To Stereo"))
+	} else if (strstr(kcontrol->id.name, "Input Mono To Stereo")) {
+		if (sfc->mono_to_stereo[SFC_RX_PATH] == value)
+			return 0;
+
 		sfc->mono_to_stereo[SFC_RX_PATH] = value;
-	else if (strstr(kcontrol->id.name, "Output Stereo To Mono"))
+	} else if (strstr(kcontrol->id.name, "Output Stereo To Mono")) {
+		if (sfc->stereo_to_mono[SFC_TX_PATH] == value)
+			return 0;
+
 		sfc->stereo_to_mono[SFC_TX_PATH] = value;
-	else if (strstr(kcontrol->id.name, "Output Mono To Stereo"))
+	} else if (strstr(kcontrol->id.name, "Output Mono To Stereo")) {
+		if (sfc->mono_to_stereo[SFC_TX_PATH] == value)
+			return 0;
+
 		sfc->mono_to_stereo[SFC_TX_PATH] = value;
-	else
-		return 0;
+	}
 
 	return 1;
 }
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 08/10] ASoC: tegra: Fix kcontrol put callback in AMX
  2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
                   ` (6 preceding siblings ...)
  2021-11-03 13:52 ` [PATCH v2 07/10] ASoC: tegra: Fix kcontrol put callback in SFC Sameer Pujar
@ 2021-11-03 13:52 ` Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 09/10] ASoC: tegra: Fix kcontrol put callback in ADX Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 10/10] ASoC: tegra: Fix kcontrol put callback in Mixer Sameer Pujar
  9 siblings, 0 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Filter
out duplicate updates in AMX driver.

Fixes: 77f7df346c45 ("ASoC: tegra: Add Tegra210 based AMX driver")
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Suggested-by: Jaroslav Kysela <perex@perex.cz>
Suggested-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/tegra/tegra210_amx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sound/soc/tegra/tegra210_amx.c b/sound/soc/tegra/tegra210_amx.c
index af9bddf..6895763 100644
--- a/sound/soc/tegra/tegra210_amx.c
+++ b/sound/soc/tegra/tegra210_amx.c
@@ -222,6 +222,9 @@ static int tegra210_amx_put_byte_map(struct snd_kcontrol *kcontrol,
 	int reg = mc->reg;
 	int value = ucontrol->value.integer.value[0];
 
+	if (value == bytes_map[reg])
+		return 0;
+
 	if (value >= 0 && value <= 255) {
 		/* Update byte map and enable slot */
 		bytes_map[reg] = value;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 09/10] ASoC: tegra: Fix kcontrol put callback in ADX
  2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
                   ` (7 preceding siblings ...)
  2021-11-03 13:52 ` [PATCH v2 08/10] ASoC: tegra: Fix kcontrol put callback in AMX Sameer Pujar
@ 2021-11-03 13:52 ` Sameer Pujar
  2021-11-03 13:52 ` [PATCH v2 10/10] ASoC: tegra: Fix kcontrol put callback in Mixer Sameer Pujar
  9 siblings, 0 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Filter
out duplicate updates in ADX driver.

Fixes: a99ab6f395a9 ("ASoC: tegra: Add Tegra210 based ADX driver")
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Suggested-by: Jaroslav Kysela <perex@perex.cz>
Suggested-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/tegra/tegra210_adx.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sound/soc/tegra/tegra210_adx.c b/sound/soc/tegra/tegra210_adx.c
index d7c7849..933c450 100644
--- a/sound/soc/tegra/tegra210_adx.c
+++ b/sound/soc/tegra/tegra210_adx.c
@@ -193,6 +193,9 @@ static int tegra210_adx_put_byte_map(struct snd_kcontrol *kcontrol,
 	struct soc_mixer_control *mc =
 		(struct soc_mixer_control *)kcontrol->private_value;;
 
+	if (value == bytes_map[mc->reg])
+		return 0;
+
 	if (value >= 0 && value <= 255) {
 		/* update byte map and enable slot */
 		bytes_map[mc->reg] = value;
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* [PATCH v2 10/10] ASoC: tegra: Fix kcontrol put callback in Mixer
  2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
                   ` (8 preceding siblings ...)
  2021-11-03 13:52 ` [PATCH v2 09/10] ASoC: tegra: Fix kcontrol put callback in ADX Sameer Pujar
@ 2021-11-03 13:52 ` Sameer Pujar
  9 siblings, 0 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-03 13:52 UTC (permalink / raw)
  To: broonie, lgirdwood, perex, tiwai
  Cc: thierry.reding, jonathanh, alsa-devel, linux-tegra, linux-kernel,
	Sameer Pujar

The kcontrol put callback is expected to return 1 when there is change
in HW or when the update is acknowledged by driver. This would ensure
that change notifications are sent to subscribed applications. Filter
out duplicate updates in Mixer driver.

Fixes: 05bb3d5ec64a ("ASoC: tegra: Add Tegra210 based Mixer driver")
Signed-off-by: Sameer Pujar <spujar@nvidia.com>
Suggested-by: Jaroslav Kysela <perex@perex.cz>
Suggested-by: Mark Brown <broonie@kernel.org>
---
 sound/soc/tegra/tegra210_mixer.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sound/soc/tegra/tegra210_mixer.c b/sound/soc/tegra/tegra210_mixer.c
index 55e6177..d2d1946 100644
--- a/sound/soc/tegra/tegra210_mixer.c
+++ b/sound/soc/tegra/tegra210_mixer.c
@@ -210,6 +210,9 @@ static int tegra210_mixer_put_gain(struct snd_kcontrol *kcontrol,
 	id = (reg - TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_0) /
 	     TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_STRIDE;
 
+	if (mixer->gain_value[id] == ucontrol->value.integer.value[0])
+		return 0;
+
 	mixer->gain_value[id] = ucontrol->value.integer.value[0];
 
 	err = tegra210_mixer_configure_gain(cmpnt, id, instant_gain);
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF
  2021-11-03 13:52 ` [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF Sameer Pujar
@ 2021-11-03 14:16   ` Takashi Iwai
  2021-11-03 14:18     ` Takashi Iwai
                       ` (2 more replies)
  0 siblings, 3 replies; 17+ messages in thread
From: Takashi Iwai @ 2021-11-03 14:16 UTC (permalink / raw)
  To: Sameer Pujar
  Cc: broonie, lgirdwood, perex, tiwai, thierry.reding, jonathanh,
	alsa-devel, linux-tegra, linux-kernel

On Wed, 03 Nov 2021 14:52:17 +0100,
Sameer Pujar wrote:
> 
> The kcontrol put callback is expected to return 1 when there is change
> in HW or when the update is acknowledged by driver. This would ensure
> that change notifications are sent to subscribed applications. Update
> the ADMAIF driver accordingly
> 
> Fixes: f74028e159bb ("ASoC: tegra: Add Tegra210 based ADMAIF driver")
> Suggested-by: Jaroslav Kysela <perex@perex.cz>
> Suggested-by: Mark Brown <broonie@kernel.org>
> Signed-off-by: Sameer Pujar <spujar@nvidia.com>
> ---
>  sound/soc/tegra/tegra210_admaif.c | 23 ++++++++++++++++++-----
>  1 file changed, 18 insertions(+), 5 deletions(-)
> 
> diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c
> index bcccdf3..dc71075 100644
> --- a/sound/soc/tegra/tegra210_admaif.c
> +++ b/sound/soc/tegra/tegra210_admaif.c
> @@ -452,16 +452,29 @@ static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol,
>  	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
>  	int value = ucontrol->value.integer.value[0];
>  
> -	if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
> +	if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) {
> +		if (admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] == value)
> +			return 0;
> +
>  		admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
> -	else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
> +	} else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) {
> +		if (admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] == value)
> +			return 0;
> +
>  		admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
> -	else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
> +	} else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) {
> +		if (admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] == value)
> +			return 0;
> +
>  		admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
> -	else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
> +	} else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) {
> +		if (admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] == value)
> +			return 0;
> +
>  		admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
> +	}
>  
> -	return 0;
> +	return 1;

Hrm, that looks too redundant.  The similar checks are seen in the get
part, so we may have a better helper function to reduce the string
checks, something like below.


BTW, independent from this patch set, I noticed that those get/put
callbacks handle the wrong type.  For enum ctls, you have to use 
ucontrol->value.enumerated.value instead of
ucontrol->value.integer.value.  The former is long while the latter is
int, hence they may have different sizes.

Such a bug could be caught if you test once with
CONFIG_SND_CTL_VALIDATION=y.  It's recommended to test with that
config once for a new driver code.

So, please submit the fix patch(es) for correcting the ctl value
types, too.


thanks,

Takashi

--- a/sound/soc/tegra/tegra210_admaif.c
+++ b/sound/soc/tegra/tegra210_admaif.c
@@ -424,44 +424,46 @@ static const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
 	.trigger	= tegra_admaif_trigger,
 };
 
-static int tegra_admaif_get_control(struct snd_kcontrol *kcontrol,
-				    struct snd_ctl_elem_value *ucontrol)
+static unsigned int *tegra_admaif_route_val(struct snd_kcontrol *kcontrol)
 {
 	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
 	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
 	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
-	long *uctl_val = &ucontrol->value.integer.value[0];
 
 	if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
-		*uctl_val = admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
+		return &admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
 	else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
-		*uctl_val = admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
+		return &admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
 	else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
-		*uctl_val = admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
+		return &admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
 	else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
-		*uctl_val = admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
+		return &admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
+	return NULL;
+}
 
+static int tegra_admaif_get_control(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	unsigned int *valp = tegra_admaif_route_val(admaif, kcontrol);
+
+	if (!valp)
+		return -EINVAL;
+	ucontrol->value.integer.value[0] = *valp;
 	return 0;
 }
 
 static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol,
 				    struct snd_ctl_elem_value *ucontrol)
 {
-	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
-	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
-	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
+	unsigned int *valp = tegra_admaif_route_val(admaif, kcontrol);
 	int value = ucontrol->value.integer.value[0];
 
-	if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
-		admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
-	else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
-		admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
-	else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
-		admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
-	else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
-		admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
-
-	return 0;
+	if (!valp)
+		return -EINVAL;
+	if (value == *valp)
+		return 0;
+	*valp = value;
+	return 1;
 }
 
 static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF
  2021-11-03 14:16   ` Takashi Iwai
@ 2021-11-03 14:18     ` Takashi Iwai
  2021-11-03 17:25     ` Jaroslav Kysela
  2021-11-08 16:08     ` Sameer Pujar
  2 siblings, 0 replies; 17+ messages in thread
From: Takashi Iwai @ 2021-11-03 14:18 UTC (permalink / raw)
  To: Sameer Pujar
  Cc: broonie, lgirdwood, perex, tiwai, thierry.reding, jonathanh,
	alsa-devel, linux-tegra, linux-kernel

On Wed, 03 Nov 2021 15:16:24 +0100,
Takashi Iwai wrote:
> 
> On Wed, 03 Nov 2021 14:52:17 +0100,
> Sameer Pujar wrote:
> > 
> > The kcontrol put callback is expected to return 1 when there is change
> > in HW or when the update is acknowledged by driver. This would ensure
> > that change notifications are sent to subscribed applications. Update
> > the ADMAIF driver accordingly
> > 
> > Fixes: f74028e159bb ("ASoC: tegra: Add Tegra210 based ADMAIF driver")
> > Suggested-by: Jaroslav Kysela <perex@perex.cz>
> > Suggested-by: Mark Brown <broonie@kernel.org>
> > Signed-off-by: Sameer Pujar <spujar@nvidia.com>
> > ---
> >  sound/soc/tegra/tegra210_admaif.c | 23 ++++++++++++++++++-----
> >  1 file changed, 18 insertions(+), 5 deletions(-)
> > 
> > diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c
> > index bcccdf3..dc71075 100644
> > --- a/sound/soc/tegra/tegra210_admaif.c
> > +++ b/sound/soc/tegra/tegra210_admaif.c
> > @@ -452,16 +452,29 @@ static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol,
> >  	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
> >  	int value = ucontrol->value.integer.value[0];
> >  
> > -	if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
> > +	if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) {
> > +		if (admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] == value)
> > +			return 0;
> > +
> >  		admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
> > -	else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
> > +	} else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) {
> > +		if (admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] == value)
> > +			return 0;
> > +
> >  		admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
> > -	else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
> > +	} else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) {
> > +		if (admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] == value)
> > +			return 0;
> > +
> >  		admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
> > -	else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
> > +	} else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) {
> > +		if (admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] == value)
> > +			return 0;
> > +
> >  		admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
> > +	}
> >  
> > -	return 0;
> > +	return 1;
> 
> Hrm, that looks too redundant.  The similar checks are seen in the get
> part, so we may have a better helper function to reduce the string
> checks, something like below.
> 
> 
> BTW, independent from this patch set, I noticed that those get/put
> callbacks handle the wrong type.  For enum ctls, you have to use 
> ucontrol->value.enumerated.value instead of
> ucontrol->value.integer.value.  The former is long while the latter is
> int, hence they may have different sizes.
> 
> Such a bug could be caught if you test once with
> CONFIG_SND_CTL_VALIDATION=y.  It's recommended to test with that
> config once for a new driver code.
> 
> So, please submit the fix patch(es) for correcting the ctl value
> types, too.
> 
> 
> thanks,
> 
> Takashi
> 
> --- a/sound/soc/tegra/tegra210_admaif.c
> +++ b/sound/soc/tegra/tegra210_admaif.c
> @@ -424,44 +424,46 @@ static const struct snd_soc_dai_ops tegra_admaif_dai_ops = {
>  	.trigger	= tegra_admaif_trigger,
>  };
>  
> -static int tegra_admaif_get_control(struct snd_kcontrol *kcontrol,
> -				    struct snd_ctl_elem_value *ucontrol)
> +static unsigned int *tegra_admaif_route_val(struct snd_kcontrol *kcontrol)
>  {
>  	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
>  	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
>  	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
> -	long *uctl_val = &ucontrol->value.integer.value[0];
>  
>  	if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
> -		*uctl_val = admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
> +		return &admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];
>  	else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
> -		*uctl_val = admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
> +		return &admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg];
>  	else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
> -		*uctl_val = admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
> +		return &admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg];
>  	else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
> -		*uctl_val = admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
> +		return &admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg];
> +	return NULL;
> +}
>  
> +static int tegra_admaif_get_control(struct snd_kcontrol *kcontrol,
> +				    struct snd_ctl_elem_value *ucontrol)
> +{
> +	unsigned int *valp = tegra_admaif_route_val(admaif, kcontrol);

The admaif argument is superfluous here, drop it.

My patch is just for bringing an idea, and feel free to cook in your
own way, of course.


Takashi

> +
> +	if (!valp)
> +		return -EINVAL;
> +	ucontrol->value.integer.value[0] = *valp;
>  	return 0;
>  }
>  
>  static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol,
>  				    struct snd_ctl_elem_value *ucontrol)
>  {
> -	struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
> -	struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
> -	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
> +	unsigned int *valp = tegra_admaif_route_val(admaif, kcontrol);
>  	int value = ucontrol->value.integer.value[0];
>  
> -	if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
> -		admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
> -	else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
> -		admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
> -	else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
> -		admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
> -	else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
> -		admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
> -
> -	return 0;
> +	if (!valp)
> +		return -EINVAL;
> +	if (value == *valp)
> +		return 0;
> +	*valp = value;
> +	return 1;
>  }
>  
>  static int tegra_admaif_dai_probe(struct snd_soc_dai *dai)
> 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF
  2021-11-03 14:16   ` Takashi Iwai
  2021-11-03 14:18     ` Takashi Iwai
@ 2021-11-03 17:25     ` Jaroslav Kysela
  2021-11-08 16:03       ` Sameer Pujar
  2021-11-08 16:08     ` Sameer Pujar
  2 siblings, 1 reply; 17+ messages in thread
From: Jaroslav Kysela @ 2021-11-03 17:25 UTC (permalink / raw)
  To: Takashi Iwai, Sameer Pujar
  Cc: broonie, lgirdwood, tiwai, thierry.reding, jonathanh, alsa-devel,
	linux-tegra, linux-kernel

On 03. 11. 21 15:16, Takashi Iwai wrote:
> On Wed, 03 Nov 2021 14:52:17 +0100,
> Sameer Pujar wrote:
>>
>> The kcontrol put callback is expected to return 1 when there is change
>> in HW or when the update is acknowledged by driver. This would ensure
>> that change notifications are sent to subscribed applications. Update
>> the ADMAIF driver accordingly
>>
>> Fixes: f74028e159bb ("ASoC: tegra: Add Tegra210 based ADMAIF driver")
>> Suggested-by: Jaroslav Kysela <perex@perex.cz>
>> Suggested-by: Mark Brown <broonie@kernel.org>
>> Signed-off-by: Sameer Pujar <spujar@nvidia.com>
>> ---
>>   sound/soc/tegra/tegra210_admaif.c | 23 ++++++++++++++++++-----
>>   1 file changed, 18 insertions(+), 5 deletions(-)
>>
>> diff --git a/sound/soc/tegra/tegra210_admaif.c b/sound/soc/tegra/tegra210_admaif.c
>> index bcccdf3..dc71075 100644
>> --- a/sound/soc/tegra/tegra210_admaif.c
>> +++ b/sound/soc/tegra/tegra210_admaif.c
>> @@ -452,16 +452,29 @@ static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol,
>>   	struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
>>   	int value = ucontrol->value.integer.value[0];
>>   
>> -	if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
>> +	if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) {
>> +		if (admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] == value)
>> +			return 0;
>> +
>>   		admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
>> -	else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
>> +	} else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) {
>> +		if (admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] == value)
>> +			return 0;
>> +
>>   		admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
>> -	else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
>> +	} else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) {
>> +		if (admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] == value)
>> +			return 0;
>> +
>>   		admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
>> -	else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
>> +	} else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) {
>> +		if (admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] == value)
>> +			return 0;
>> +
>>   		admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
>> +	}
>>   
>> -	return 0;
>> +	return 1;
> 
> Hrm, that looks too redundant.  The similar checks are seen in the get
> part, so we may have a better helper function to reduce the string
> checks, something like below.

While proposing such cleanups, I would create separate get/put callbacks for 
all four ops instead using strstr(). The callbacks may put the common code to 
one function. It may reduce the code size (and the text segment size).

						Jaroslav

-- 
Jaroslav Kysela <perex@perex.cz>
Linux Sound Maintainer; ALSA Project; Red Hat, Inc.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF
  2021-11-03 17:25     ` Jaroslav Kysela
@ 2021-11-08 16:03       ` Sameer Pujar
  2021-11-08 16:16         ` Mark Brown
  0 siblings, 1 reply; 17+ messages in thread
From: Sameer Pujar @ 2021-11-08 16:03 UTC (permalink / raw)
  To: Jaroslav Kysela, Takashi Iwai
  Cc: broonie, lgirdwood, tiwai, thierry.reding, jonathanh, alsa-devel,
	linux-tegra, linux-kernel



On 11/3/2021 10:55 PM, Jaroslav Kysela wrote:
> On 03. 11. 21 15:16, Takashi Iwai wrote:
>> On Wed, 03 Nov 2021 14:52:17 +0100,
>> Sameer Pujar wrote:
>>>
>>> The kcontrol put callback is expected to return 1 when there is change
>>> in HW or when the update is acknowledged by driver. This would ensure
>>> that change notifications are sent to subscribed applications. Update
>>> the ADMAIF driver accordingly
>>>
>>> Fixes: f74028e159bb ("ASoC: tegra: Add Tegra210 based ADMAIF driver")
>>> Suggested-by: Jaroslav Kysela <perex@perex.cz>
>>> Suggested-by: Mark Brown <broonie@kernel.org>
>>> Signed-off-by: Sameer Pujar <spujar@nvidia.com>
>>> ---
>>>   sound/soc/tegra/tegra210_admaif.c | 23 ++++++++++++++++++-----
>>>   1 file changed, 18 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/sound/soc/tegra/tegra210_admaif.c 
>>> b/sound/soc/tegra/tegra210_admaif.c
>>> index bcccdf3..dc71075 100644
>>> --- a/sound/soc/tegra/tegra210_admaif.c
>>> +++ b/sound/soc/tegra/tegra210_admaif.c
>>> @@ -452,16 +452,29 @@ static int tegra_admaif_put_control(struct 
>>> snd_kcontrol *kcontrol,
>>>      struct tegra_admaif *admaif = 
>>> snd_soc_component_get_drvdata(cmpnt);
>>>      int value = ucontrol->value.integer.value[0];
>>>
>>> -    if (strstr(kcontrol->id.name, "Playback Mono To Stereo"))
>>> +    if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) {
>>> +            if (admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] == 
>>> value)
>>> +                    return 0;
>>> +
>>> admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;
>>> -    else if (strstr(kcontrol->id.name, "Capture Mono To Stereo"))
>>> +    } else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) {
>>> +            if (admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] == 
>>> value)
>>> +                    return 0;
>>> +
>>> admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value;
>>> -    else if (strstr(kcontrol->id.name, "Playback Stereo To Mono"))
>>> +    } else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) {
>>> +            if (admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] == 
>>> value)
>>> +                    return 0;
>>> +
>>> admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value;
>>> -    else if (strstr(kcontrol->id.name, "Capture Stereo To Mono"))
>>> +    } else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) {
>>> +            if (admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] == 
>>> value)
>>> +                    return 0;
>>> +
>>> admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value;
>>> +    }
>>>
>>> -    return 0;
>>> +    return 1;
>>
>> Hrm, that looks too redundant.  The similar checks are seen in the get
>> part, so we may have a better helper function to reduce the string
>> checks, something like below.
>

Thanks Takashi for your inputs. This would make the get/put callbacks 
simpler. But in some cases, for few controls additional handling is 
required (tegra210_i2s.c driver for example). In such cases additional 
checks would be required if the callback is common.

> While proposing such cleanups, I would create separate get/put 
> callbacks for
> all four ops instead using strstr(). The callbacks may put the common 
> code to
> one function. It may reduce the code size (and the text segment size).

With separate callbacks, the string checks can be removed. However for 
most of the controls, the common part is minimal. So there would be 
multiple independent small functions depending on the number of controls 
and the local variables are duplicated that many times. Would there be 
any concern on the space these local variables take? One pair of 
callbacks for a control may look like this.

static int kctl_pget_mono_to_stereo(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
{
         struct snd_soc_component *cmpnt = 
snd_soc_kcontrol_component(kcontrol);
         struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
         struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);

         ucontrol->value.integer.value[0] =
admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg];

         return 0;
}

static int kctl_pput_mono_to_stereo(struct snd_kcontrol *kcontrol,
                                     struct snd_ctl_elem_value *ucontrol)
{
         struct snd_soc_component *cmpnt = 
snd_soc_kcontrol_component(kcontrol);
         struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value;
         struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt);
         int value = ucontrol->value.integer.value[0];

         if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg])
                 return 0;

         admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value;

         return 1;
}


Looks like having separate callbacks make it look more cleaner. If this 
appears fine, I can send next revision.


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF
  2021-11-03 14:16   ` Takashi Iwai
  2021-11-03 14:18     ` Takashi Iwai
  2021-11-03 17:25     ` Jaroslav Kysela
@ 2021-11-08 16:08     ` Sameer Pujar
  2 siblings, 0 replies; 17+ messages in thread
From: Sameer Pujar @ 2021-11-08 16:08 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: broonie, lgirdwood, perex, tiwai, thierry.reding, jonathanh,
	alsa-devel, linux-tegra, linux-kernel



On 11/3/2021 7:46 PM, Takashi Iwai wrote:
> BTW, independent from this patch set, I noticed that those get/put
> callbacks handle the wrong type.  For enum ctls, you have to use
> ucontrol->value.enumerated.value instead of
> ucontrol->value.integer.value.  The former is long while the latter is
> int, hence they may have different sizes.
>
> Such a bug could be caught if you test once with
> CONFIG_SND_CTL_VALIDATION=y.  It's recommended to test with that
> config once for a new driver code.
>
> So, please submit the fix patch(es) for correcting the ctl value
> types, too.

Thanks for suggesting. I will include fixes for this as well in current 
series.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF
  2021-11-08 16:03       ` Sameer Pujar
@ 2021-11-08 16:16         ` Mark Brown
  0 siblings, 0 replies; 17+ messages in thread
From: Mark Brown @ 2021-11-08 16:16 UTC (permalink / raw)
  To: Sameer Pujar
  Cc: Jaroslav Kysela, Takashi Iwai, lgirdwood, tiwai, thierry.reding,
	jonathanh, alsa-devel, linux-tegra, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 879 bytes --]

On Mon, Nov 08, 2021 at 09:33:25PM +0530, Sameer Pujar wrote:

> With separate callbacks, the string checks can be removed. However for most
> of the controls, the common part is minimal. So there would be multiple
> independent small functions depending on the number of controls and the
> local variables are duplicated that many times. Would there be any concern
> on the space these local variables take? One pair of callbacks for a control
> may look like this.

...

> Looks like having separate callbacks make it look more cleaner. If this
> appears fine, I can send next revision.

Looks fine.  It'll result in more code but hopefully they should be
smaller, especially if you're using substrings rather than the full
control name to identify the control and we need to store all them
separately to the copy used to identify the control to userspace (I
didn't go check).

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2021-11-08 16:16 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-03 13:52 [PATCH v2 00/10] Fix kcontrol put callback in Tegra drivers Sameer Pujar
2021-11-03 13:52 ` [PATCH v2 01/10] ASoC: tegra: Fix kcontrol put callback in ADMAIF Sameer Pujar
2021-11-03 14:16   ` Takashi Iwai
2021-11-03 14:18     ` Takashi Iwai
2021-11-03 17:25     ` Jaroslav Kysela
2021-11-08 16:03       ` Sameer Pujar
2021-11-08 16:16         ` Mark Brown
2021-11-08 16:08     ` Sameer Pujar
2021-11-03 13:52 ` [PATCH v2 02/10] ASoC: tegra: Fix kcontrol put callback in I2S Sameer Pujar
2021-11-03 13:52 ` [PATCH v2 03/10] ASoC: tegra: Fix kcontrol put callback in DMIC Sameer Pujar
2021-11-03 13:52 ` [PATCH v2 04/10] ASoC: tegra: Fix kcontrol put callback in DSPK Sameer Pujar
2021-11-03 13:52 ` [PATCH v2 05/10] ASoC: tegra: Fix kcontrol put callback in AHUB Sameer Pujar
2021-11-03 13:52 ` [PATCH v2 06/10] ASoC: tegra: Fix kcontrol put callback in MVC Sameer Pujar
2021-11-03 13:52 ` [PATCH v2 07/10] ASoC: tegra: Fix kcontrol put callback in SFC Sameer Pujar
2021-11-03 13:52 ` [PATCH v2 08/10] ASoC: tegra: Fix kcontrol put callback in AMX Sameer Pujar
2021-11-03 13:52 ` [PATCH v2 09/10] ASoC: tegra: Fix kcontrol put callback in ADX Sameer Pujar
2021-11-03 13:52 ` [PATCH v2 10/10] ASoC: tegra: Fix kcontrol put callback in Mixer Sameer Pujar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).