Skip to content

Commit 2ed1a4a

Browse files
codrin989broonie
authored andcommitted
ASoC: atmel: mchp-pdmc: Retain Non-Runtime Controls
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. [[email protected]: Reword the commit title and the commit message. Replace spinlock and busy variable with atomic_t busy_stream.] Signed-off-by: Codrin Ciubotariu <[email protected]> Signed-off-by: Andrei Simion <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 49b2597 commit 2ed1a4a

File tree

1 file changed

+15
-42
lines changed

1 file changed

+15
-42
lines changed

sound/soc/atmel/mchp-pdmc.c

Lines changed: 15 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ struct mchp_pdmc {
124124
int mic_no;
125125
int sinc_order;
126126
bool audio_filter_en;
127+
atomic_t busy_stream;
127128
};
128129

129130
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,
167168
return -EINVAL;
168169

169170
val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
171+
172+
if (atomic_read(&dd->busy_stream))
173+
return -EBUSY;
174+
170175
if (val == dd->sinc_order)
171176
return 0;
172177

@@ -193,6 +198,9 @@ static int mchp_pdmc_af_put(struct snd_kcontrol *kcontrol,
193198
struct mchp_pdmc *dd = snd_soc_component_get_drvdata(component);
194199
bool af = uvalue->value.integer.value[0] ? true : false;
195200

201+
if (atomic_read(&dd->busy_stream))
202+
return -EBUSY;
203+
196204
if (dd->audio_filter_en == af)
197205
return 0;
198206

@@ -379,52 +387,10 @@ static const struct snd_kcontrol_new mchp_pdmc_snd_controls[] = {
379387
},
380388
};
381389

382-
static int mchp_pdmc_close(struct snd_soc_component *component,
383-
struct snd_pcm_substream *substream)
384-
{
385-
return snd_soc_add_component_controls(component, mchp_pdmc_snd_controls,
386-
ARRAY_SIZE(mchp_pdmc_snd_controls));
387-
}
388-
389-
static int mchp_pdmc_open(struct snd_soc_component *component,
390-
struct snd_pcm_substream *substream)
391-
{
392-
int i;
393-
394-
/* remove controls that can't be changed at runtime */
395-
for (i = 0; i < ARRAY_SIZE(mchp_pdmc_snd_controls); i++) {
396-
const struct snd_kcontrol_new *control = &mchp_pdmc_snd_controls[i];
397-
struct snd_ctl_elem_id id;
398-
int err;
399-
400-
if (component->name_prefix)
401-
snprintf(id.name, sizeof(id.name), "%s %s", component->name_prefix,
402-
control->name);
403-
else
404-
strscpy(id.name, control->name, sizeof(id.name));
405-
406-
id.numid = 0;
407-
id.iface = control->iface;
408-
id.device = control->device;
409-
id.subdevice = control->subdevice;
410-
id.index = control->index;
411-
err = snd_ctl_remove_id(component->card->snd_card, &id);
412-
if (err < 0)
413-
dev_err(component->dev, "%d: Failed to remove %s\n", err,
414-
control->name);
415-
}
416-
417-
return 0;
418-
}
419-
420390
static const struct snd_soc_component_driver mchp_pdmc_dai_component = {
421391
.name = "mchp-pdmc",
422392
.controls = mchp_pdmc_snd_controls,
423393
.num_controls = ARRAY_SIZE(mchp_pdmc_snd_controls),
424-
.open = &mchp_pdmc_open,
425-
.close = &mchp_pdmc_close,
426-
.legacy_dai_naming = 1,
427-
.trigger_start = SND_SOC_TRIGGER_ORDER_LDC,
428394
};
429395

430396
static const unsigned int mchp_pdmc_1mic[] = {1};
@@ -587,6 +553,11 @@ static int mchp_pdmc_hw_params(struct snd_pcm_substream *substream,
587553
cfgr_val |= MCHP_PDMC_CFGR_BSSEL(i);
588554
}
589555

556+
/*
557+
* from these point forward, we consider the controller busy, so the
558+
* audio filter and SINC order can't be changed
559+
*/
560+
atomic_set(&dd->busy_stream, 1);
590561
for (osr_start = dd->audio_filter_en ? 64 : 8;
591562
osr_start <= 256 && best_diff_rate; osr_start *= 2) {
592563
long round_rate;
@@ -1143,6 +1114,8 @@ static void mchp_pdmc_remove(struct platform_device *pdev)
11431114
{
11441115
struct mchp_pdmc *dd = platform_get_drvdata(pdev);
11451116

1117+
atomic_set(&dd->busy_stream, 0);
1118+
11461119
if (!pm_runtime_status_suspended(dd->dev))
11471120
mchp_pdmc_runtime_suspend(dd->dev);
11481121

0 commit comments

Comments
 (0)