Skip to content

Commit ce0138d

Browse files
claudiubezneagregkh
authored andcommitted
ASoC: da7213: Use component driver suspend/resume
[ Upstream commit 249d96b492efb7a773296ab2c62179918301c146 ] Since snd_soc_suspend() is invoked through snd_soc_pm_ops->suspend(), and snd_soc_pm_ops is associated with the soc_driver (defined in sound/soc/soc-core.c), and there is no parent-child relationship between the soc_driver and the DA7213 codec driver, the power management subsystem does not enforce a specific suspend/resume order between the DA7213 driver and the soc_driver. Because of this, the different codec component functionalities, called from snd_soc_resume() to reconfigure various functions, can race with the DA7213 struct dev_pm_ops::resume function, leading to misapplied configuration. This occasionally results in clipped sound. Fix this by dropping the struct dev_pm_ops::{suspend, resume} and use instead struct snd_soc_component_driver::{suspend, resume}. This ensures the proper configuration sequence is handled by the ASoC subsystem. Cc: [email protected] Fixes: 431e040 ("ASoC: da7213: Add suspend to RAM support") Signed-off-by: Claudiu Beznea <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]> Signed-off-by: Sasha Levin <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent afd2d22 commit ce0138d

2 files changed

Lines changed: 45 additions & 25 deletions

File tree

sound/soc/codecs/da7213.c

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2124,11 +2124,50 @@ static int da7213_probe(struct snd_soc_component *component)
21242124
return 0;
21252125
}
21262126

2127+
static int da7213_runtime_suspend(struct device *dev)
2128+
{
2129+
struct da7213_priv *da7213 = dev_get_drvdata(dev);
2130+
2131+
regcache_cache_only(da7213->regmap, true);
2132+
regcache_mark_dirty(da7213->regmap);
2133+
regulator_bulk_disable(DA7213_NUM_SUPPLIES, da7213->supplies);
2134+
2135+
return 0;
2136+
}
2137+
2138+
static int da7213_runtime_resume(struct device *dev)
2139+
{
2140+
struct da7213_priv *da7213 = dev_get_drvdata(dev);
2141+
int ret;
2142+
2143+
ret = regulator_bulk_enable(DA7213_NUM_SUPPLIES, da7213->supplies);
2144+
if (ret < 0)
2145+
return ret;
2146+
regcache_cache_only(da7213->regmap, false);
2147+
return regcache_sync(da7213->regmap);
2148+
}
2149+
2150+
static int da7213_suspend(struct snd_soc_component *component)
2151+
{
2152+
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
2153+
2154+
return da7213_runtime_suspend(da7213->dev);
2155+
}
2156+
2157+
static int da7213_resume(struct snd_soc_component *component)
2158+
{
2159+
struct da7213_priv *da7213 = snd_soc_component_get_drvdata(component);
2160+
2161+
return da7213_runtime_resume(da7213->dev);
2162+
}
2163+
21272164
static const struct snd_soc_component_driver soc_component_dev_da7213 = {
21282165
.probe = da7213_probe,
21292166
.set_bias_level = da7213_set_bias_level,
21302167
.controls = da7213_snd_controls,
21312168
.num_controls = ARRAY_SIZE(da7213_snd_controls),
2169+
.suspend = da7213_suspend,
2170+
.resume = da7213_resume,
21322171
.dapm_widgets = da7213_dapm_widgets,
21332172
.num_dapm_widgets = ARRAY_SIZE(da7213_dapm_widgets),
21342173
.dapm_routes = da7213_audio_map,
@@ -2175,6 +2214,8 @@ static int da7213_i2c_probe(struct i2c_client *i2c)
21752214
if (!da7213->fin_min_rate)
21762215
return -EINVAL;
21772216

2217+
da7213->dev = &i2c->dev;
2218+
21782219
i2c_set_clientdata(i2c, da7213);
21792220

21802221
/* Get required supplies */
@@ -2224,31 +2265,9 @@ static void da7213_i2c_remove(struct i2c_client *i2c)
22242265
pm_runtime_disable(&i2c->dev);
22252266
}
22262267

2227-
static int da7213_runtime_suspend(struct device *dev)
2228-
{
2229-
struct da7213_priv *da7213 = dev_get_drvdata(dev);
2230-
2231-
regcache_cache_only(da7213->regmap, true);
2232-
regcache_mark_dirty(da7213->regmap);
2233-
regulator_bulk_disable(DA7213_NUM_SUPPLIES, da7213->supplies);
2234-
2235-
return 0;
2236-
}
2237-
2238-
static int da7213_runtime_resume(struct device *dev)
2239-
{
2240-
struct da7213_priv *da7213 = dev_get_drvdata(dev);
2241-
int ret;
2242-
2243-
ret = regulator_bulk_enable(DA7213_NUM_SUPPLIES, da7213->supplies);
2244-
if (ret < 0)
2245-
return ret;
2246-
regcache_cache_only(da7213->regmap, false);
2247-
return regcache_sync(da7213->regmap);
2248-
}
2249-
2250-
static DEFINE_RUNTIME_DEV_PM_OPS(da7213_pm, da7213_runtime_suspend,
2251-
da7213_runtime_resume, NULL);
2268+
static const struct dev_pm_ops da7213_pm = {
2269+
RUNTIME_PM_OPS(da7213_runtime_suspend, da7213_runtime_resume, NULL)
2270+
};
22522271

22532272
static const struct i2c_device_id da7213_i2c_id[] = {
22542273
{ "da7213" },

sound/soc/codecs/da7213.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -595,6 +595,7 @@ enum da7213_supplies {
595595
/* Codec private data */
596596
struct da7213_priv {
597597
struct regmap *regmap;
598+
struct device *dev;
598599
struct mutex ctrl_lock;
599600
struct regulator_bulk_data supplies[DA7213_NUM_SUPPLIES];
600601
struct clk *mclk;

0 commit comments

Comments
 (0)