Commit cec5b01f authored by Mac Chiang's avatar Mac Chiang Committed by Mark Brown

ASoC: max98357a: avoid speaker pop when playback startup

Loud speaker pop happens during playback even when in slience
playback. Specify Max98357a amp delay times to make sure
clocks are always earlier than sdmode on.
Signed-off-by: default avatarMac Chiang <mac.chiang@intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4b9b73b8
...@@ -9,6 +9,10 @@ Optional properties: ...@@ -9,6 +9,10 @@ Optional properties:
- sdmode-gpios : GPIO specifier for the chip's SD_MODE pin. - sdmode-gpios : GPIO specifier for the chip's SD_MODE pin.
If this option is not specified then driver does not manage If this option is not specified then driver does not manage
the pin state (e.g. chip is always on). the pin state (e.g. chip is always on).
- sdmode-delay : specify delay time for SD_MODE pin.
If this option is specified, which means it's required i2s clocks
ready before SD_MODE is unmuted in order to avoid the speaker pop noise.
It's observed that 5ms is sufficient.
Example: Example:
......
...@@ -19,24 +19,42 @@ ...@@ -19,24 +19,42 @@
#include <sound/soc-dai.h> #include <sound/soc-dai.h>
#include <sound/soc-dapm.h> #include <sound/soc-dapm.h>
struct max98357a_priv {
struct delayed_work enable_sdmode_work;
struct gpio_desc *sdmode;
unsigned int sdmode_delay;
};
static void max98357a_enable_sdmode_work(struct work_struct *work)
{
struct max98357a_priv *max98357a =
container_of(work, struct max98357a_priv,
enable_sdmode_work.work);
gpiod_set_value(max98357a->sdmode, 1);
}
static int max98357a_daiops_trigger(struct snd_pcm_substream *substream, static int max98357a_daiops_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai) int cmd, struct snd_soc_dai *dai)
{ {
struct gpio_desc *sdmode = snd_soc_dai_get_drvdata(dai); struct max98357a_priv *max98357a = snd_soc_dai_get_drvdata(dai);
if (!sdmode) if (!max98357a->sdmode)
return 0; return 0;
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
gpiod_set_value(sdmode, 1); queue_delayed_work(system_power_efficient_wq,
&max98357a->enable_sdmode_work,
msecs_to_jiffies(max98357a->sdmode_delay));
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
gpiod_set_value(sdmode, 0); cancel_delayed_work_sync(&max98357a->enable_sdmode_work);
gpiod_set_value(max98357a->sdmode, 0);
break; break;
} }
...@@ -90,14 +108,33 @@ static struct snd_soc_dai_driver max98357a_dai_driver = { ...@@ -90,14 +108,33 @@ static struct snd_soc_dai_driver max98357a_dai_driver = {
static int max98357a_platform_probe(struct platform_device *pdev) static int max98357a_platform_probe(struct platform_device *pdev)
{ {
struct gpio_desc *sdmode; struct max98357a_priv *max98357a;
int ret;
sdmode = devm_gpiod_get_optional(&pdev->dev, max98357a = devm_kzalloc(&pdev->dev, sizeof(*max98357a), GFP_KERNEL);
if (!max98357a)
return -ENOMEM;
max98357a->sdmode = devm_gpiod_get_optional(&pdev->dev,
"sdmode", GPIOD_OUT_LOW); "sdmode", GPIOD_OUT_LOW);
if (IS_ERR(sdmode))
return PTR_ERR(sdmode);
dev_set_drvdata(&pdev->dev, sdmode); if (IS_ERR(max98357a->sdmode))
return PTR_ERR(max98357a->sdmode);
ret = device_property_read_u32(&pdev->dev, "sdmode-delay",
&max98357a->sdmode_delay);
if (ret) {
max98357a->sdmode_delay = 0;
dev_dbg(&pdev->dev,
"no optional property 'sdmode-delay' found, default: no delay\n");
}
dev_set_drvdata(&pdev->dev, max98357a);
INIT_DELAYED_WORK(&max98357a->enable_sdmode_work,
max98357a_enable_sdmode_work);
return devm_snd_soc_register_component(&pdev->dev, return devm_snd_soc_register_component(&pdev->dev,
&max98357a_component_driver, &max98357a_component_driver,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment