* [PATCH v2 1/2] ASoC: atmel-i2s: Use devm_clk_get_enabled() for pclk
2026-11-11 10:06 [PATCH v2 0/2] ASoC: atmel-i2s: Fix clock and slot width handling phucduc.bui
@ 2026-11-11 10:06 ` phucduc.bui
2026-11-11 10:06 ` [PATCH v2 2/2] ASoC: atmel-i2s: Fix I2SC_WS slot width configuration phucduc.bui
1 sibling, 0 replies; 3+ messages in thread
From: phucduc.bui @ 2026-11-11 10:06 UTC (permalink / raw)
To: Mark Brown, Claudiu Beznea, Andrei Simion, Nicolas Ferre,
Alexandre Belloni
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Codrin Ciubotariu,
linux-sound, linux-arm-kernel, linux-kernel, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
The peripheral clock is only acquired and enabled once during
probe. Use devm_clk_get_enabled() to combine clock acquisition
and enabling into a single call.
Since the clock is now enabled during probe, request the IRQ
afterwards to ensure it is freed before the clock is disabled
during teardown.
This also removes the need for manual clock disable handling
on probe failures and in the remove callback, as the devm API
automatically handles clock cleanup.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
Changes in v2:
- Move the devm_request_irq() call below clock initialization and
dev->regmap setup, as suggested by Sashiko.
sound/soc/atmel/atmel-i2s.c | 43 +++++++++++++------------------------
1 file changed, 15 insertions(+), 28 deletions(-)
diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c
index e1d8af056234..60e885980f4c 100644
--- a/sound/soc/atmel/atmel-i2s.c
+++ b/sound/soc/atmel/atmel-i2s.c
@@ -650,21 +650,16 @@ static int atmel_i2s_probe(struct platform_device *pdev)
if (IS_ERR(regmap))
return PTR_ERR(regmap);
- /* Request IRQ. */
+ /* Get the IRQ. */
irq = platform_get_irq(pdev, 0);
if (irq < 0)
return irq;
- err = devm_request_irq(&pdev->dev, irq, atmel_i2s_interrupt, 0,
- dev_name(&pdev->dev), dev);
- if (err)
- return err;
-
- /* Get the peripheral clock. */
- dev->pclk = devm_clk_get(&pdev->dev, "pclk");
+ /* Get and enable the peripheral clock. */
+ dev->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
if (IS_ERR(dev->pclk))
return dev_err_probe(&pdev->dev, PTR_ERR(dev->pclk),
- "failed to get the peripheral clock\n");
+ "failed to get/enable the peripheral clock\n");
/* Get audio clock to generate the I2S Master Clock (I2S_MCK) */
dev->gclk = devm_clk_get_optional(&pdev->dev, "gclk");
@@ -675,6 +670,15 @@ static int atmel_i2s_probe(struct platform_device *pdev)
dev->regmap = regmap;
platform_set_drvdata(pdev, dev);
+ /*
+ * Request IRQ after initializing dev->regmap and enabling pclk,
+ * so devres frees the IRQ before disabling pclk.
+ */
+ err = devm_request_irq(&pdev->dev, irq, atmel_i2s_interrupt, 0,
+ dev_name(&pdev->dev), dev);
+ if (err)
+ return err;
+
/* Do hardware specific settings to initialize I2S_MCK generator */
if (dev->caps && dev->caps->mck_init) {
err = dev->caps->mck_init(dev, np);
@@ -682,11 +686,6 @@ static int atmel_i2s_probe(struct platform_device *pdev)
return err;
}
- /* Enable the peripheral clock. */
- err = clk_prepare_enable(dev->pclk);
- if (err)
- return err;
-
/* Get IP version. */
regmap_read(dev->regmap, ATMEL_I2SC_VERSION, &version);
dev_info(&pdev->dev, "hw version: %#x\n", version);
@@ -698,10 +697,8 @@ static int atmel_i2s_probe(struct platform_device *pdev)
err = devm_snd_soc_register_component(&pdev->dev,
&atmel_i2s_component,
&atmel_i2s_dai, 1);
- if (err) {
- clk_disable_unprepare(dev->pclk);
+ if (err)
return err;
- }
/* Prepare DMA config. */
dev->playback.addr = (dma_addr_t)mem->start + ATMEL_I2SC_THR;
@@ -712,28 +709,18 @@ static int atmel_i2s_probe(struct platform_device *pdev)
if (of_property_match_string(np, "dma-names", "rx-tx") == 0)
pcm_flags |= SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX;
err = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, pcm_flags);
- if (err) {
- clk_disable_unprepare(dev->pclk);
+ if (err)
return err;
- }
return 0;
}
-static void atmel_i2s_remove(struct platform_device *pdev)
-{
- struct atmel_i2s_dev *dev = platform_get_drvdata(pdev);
-
- clk_disable_unprepare(dev->pclk);
-}
-
static struct platform_driver atmel_i2s_driver = {
.driver = {
.name = "atmel_i2s",
.of_match_table = atmel_i2s_dt_ids,
},
.probe = atmel_i2s_probe,
- .remove = atmel_i2s_remove,
};
module_platform_driver(atmel_i2s_driver);
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread* [PATCH v2 2/2] ASoC: atmel-i2s: Fix I2SC_WS slot width configuration
2026-11-11 10:06 [PATCH v2 0/2] ASoC: atmel-i2s: Fix clock and slot width handling phucduc.bui
2026-11-11 10:06 ` [PATCH v2 1/2] ASoC: atmel-i2s: Use devm_clk_get_enabled() for pclk phucduc.bui
@ 2026-11-11 10:06 ` phucduc.bui
1 sibling, 0 replies; 3+ messages in thread
From: phucduc.bui @ 2026-11-11 10:06 UTC (permalink / raw)
To: Mark Brown, Claudiu Beznea, Andrei Simion, Nicolas Ferre,
Alexandre Belloni
Cc: Liam Girdwood, Jaroslav Kysela, Takashi Iwai, Codrin Ciubotariu,
linux-sound, linux-arm-kernel, linux-kernel, bui duc phuc
From: bui duc phuc <phucduc.bui@gmail.com>
The atmel_i2s_hw_params() function configures the PCM formats
S18_3LE, S20_3LE and S24_3LE, which require a 24-bit I2SC_WS
slot width.
However, ATMEL_I2SC_MR_IWS is missing from the mask passed to
regmap_update_bits() when updating ATMEL_I2SC_MR. As a result,
the IWS bit is never updated, potentially leaving the slot width
at 32 bits.
Add ATMEL_I2SC_MR_IWS to the mask to ensure the slot width is
configured correctly.
Fixes: 3b7961a326f8 ("ASoC: atmel-i2s: Fix usage of capture and playback at the same time")
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
---
sound/soc/atmel/atmel-i2s.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c
index 60e885980f4c..d23ac43590d8 100644
--- a/sound/soc/atmel/atmel-i2s.c
+++ b/sound/soc/atmel/atmel-i2s.c
@@ -329,7 +329,7 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
int ret;
mr_mask = ATMEL_I2SC_MR_FORMAT_MASK | ATMEL_I2SC_MR_MODE_MASK |
- ATMEL_I2SC_MR_DATALENGTH_MASK;
+ ATMEL_I2SC_MR_DATALENGTH_MASK | ATMEL_I2SC_MR_IWS;
if (is_playback)
mr_mask |= ATMEL_I2SC_MR_TXMONO;
else
--
2.43.0
^ permalink raw reply [flat|nested] 3+ messages in thread