mirror of
https://github.com/torvalds/linux.git
synced 2024-12-03 09:31:26 +00:00
ASoC: SoundWire codecs: improve pm_runtime handling
Merge series from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>: This patchset improves the pm_runtime behavior in rare corner cases identified by the Intel CI in the last 6 months. a) in stress-tests, it's not uncommon to see the following type of warnings when the codec reports as ATTACHED "rt711 sdw:0:025d:0711:00: runtime PM trying to activate child device sdw:0:025d:0711:00 but parent (sdw-master-0) is not active" This warning was not correlated with any functional issue, but it exposed a design issue on when to enable pm_runtime. The recommended practice in the pm_runtime documentation is to keep the devices in 'suspended' mode and mark them as 'active' when they are really functional. b) enabling pm_runtime when the codec reports as ATTACHED also creates a problematic case when the ASoC pm_runtime_get_sync() will silently fail due to the -EACCESS error handling. This can happen when playback starts before the codec is enumerated. This patchset modifies the initial stages so that codecs are pm_runtime enabled in the .probe() callback, but become pm_runtime 'active' only when they report present. This is better aligned with the design of the pm_runtime helpers and improved CI results significantly. This patchset modifies all existing SoundWire codecs (except Qualcomm ones), but the pattern of changes is exactly the same in all patches.
This commit is contained in:
commit
5a119551b6
@ -160,28 +160,17 @@ static int max98363_io_init(struct sdw_slave *slave)
|
||||
struct max98363_priv *max98363 = dev_get_drvdata(dev);
|
||||
int ret, reg;
|
||||
|
||||
if (max98363->first_hw_init) {
|
||||
regcache_cache_only(max98363->regmap, false);
|
||||
regcache_cache_only(max98363->regmap, false);
|
||||
if (max98363->first_hw_init)
|
||||
regcache_cache_bypass(max98363->regmap, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
if (!max98363->first_hw_init) {
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
if (!max98363->first_hw_init)
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(dev);
|
||||
|
||||
ret = regmap_read(max98363->regmap, MAX98363_R21FF_REV_ID, ®);
|
||||
@ -409,6 +398,8 @@ static int max98363_init(struct sdw_slave *slave, struct regmap *regmap)
|
||||
max98363->regmap = regmap;
|
||||
max98363->slave = slave;
|
||||
|
||||
regcache_cache_only(max98363->regmap, true);
|
||||
|
||||
max98363->hw_init = false;
|
||||
max98363->first_hw_init = false;
|
||||
|
||||
@ -416,10 +407,26 @@ static int max98363_init(struct sdw_slave *slave, struct regmap *regmap)
|
||||
ret = devm_snd_soc_register_component(dev, &soc_codec_dev_max98363,
|
||||
max98363_dai,
|
||||
ARRAY_SIZE(max98363_dai));
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to register codec: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max98363_sdw_probe(struct sdw_slave *slave,
|
||||
|
@ -361,28 +361,17 @@ static int max98373_io_init(struct sdw_slave *slave)
|
||||
struct device *dev = &slave->dev;
|
||||
struct max98373_priv *max98373 = dev_get_drvdata(dev);
|
||||
|
||||
if (max98373->first_hw_init) {
|
||||
regcache_cache_only(max98373->regmap, false);
|
||||
regcache_cache_only(max98373->regmap, false);
|
||||
if (max98373->first_hw_init)
|
||||
regcache_cache_bypass(max98373->regmap, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
if (!max98373->first_hw_init) {
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
if (!max98373->first_hw_init)
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(dev);
|
||||
|
||||
/* Software Reset */
|
||||
@ -753,6 +742,8 @@ static int max98373_init(struct sdw_slave *slave, struct regmap *regmap)
|
||||
max98373->regmap = regmap;
|
||||
max98373->slave = slave;
|
||||
|
||||
regcache_cache_only(max98373->regmap, true);
|
||||
|
||||
max98373->cache_num = ARRAY_SIZE(max98373_sdw_cache_reg);
|
||||
max98373->cache = devm_kcalloc(dev, max98373->cache_num,
|
||||
sizeof(*max98373->cache),
|
||||
@ -773,10 +764,27 @@ static int max98373_init(struct sdw_slave *slave, struct regmap *regmap)
|
||||
ret = devm_snd_soc_register_component(dev, &soc_codec_dev_max98373_sdw,
|
||||
max98373_sdw_dai,
|
||||
ARRAY_SIZE(max98373_sdw_dai));
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "Failed to register codec: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max98373_update_status(struct sdw_slave *slave,
|
||||
@ -834,10 +842,7 @@ static int max98373_sdw_probe(struct sdw_slave *slave,
|
||||
|
||||
static int max98373_sdw_remove(struct sdw_slave *slave)
|
||||
{
|
||||
struct max98373_priv *max98373 = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (max98373->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -218,28 +218,17 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt1308->hw_init)
|
||||
return 0;
|
||||
|
||||
if (rt1308->first_hw_init) {
|
||||
regcache_cache_only(rt1308->regmap, false);
|
||||
regcache_cache_only(rt1308->regmap, false);
|
||||
if (rt1308->first_hw_init)
|
||||
regcache_cache_bypass(rt1308->regmap, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
if (!rt1308->first_hw_init) {
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
|
||||
if (!rt1308->first_hw_init)
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
|
||||
/* sw reset */
|
||||
@ -626,6 +615,9 @@ static int rt1308_sdw_component_probe(struct snd_soc_component *component)
|
||||
rt1308->component = component;
|
||||
rt1308_sdw_parse_dt(rt1308, &rt1308->sdw_slave->dev);
|
||||
|
||||
if (!rt1308->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
@ -688,6 +680,8 @@ static int rt1308_sdw_init(struct device *dev, struct regmap *regmap,
|
||||
rt1308->sdw_slave = slave;
|
||||
rt1308->regmap = regmap;
|
||||
|
||||
regcache_cache_only(rt1308->regmap, true);
|
||||
|
||||
/*
|
||||
* Mark hw_init to false
|
||||
* HW init will be performed when device reports present
|
||||
@ -699,10 +693,27 @@ static int rt1308_sdw_init(struct device *dev, struct regmap *regmap,
|
||||
&soc_component_sdw_rt1308,
|
||||
rt1308_sdw_dai,
|
||||
ARRAY_SIZE(rt1308_sdw_dai));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(&slave->dev, "%s\n", __func__);
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
return ret;
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1308_sdw_probe(struct sdw_slave *slave,
|
||||
@ -715,17 +726,12 @@ static int rt1308_sdw_probe(struct sdw_slave *slave,
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
rt1308_sdw_init(&slave->dev, regmap, slave);
|
||||
|
||||
return 0;
|
||||
return rt1308_sdw_init(&slave->dev, regmap, slave);
|
||||
}
|
||||
|
||||
static int rt1308_sdw_remove(struct sdw_slave *slave)
|
||||
{
|
||||
struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (rt1308->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -272,25 +272,16 @@ static int rt1316_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt1316->hw_init)
|
||||
return 0;
|
||||
|
||||
regcache_cache_only(rt1316->regmap, false);
|
||||
if (rt1316->first_hw_init) {
|
||||
regcache_cache_only(rt1316->regmap, false);
|
||||
regcache_cache_bypass(rt1316->regmap, true);
|
||||
} else {
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
@ -607,6 +598,9 @@ static int rt1316_sdw_component_probe(struct snd_soc_component *component)
|
||||
rt1316->component = component;
|
||||
rt1316_sdw_parse_dt(rt1316, &rt1316->sdw_slave->dev);
|
||||
|
||||
if (!rt1316->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
@ -674,6 +668,8 @@ static int rt1316_sdw_init(struct device *dev, struct regmap *regmap,
|
||||
rt1316->sdw_slave = slave;
|
||||
rt1316->regmap = regmap;
|
||||
|
||||
regcache_cache_only(rt1316->regmap, true);
|
||||
|
||||
/*
|
||||
* Mark hw_init to false
|
||||
* HW init will be performed when device reports present
|
||||
@ -685,10 +681,27 @@ static int rt1316_sdw_init(struct device *dev, struct regmap *regmap,
|
||||
&soc_component_sdw_rt1316,
|
||||
rt1316_sdw_dai,
|
||||
ARRAY_SIZE(rt1316_sdw_dai));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(&slave->dev, "%s\n", __func__);
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
return ret;
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt1316_sdw_probe(struct sdw_slave *slave,
|
||||
@ -706,10 +719,7 @@ static int rt1316_sdw_probe(struct sdw_slave *slave,
|
||||
|
||||
static int rt1316_sdw_remove(struct sdw_slave *slave)
|
||||
{
|
||||
struct rt1316_sdw_priv *rt1316 = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (rt1316->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -408,25 +408,15 @@ static int rt1318_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt1318->hw_init)
|
||||
return 0;
|
||||
|
||||
regcache_cache_only(rt1318->regmap, false);
|
||||
if (rt1318->first_hw_init) {
|
||||
regcache_cache_only(rt1318->regmap, false);
|
||||
regcache_cache_bypass(rt1318->regmap, true);
|
||||
} else {
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
@ -686,6 +676,9 @@ static int rt1318_sdw_component_probe(struct snd_soc_component *component)
|
||||
|
||||
rt1318->component = component;
|
||||
|
||||
if (!rt1318->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
dev_dbg(&rt1318->sdw_slave->dev, "%s pm_runtime_resume, ret=%d", __func__, ret);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
@ -752,6 +745,8 @@ static int rt1318_sdw_init(struct device *dev, struct regmap *regmap,
|
||||
rt1318->sdw_slave = slave;
|
||||
rt1318->regmap = regmap;
|
||||
|
||||
regcache_cache_only(rt1318->regmap, true);
|
||||
|
||||
/*
|
||||
* Mark hw_init to false
|
||||
* HW init will be performed when device reports present
|
||||
@ -763,8 +758,25 @@ static int rt1318_sdw_init(struct device *dev, struct regmap *regmap,
|
||||
&soc_component_sdw_rt1318,
|
||||
rt1318_sdw_dai,
|
||||
ARRAY_SIZE(rt1318_sdw_dai));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(&slave->dev, "%s\n", __func__);
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -784,10 +796,7 @@ static int rt1318_sdw_probe(struct sdw_slave *slave,
|
||||
|
||||
static int rt1318_sdw_remove(struct sdw_slave *slave)
|
||||
{
|
||||
struct rt1318_sdw_priv *rt1318 = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (rt1318->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -322,6 +322,9 @@ static int rt5682_sdw_init(struct device *dev, struct regmap *regmap,
|
||||
return ret;
|
||||
}
|
||||
|
||||
regcache_cache_only(rt5682->sdw_regmap, true);
|
||||
regcache_cache_only(rt5682->regmap, true);
|
||||
|
||||
/*
|
||||
* Mark hw_init to false
|
||||
* HW init will be performed when device reports present
|
||||
@ -336,7 +339,25 @@ static int rt5682_sdw_init(struct device *dev, struct regmap *regmap,
|
||||
ret = devm_snd_soc_register_component(dev,
|
||||
&rt5682_soc_component_dev,
|
||||
rt5682_dai, ARRAY_SIZE(rt5682_dai));
|
||||
dev_dbg(&slave->dev, "%s\n", __func__);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -352,30 +373,20 @@ static int rt5682_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt5682->hw_init)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
*/
|
||||
if (!rt5682->first_hw_init) {
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
regcache_cache_only(rt5682->sdw_regmap, false);
|
||||
regcache_cache_only(rt5682->regmap, false);
|
||||
if (rt5682->first_hw_init)
|
||||
regcache_cache_bypass(rt5682->regmap, true);
|
||||
|
||||
/*
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
if (!rt5682->first_hw_init)
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
|
||||
if (rt5682->first_hw_init) {
|
||||
regcache_cache_only(rt5682->regmap, false);
|
||||
regcache_cache_bypass(rt5682->regmap, true);
|
||||
}
|
||||
|
||||
while (loop > 0) {
|
||||
regmap_read(rt5682->regmap, RT5682_DEVICE_ID, &val);
|
||||
if (val == DEVICE_ID)
|
||||
@ -674,9 +685,7 @@ static int rt5682_sdw_probe(struct sdw_slave *slave,
|
||||
if (IS_ERR(regmap))
|
||||
return -EINVAL;
|
||||
|
||||
rt5682_sdw_init(&slave->dev, regmap, slave);
|
||||
|
||||
return 0;
|
||||
return rt5682_sdw_init(&slave->dev, regmap, slave);
|
||||
}
|
||||
|
||||
static int rt5682_sdw_remove(struct sdw_slave *slave)
|
||||
@ -686,8 +695,7 @@ static int rt5682_sdw_remove(struct sdw_slave *slave)
|
||||
if (rt5682->hw_init)
|
||||
cancel_delayed_work_sync(&rt5682->jack_detect_work);
|
||||
|
||||
if (rt5682->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -707,6 +715,7 @@ static int __maybe_unused rt5682_dev_suspend(struct device *dev)
|
||||
|
||||
cancel_delayed_work_sync(&rt5682->jack_detect_work);
|
||||
|
||||
regcache_cache_only(rt5682->sdw_regmap, true);
|
||||
regcache_cache_only(rt5682->regmap, true);
|
||||
regcache_mark_dirty(rt5682->regmap);
|
||||
|
||||
@ -771,6 +780,7 @@ static int __maybe_unused rt5682_dev_resume(struct device *dev)
|
||||
|
||||
regmap_sync:
|
||||
slave->unattach_request = 0;
|
||||
regcache_cache_only(rt5682->sdw_regmap, false);
|
||||
regcache_cache_only(rt5682->regmap, false);
|
||||
regcache_sync(rt5682->regmap);
|
||||
|
||||
|
@ -1017,6 +1017,9 @@ static int rt5682_set_jack_detect(struct snd_soc_component *component,
|
||||
|
||||
rt5682->hs_jack = hs_jack;
|
||||
|
||||
if (rt5682->is_sdw && !rt5682->first_hw_init)
|
||||
return 0;
|
||||
|
||||
if (!hs_jack) {
|
||||
regmap_update_bits(rt5682->regmap, RT5682_IRQ_CTRL_2,
|
||||
RT5682_JD1_EN_MASK, RT5682_JD1_DIS);
|
||||
|
@ -452,9 +452,7 @@ static int rt700_sdw_probe(struct sdw_slave *slave,
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
rt700_init(&slave->dev, sdw_regmap, regmap, slave);
|
||||
|
||||
return 0;
|
||||
return rt700_init(&slave->dev, sdw_regmap, regmap, slave);
|
||||
}
|
||||
|
||||
static int rt700_sdw_remove(struct sdw_slave *slave)
|
||||
@ -466,8 +464,7 @@ static int rt700_sdw_remove(struct sdw_slave *slave)
|
||||
cancel_delayed_work_sync(&rt700->jack_btn_check_work);
|
||||
}
|
||||
|
||||
if (rt700->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -320,6 +320,10 @@ static int rt700_set_jack_detect(struct snd_soc_component *component,
|
||||
|
||||
rt700->hs_jack = hs_jack;
|
||||
|
||||
/* we can only resume if the device was initialized at least once */
|
||||
if (!rt700->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume_and_get(component->dev);
|
||||
if (ret < 0) {
|
||||
if (ret != -EACCES) {
|
||||
@ -823,6 +827,9 @@ static int rt700_probe(struct snd_soc_component *component)
|
||||
|
||||
rt700->component = component;
|
||||
|
||||
if (!rt700->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
@ -1099,6 +1106,8 @@ int rt700_init(struct device *dev, struct regmap *sdw_regmap,
|
||||
rt700->sdw_regmap = sdw_regmap;
|
||||
rt700->regmap = regmap;
|
||||
|
||||
regcache_cache_only(rt700->regmap, true);
|
||||
|
||||
mutex_init(&rt700->disable_irq_lock);
|
||||
|
||||
INIT_DELAYED_WORK(&rt700->jack_detect_work,
|
||||
@ -1117,10 +1126,26 @@ int rt700_init(struct device *dev, struct regmap *sdw_regmap,
|
||||
&soc_codec_dev_rt700,
|
||||
rt700_dai,
|
||||
ARRAY_SIZE(rt700_dai));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
dev_dbg(&slave->dev, "%s\n", __func__);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt700_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
@ -1132,28 +1157,17 @@ int rt700_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt700->hw_init)
|
||||
return 0;
|
||||
|
||||
if (rt700->first_hw_init) {
|
||||
regcache_cache_only(rt700->regmap, false);
|
||||
regcache_cache_only(rt700->regmap, false);
|
||||
if (rt700->first_hw_init)
|
||||
regcache_cache_bypass(rt700->regmap, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
*/
|
||||
if (!rt700->first_hw_init) {
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
|
||||
/* update count of parent 'active' children */
|
||||
if (!rt700->first_hw_init)
|
||||
/* PM runtime status is marked as 'active' only when a Slave reports as Attached */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
|
||||
/* reset */
|
||||
|
@ -366,8 +366,7 @@ static int rt711_sdca_sdw_remove(struct sdw_slave *slave)
|
||||
cancel_delayed_work_sync(&rt711->jack_btn_check_work);
|
||||
}
|
||||
|
||||
if (rt711->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
mutex_destroy(&rt711->calibrate_mutex);
|
||||
mutex_destroy(&rt711->disable_irq_lock);
|
||||
|
@ -507,6 +507,10 @@ static int rt711_sdca_set_jack_detect(struct snd_soc_component *component,
|
||||
|
||||
rt711->hs_jack = hs_jack;
|
||||
|
||||
/* we can only resume if the device was initialized at least once */
|
||||
if (!rt711->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume_and_get(component->dev);
|
||||
if (ret < 0) {
|
||||
if (ret != -EACCES) {
|
||||
@ -1215,6 +1219,9 @@ static int rt711_sdca_probe(struct snd_soc_component *component)
|
||||
rt711_sdca_parse_dt(rt711, &rt711->slave->dev);
|
||||
rt711->component = component;
|
||||
|
||||
if (!rt711->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
@ -1406,6 +1413,9 @@ int rt711_sdca_init(struct device *dev, struct regmap *regmap,
|
||||
rt711->regmap = regmap;
|
||||
rt711->mbq_regmap = mbq_regmap;
|
||||
|
||||
regcache_cache_only(rt711->regmap, true);
|
||||
regcache_cache_only(rt711->mbq_regmap, true);
|
||||
|
||||
mutex_init(&rt711->calibrate_mutex);
|
||||
mutex_init(&rt711->disable_irq_lock);
|
||||
|
||||
@ -1431,9 +1441,27 @@ int rt711_sdca_init(struct device *dev, struct regmap *regmap,
|
||||
rt711_sdca_dai,
|
||||
ARRAY_SIZE(rt711_sdca_dai));
|
||||
|
||||
dev_dbg(&slave->dev, "%s\n", __func__);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rt711_sdca_vd0_io_init(struct rt711_sdca_priv *rt711)
|
||||
@ -1500,27 +1528,19 @@ int rt711_sdca_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt711->hw_init)
|
||||
return 0;
|
||||
|
||||
regcache_cache_only(rt711->regmap, false);
|
||||
regcache_cache_only(rt711->mbq_regmap, false);
|
||||
|
||||
if (rt711->first_hw_init) {
|
||||
regcache_cache_only(rt711->regmap, false);
|
||||
regcache_cache_bypass(rt711->regmap, true);
|
||||
regcache_cache_only(rt711->mbq_regmap, false);
|
||||
regcache_cache_bypass(rt711->mbq_regmap, true);
|
||||
} else {
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
|
@ -453,9 +453,7 @@ static int rt711_sdw_probe(struct sdw_slave *slave,
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
rt711_init(&slave->dev, sdw_regmap, regmap, slave);
|
||||
|
||||
return 0;
|
||||
return rt711_init(&slave->dev, sdw_regmap, regmap, slave);
|
||||
}
|
||||
|
||||
static int rt711_sdw_remove(struct sdw_slave *slave)
|
||||
@ -468,8 +466,7 @@ static int rt711_sdw_remove(struct sdw_slave *slave)
|
||||
cancel_work_sync(&rt711->calibration_work);
|
||||
}
|
||||
|
||||
if (rt711->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
mutex_destroy(&rt711->calibrate_mutex);
|
||||
mutex_destroy(&rt711->disable_irq_lock);
|
||||
|
@ -462,6 +462,10 @@ static int rt711_set_jack_detect(struct snd_soc_component *component,
|
||||
|
||||
rt711->hs_jack = hs_jack;
|
||||
|
||||
/* we can only resume if the device was initialized at least once */
|
||||
if (!rt711->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume_and_get(component->dev);
|
||||
if (ret < 0) {
|
||||
if (ret != -EACCES) {
|
||||
@ -941,6 +945,9 @@ static int rt711_probe(struct snd_soc_component *component)
|
||||
rt711_parse_dt(rt711, &rt711->slave->dev);
|
||||
rt711->component = component;
|
||||
|
||||
if (!rt711->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
@ -1183,6 +1190,8 @@ int rt711_init(struct device *dev, struct regmap *sdw_regmap,
|
||||
rt711->sdw_regmap = sdw_regmap;
|
||||
rt711->regmap = regmap;
|
||||
|
||||
regcache_cache_only(rt711->regmap, true);
|
||||
|
||||
mutex_init(&rt711->calibrate_mutex);
|
||||
mutex_init(&rt711->disable_irq_lock);
|
||||
|
||||
@ -1204,8 +1213,25 @@ int rt711_init(struct device *dev, struct regmap *sdw_regmap,
|
||||
&soc_codec_dev_rt711,
|
||||
rt711_dai,
|
||||
ARRAY_SIZE(rt711_dai));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(&slave->dev, "%s\n", __func__);
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1219,28 +1245,17 @@ int rt711_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt711->hw_init)
|
||||
return 0;
|
||||
|
||||
if (rt711->first_hw_init) {
|
||||
regcache_cache_only(rt711->regmap, false);
|
||||
regcache_cache_only(rt711->regmap, false);
|
||||
if (rt711->first_hw_init)
|
||||
regcache_cache_bypass(rt711->regmap, true);
|
||||
}
|
||||
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
if (!rt711->first_hw_init) {
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
|
||||
if (!rt711->first_hw_init)
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
|
||||
rt711_reset(rt711->regmap);
|
||||
|
@ -182,27 +182,18 @@ static int rt712_sdca_dmic_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt712->hw_init)
|
||||
return 0;
|
||||
|
||||
regcache_cache_only(rt712->regmap, false);
|
||||
regcache_cache_only(rt712->mbq_regmap, false);
|
||||
if (rt712->first_hw_init) {
|
||||
regcache_cache_only(rt712->regmap, false);
|
||||
regcache_cache_bypass(rt712->regmap, true);
|
||||
regcache_cache_only(rt712->mbq_regmap, false);
|
||||
regcache_cache_bypass(rt712->mbq_regmap, true);
|
||||
} else {
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
@ -608,6 +599,9 @@ static int rt712_sdca_dmic_probe(struct snd_soc_component *component)
|
||||
|
||||
rt712->component = component;
|
||||
|
||||
if (!rt712->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
@ -777,6 +771,9 @@ static int rt712_sdca_dmic_init(struct device *dev, struct regmap *regmap,
|
||||
rt712->regmap = regmap;
|
||||
rt712->mbq_regmap = mbq_regmap;
|
||||
|
||||
regcache_cache_only(rt712->regmap, true);
|
||||
regcache_cache_only(rt712->mbq_regmap, true);
|
||||
|
||||
/*
|
||||
* Mark hw_init to false
|
||||
* HW init will be performed when device reports present
|
||||
@ -791,10 +788,27 @@ static int rt712_sdca_dmic_init(struct device *dev, struct regmap *regmap,
|
||||
&soc_sdca_dev_rt712_dmic,
|
||||
rt712_sdca_dmic_dai,
|
||||
ARRAY_SIZE(rt712_sdca_dmic_dai));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(&slave->dev, "%s\n", __func__);
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
return ret;
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -954,10 +968,7 @@ static int rt712_sdca_dmic_sdw_probe(struct sdw_slave *slave,
|
||||
|
||||
static int rt712_sdca_dmic_sdw_remove(struct sdw_slave *slave)
|
||||
{
|
||||
struct rt712_sdca_dmic_priv *rt712 = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (rt712->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -363,8 +363,7 @@ static int rt712_sdca_sdw_remove(struct sdw_slave *slave)
|
||||
cancel_delayed_work_sync(&rt712->jack_btn_check_work);
|
||||
}
|
||||
|
||||
if (rt712->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
mutex_destroy(&rt712->calibrate_mutex);
|
||||
mutex_destroy(&rt712->disable_irq_lock);
|
||||
|
@ -453,6 +453,9 @@ static int rt712_sdca_set_jack_detect(struct snd_soc_component *component,
|
||||
|
||||
rt712->hs_jack = hs_jack;
|
||||
|
||||
if (!rt712->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume_and_get(component->dev);
|
||||
if (ret < 0) {
|
||||
if (ret != -EACCES) {
|
||||
@ -960,6 +963,9 @@ static int rt712_sdca_probe(struct snd_soc_component *component)
|
||||
rt712_sdca_parse_dt(rt712, &rt712->slave->dev);
|
||||
rt712->component = component;
|
||||
|
||||
if (!rt712->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
@ -1183,6 +1189,9 @@ int rt712_sdca_init(struct device *dev, struct regmap *regmap,
|
||||
rt712->regmap = regmap;
|
||||
rt712->mbq_regmap = mbq_regmap;
|
||||
|
||||
regcache_cache_only(rt712->regmap, true);
|
||||
regcache_cache_only(rt712->mbq_regmap, true);
|
||||
|
||||
mutex_init(&rt712->calibrate_mutex);
|
||||
mutex_init(&rt712->disable_irq_lock);
|
||||
|
||||
@ -1207,10 +1216,27 @@ int rt712_sdca_init(struct device *dev, struct regmap *regmap,
|
||||
else
|
||||
ret = devm_snd_soc_register_component(dev,
|
||||
&soc_sdca_dev_rt712, rt712_sdca_dai, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dev_dbg(&slave->dev, "%s\n", __func__);
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
return ret;
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
@ -1224,27 +1250,18 @@ int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt712->hw_init)
|
||||
return 0;
|
||||
|
||||
regcache_cache_only(rt712->regmap, false);
|
||||
regcache_cache_only(rt712->mbq_regmap, false);
|
||||
if (rt712->first_hw_init) {
|
||||
regcache_cache_only(rt712->regmap, false);
|
||||
regcache_cache_bypass(rt712->regmap, true);
|
||||
regcache_cache_only(rt712->mbq_regmap, false);
|
||||
regcache_cache_bypass(rt712->mbq_regmap, true);
|
||||
} else {
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
|
@ -193,10 +193,7 @@ static int rt715_sdca_sdw_probe(struct sdw_slave *slave,
|
||||
|
||||
static int rt715_sdca_sdw_remove(struct sdw_slave *slave)
|
||||
{
|
||||
struct rt715_sdca_priv *rt715 = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (rt715->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -761,8 +761,12 @@ static const struct snd_soc_dapm_route rt715_sdca_audio_map[] = {
|
||||
|
||||
static int rt715_sdca_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
|
||||
int ret;
|
||||
|
||||
if (!rt715->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
@ -977,6 +981,10 @@ int rt715_sdca_init(struct device *dev, struct regmap *mbq_regmap,
|
||||
rt715->regmap = regmap;
|
||||
rt715->mbq_regmap = mbq_regmap;
|
||||
rt715->hw_sdw_ver = slave->id.sdw_version;
|
||||
|
||||
regcache_cache_only(rt715->regmap, true);
|
||||
regcache_cache_only(rt715->mbq_regmap, true);
|
||||
|
||||
/*
|
||||
* Mark hw_init to false
|
||||
* HW init will be performed when device reports present
|
||||
@ -988,6 +996,25 @@ int rt715_sdca_init(struct device *dev, struct regmap *mbq_regmap,
|
||||
&soc_codec_dev_rt715_sdca,
|
||||
rt715_sdca_dai,
|
||||
ARRAY_SIZE(rt715_sdca_dai));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
dev_dbg(dev, "%s\n", __func__);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1000,22 +1027,16 @@ int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt715->hw_init)
|
||||
return 0;
|
||||
|
||||
regcache_cache_only(rt715->regmap, false);
|
||||
regcache_cache_only(rt715->mbq_regmap, false);
|
||||
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
if (!rt715->first_hw_init) {
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
|
||||
rt715->first_hw_init = true;
|
||||
}
|
||||
|
||||
|
@ -508,17 +508,12 @@ static int rt715_sdw_probe(struct sdw_slave *slave,
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
rt715_init(&slave->dev, sdw_regmap, regmap, slave);
|
||||
|
||||
return 0;
|
||||
return rt715_init(&slave->dev, sdw_regmap, regmap, slave);
|
||||
}
|
||||
|
||||
static int rt715_sdw_remove(struct sdw_slave *slave)
|
||||
{
|
||||
struct rt715_priv *rt715 = dev_get_drvdata(&slave->dev);
|
||||
|
||||
if (rt715->first_hw_init)
|
||||
pm_runtime_disable(&slave->dev);
|
||||
pm_runtime_disable(&slave->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -740,8 +740,12 @@ static int rt715_set_bias_level(struct snd_soc_component *component,
|
||||
|
||||
static int rt715_probe(struct snd_soc_component *component)
|
||||
{
|
||||
struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);
|
||||
int ret;
|
||||
|
||||
if (!rt715->first_hw_init)
|
||||
return 0;
|
||||
|
||||
ret = pm_runtime_resume(component->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
@ -984,6 +988,8 @@ int rt715_init(struct device *dev, struct regmap *sdw_regmap,
|
||||
rt715->regmap = regmap;
|
||||
rt715->sdw_regmap = sdw_regmap;
|
||||
|
||||
regcache_cache_only(rt715->regmap, true);
|
||||
|
||||
/*
|
||||
* Mark hw_init to false
|
||||
* HW init will be performed when device reports present
|
||||
@ -995,8 +1001,25 @@ int rt715_init(struct device *dev, struct regmap *sdw_regmap,
|
||||
&soc_codec_dev_rt715,
|
||||
rt715_dai,
|
||||
ARRAY_SIZE(rt715_dai));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return ret;
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(dev, 3000);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
/* important note: the device is NOT tagged as 'active' and will remain
|
||||
* 'suspended' until the hardware is enumerated/initialized. This is required
|
||||
* to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
|
||||
* fail with -EACCESS because of race conditions between card creation and enumeration
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt715_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
@ -1006,23 +1029,15 @@ int rt715_io_init(struct device *dev, struct sdw_slave *slave)
|
||||
if (rt715->hw_init)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* PM runtime is only enabled when a Slave reports as Attached
|
||||
*/
|
||||
if (!rt715->first_hw_init) {
|
||||
/* set autosuspend parameters */
|
||||
pm_runtime_set_autosuspend_delay(&slave->dev, 3000);
|
||||
pm_runtime_use_autosuspend(&slave->dev);
|
||||
regcache_cache_only(rt715->regmap, false);
|
||||
|
||||
/*
|
||||
* PM runtime status is marked as 'active' only when a Slave reports as Attached
|
||||
*/
|
||||
if (!rt715->first_hw_init)
|
||||
/* update count of parent 'active' children */
|
||||
pm_runtime_set_active(&slave->dev);
|
||||
|
||||
/* make sure the device does not suspend immediately */
|
||||
pm_runtime_mark_last_busy(&slave->dev);
|
||||
|
||||
pm_runtime_enable(&slave->dev);
|
||||
}
|
||||
|
||||
pm_runtime_get_noresume(&slave->dev);
|
||||
|
||||
/* Mute nid=08h/09h */
|
||||
|
Loading…
Reference in New Issue
Block a user