diff mbox series

[v2] ASoC: atmel: mchp-pdmc: Retain Non-Runtime Controls

Message ID 20240913120621.79088-1-andrei.simion@microchip.com (mailing list archive)
State New, archived
Headers show
Series [v2] ASoC: atmel: mchp-pdmc: Retain Non-Runtime Controls | expand

Commit Message

Andrei Simion Sept. 13, 2024, 12:06 p.m. UTC
From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>

Avoid removing these controls, as doing so can cause issues if the stream
is initiated from another control. Ensure these controls remain intact when
the stream is started or finished. Instead of removing them, return an
-EBUSY error code to indicate that the controller is busy, especially when
the audio filter and the SINC filter are in use.

[andrei.simion@microchip.com: Reword the commit title and the commit
message. Replace spinlock and busy variable with atomic_t busy_stream.]

Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com>
Signed-off-by: Andrei Simion <andrei.simion@microchip.com>
---
v1 -> v2:
- drop spinlock and u8 busy:1;
- use atomic_t variable busy_stream
- use atomic_read, atomic_set
---
 sound/soc/atmel/mchp-pdmc.c | 57 ++++++++++---------------------------
 1 file changed, 15 insertions(+), 42 deletions(-)


base-commit: 5acd9952f95fb4b7da6d09a3be39195a80845eb6

Comments

Mark Brown Sept. 13, 2024, 3:59 p.m. UTC | #1
On Fri, 13 Sep 2024 15:06:22 +0300, Andrei Simion wrote:
> Avoid removing these controls, as doing so can cause issues if the stream
> is initiated from another control. Ensure these controls remain intact when
> the stream is started or finished. Instead of removing them, return an
> -EBUSY error code to indicate that the controller is busy, especially when
> the audio filter and the SINC filter are in use.
> 
> [andrei.simion@microchip.com: Reword the commit title and the commit
> message. Replace spinlock and busy variable with atomic_t busy_stream.]
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next

Thanks!

[1/1] ASoC: atmel: mchp-pdmc: Retain Non-Runtime Controls
      commit: 2ed1a4a5c0058dfd78f5037576d668a37d0ec609

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark
diff mbox series

Patch

diff --git a/sound/soc/atmel/mchp-pdmc.c b/sound/soc/atmel/mchp-pdmc.c
index d97d153ee375..939cd44ebc8a 100644
--- a/sound/soc/atmel/mchp-pdmc.c
+++ b/sound/soc/atmel/mchp-pdmc.c
@@ -124,6 +124,7 @@  struct mchp_pdmc {
 	int mic_no;
 	int sinc_order;
 	bool audio_filter_en;
+	atomic_t busy_stream;
 };
 
 static const char *const mchp_pdmc_sinc_filter_order_text[] = {
@@ -167,6 +168,10 @@  static int mchp_pdmc_sinc_order_put(struct snd_kcontrol *kcontrol,
 		return -EINVAL;
 
 	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
+
+	if (atomic_read(&dd->busy_stream))
+		return -EBUSY;
+
 	if (val == dd->sinc_order)
 		return 0;
 
@@ -193,6 +198,9 @@  static int mchp_pdmc_af_put(struct snd_kcontrol *kcontrol,
 	struct mchp_pdmc *dd = snd_soc_component_get_drvdata(component);
 	bool af = uvalue->value.integer.value[0] ? true : false;
 
+	if (atomic_read(&dd->busy_stream))
+		return -EBUSY;
+
 	if (dd->audio_filter_en == af)
 		return 0;
 
@@ -379,52 +387,10 @@  static const struct snd_kcontrol_new mchp_pdmc_snd_controls[] = {
 	},
 };
 
-static int mchp_pdmc_close(struct snd_soc_component *component,
-			   struct snd_pcm_substream *substream)
-{
-	return snd_soc_add_component_controls(component, mchp_pdmc_snd_controls,
-					      ARRAY_SIZE(mchp_pdmc_snd_controls));
-}
-
-static int mchp_pdmc_open(struct snd_soc_component *component,
-			  struct snd_pcm_substream *substream)
-{
-	int i;
-
-	/* remove controls that can't be changed at runtime */
-	for (i = 0; i < ARRAY_SIZE(mchp_pdmc_snd_controls); i++) {
-		const struct snd_kcontrol_new *control = &mchp_pdmc_snd_controls[i];
-		struct snd_ctl_elem_id id;
-		int err;
-
-		if (component->name_prefix)
-			snprintf(id.name, sizeof(id.name), "%s %s", component->name_prefix,
-				 control->name);
-		else
-			strscpy(id.name, control->name, sizeof(id.name));
-
-		id.numid = 0;
-		id.iface = control->iface;
-		id.device = control->device;
-		id.subdevice = control->subdevice;
-		id.index = control->index;
-		err = snd_ctl_remove_id(component->card->snd_card, &id);
-		if (err < 0)
-			dev_err(component->dev, "%d: Failed to remove %s\n", err,
-				control->name);
-	}
-
-	return 0;
-}
-
 static const struct snd_soc_component_driver mchp_pdmc_dai_component = {
 	.name = "mchp-pdmc",
 	.controls = mchp_pdmc_snd_controls,
 	.num_controls = ARRAY_SIZE(mchp_pdmc_snd_controls),
-	.open = &mchp_pdmc_open,
-	.close = &mchp_pdmc_close,
-	.legacy_dai_naming = 1,
-	.trigger_start = SND_SOC_TRIGGER_ORDER_LDC,
 };
 
 static const unsigned int mchp_pdmc_1mic[] = {1};
@@ -587,6 +553,11 @@  static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
 			cfgr_val |= MCHP_PDMC_CFGR_BSSEL(i);
 	}
 
+	/*
+	 * from these point forward, we consider the controller busy, so the
+	 * audio filter and SINC order can't be changed
+	 */
+	atomic_set(&dd->busy_stream, 1);
 	for (osr_start = dd->audio_filter_en ? 64 : 8;
 	     osr_start <= 256 && best_diff_rate; osr_start *= 2) {
 		long round_rate;
@@ -1143,6 +1114,8 @@  static void mchp_pdmc_remove(struct platform_device *pdev)
 {
 	struct mchp_pdmc *dd = platform_get_drvdata(pdev);
 
+	atomic_set(&dd->busy_stream, 0);
+
 	if (!pm_runtime_status_suspended(dd->dev))
 		mchp_pdmc_runtime_suspend(dd->dev);