summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/rt712-sdca-dmic.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/rt712-sdca-dmic.c')
-rw-r--r--sound/soc/codecs/rt712-sdca-dmic.c104
1 files changed, 54 insertions, 50 deletions
diff --git a/sound/soc/codecs/rt712-sdca-dmic.c b/sound/soc/codecs/rt712-sdca-dmic.c
index 869cc7bfd178..2928649e80e4 100644
--- a/sound/soc/codecs/rt712-sdca-dmic.c
+++ b/sound/soc/codecs/rt712-sdca-dmic.c
@@ -139,8 +139,8 @@ static int rt712_sdca_dmic_index_write(struct rt712_sdca_dmic_priv *rt712,
ret = regmap_write(regmap, addr, value);
if (ret < 0)
dev_err(&rt712->slave->dev,
- "Failed to set private value: %06x <= %04x ret=%d\n",
- addr, value, ret);
+ "%s: Failed to set private value: %06x <= %04x ret=%d\n",
+ __func__, addr, value, ret);
return ret;
}
@@ -155,8 +155,8 @@ static int rt712_sdca_dmic_index_read(struct rt712_sdca_dmic_priv *rt712,
ret = regmap_read(regmap, addr, value);
if (ret < 0)
dev_err(&rt712->slave->dev,
- "Failed to get private value: %06x => %04x ret=%d\n",
- addr, *value, ret);
+ "%s: Failed to get private value: %06x => %04x ret=%d\n",
+ __func__, addr, *value, ret);
return ret;
}
@@ -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);
@@ -245,7 +236,6 @@ static int rt712_sdca_dmic_io_init(struct device *dev, struct sdw_slave *slave)
/* Mark Slave initialization complete */
rt712->hw_init = true;
- pm_runtime_mark_last_busy(&slave->dev);
pm_runtime_put_autosuspend(&slave->dev);
dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
@@ -272,12 +262,8 @@ static int rt712_sdca_dmic_set_gain_get(struct snd_kcontrol *kcontrol,
if (!adc_vol_flag) /* boost gain */
ctl = regvalue / 0x0a00;
- else { /* ADC gain */
- if (adc_vol_flag)
- ctl = p->max - (((0x1e00 - regvalue) & 0xffff) / interval_offset);
- else
- ctl = p->max - (((0 - regvalue) & 0xffff) / interval_offset);
- }
+ else /* ADC gain */
+ ctl = p->max - (((0x1e00 - regvalue) & 0xffff) / interval_offset);
ucontrol->value.integer.value[i] = ctl;
}
@@ -326,7 +312,8 @@ static int rt712_sdca_dmic_set_gain_put(struct snd_kcontrol *kcontrol,
for (i = 0; i < p->count; i++) {
err = regmap_write(rt712->mbq_regmap, p->reg_base + i, gain_val[i]);
if (err < 0)
- dev_err(&rt712->slave->dev, "0x%08x can't be set\n", p->reg_base + i);
+ dev_err(&rt712->slave->dev, "%s: 0x%08x can't be set\n",
+ __func__, p->reg_base + i);
}
return changed;
@@ -442,8 +429,7 @@ static const struct snd_kcontrol_new rt712_sdca_dmic_snd_controls[] = {
static int rt712_sdca_dmic_mux_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_component *component =
- snd_soc_dapm_kcontrol_component(kcontrol);
+ struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol);
struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
unsigned int val = 0, mask_sft;
@@ -465,10 +451,8 @@ static int rt712_sdca_dmic_mux_get(struct snd_kcontrol *kcontrol,
static int rt712_sdca_dmic_mux_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- struct snd_soc_component *component =
- snd_soc_dapm_kcontrol_component(kcontrol);
- struct snd_soc_dapm_context *dapm =
- snd_soc_dapm_kcontrol_dapm(kcontrol);
+ struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol);
+ struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
struct rt712_sdca_dmic_priv *rt712 = snd_soc_component_get_drvdata(component);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned int *item = ucontrol->value.enumerated.item;
@@ -608,6 +592,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;
@@ -673,13 +660,13 @@ static int rt712_sdca_dmic_hw_params(struct snd_pcm_substream *substream,
retval = sdw_stream_add_slave(rt712->slave, &stream_config,
&port_config, 1, sdw_stream);
if (retval) {
- dev_err(dai->dev, "Unable to configure port\n");
+ dev_err(dai->dev, "%s: Unable to configure port\n", __func__);
return retval;
}
if (params_channels(params) > 4) {
- dev_err(component->dev, "Unsupported channels %d\n",
- params_channels(params));
+ dev_err(component->dev, "%s: Unsupported channels %d\n",
+ __func__, params_channels(params));
return -EINVAL;
}
@@ -704,8 +691,8 @@ static int rt712_sdca_dmic_hw_params(struct snd_pcm_substream *substream,
sampling_rate = RT712_SDCA_RATE_192000HZ;
break;
default:
- dev_err(component->dev, "Rate %d is not supported\n",
- params_rate(params));
+ dev_err(component->dev, "%s: Rate %d is not supported\n",
+ __func__, params_rate(params));
return -EINVAL;
}
@@ -777,6 +764,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 +781,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;
}
@@ -869,7 +876,7 @@ static const struct sdw_device_id rt712_sdca_dmic_id[] = {
};
MODULE_DEVICE_TABLE(sdw, rt712_sdca_dmic_id);
-static int __maybe_unused rt712_sdca_dmic_dev_suspend(struct device *dev)
+static int rt712_sdca_dmic_dev_suspend(struct device *dev)
{
struct rt712_sdca_dmic_priv *rt712 = dev_get_drvdata(dev);
@@ -882,7 +889,7 @@ static int __maybe_unused rt712_sdca_dmic_dev_suspend(struct device *dev)
return 0;
}
-static int __maybe_unused rt712_sdca_dmic_dev_system_suspend(struct device *dev)
+static int rt712_sdca_dmic_dev_system_suspend(struct device *dev)
{
struct rt712_sdca_dmic_priv *rt712_sdca = dev_get_drvdata(dev);
@@ -894,7 +901,7 @@ static int __maybe_unused rt712_sdca_dmic_dev_system_suspend(struct device *dev)
#define RT712_PROBE_TIMEOUT 5000
-static int __maybe_unused rt712_sdca_dmic_dev_resume(struct device *dev)
+static int rt712_sdca_dmic_dev_resume(struct device *dev)
{
struct sdw_slave *slave = dev_to_sdw_dev(dev);
struct rt712_sdca_dmic_priv *rt712 = dev_get_drvdata(dev);
@@ -909,7 +916,8 @@ static int __maybe_unused rt712_sdca_dmic_dev_resume(struct device *dev)
time = wait_for_completion_timeout(&slave->initialization_complete,
msecs_to_jiffies(RT712_PROBE_TIMEOUT));
if (!time) {
- dev_err(&slave->dev, "Initialization not complete, timed out\n");
+ dev_err(&slave->dev, "%s: Initialization not complete, timed out\n",
+ __func__);
sdw_show_ping_status(slave->bus, true);
return -ETIMEDOUT;
@@ -925,12 +933,12 @@ regmap_sync:
}
static const struct dev_pm_ops rt712_sdca_dmic_pm = {
- SET_SYSTEM_SLEEP_PM_OPS(rt712_sdca_dmic_dev_system_suspend, rt712_sdca_dmic_dev_resume)
- SET_RUNTIME_PM_OPS(rt712_sdca_dmic_dev_suspend, rt712_sdca_dmic_dev_resume, NULL)
+ SYSTEM_SLEEP_PM_OPS(rt712_sdca_dmic_dev_system_suspend, rt712_sdca_dmic_dev_resume)
+ RUNTIME_PM_OPS(rt712_sdca_dmic_dev_suspend, rt712_sdca_dmic_dev_resume, NULL)
};
-static struct sdw_slave_ops rt712_sdca_dmic_slave_ops = {
+static const struct sdw_slave_ops rt712_sdca_dmic_slave_ops = {
.read_prop = rt712_sdca_dmic_read_prop,
.update_status = rt712_sdca_dmic_update_status,
};
@@ -954,10 +962,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;
}
@@ -965,8 +970,7 @@ static int rt712_sdca_dmic_sdw_remove(struct sdw_slave *slave)
static struct sdw_driver rt712_sdca_dmic_sdw_driver = {
.driver = {
.name = "rt712-sdca-dmic",
- .owner = THIS_MODULE,
- .pm = &rt712_sdca_dmic_pm,
+ .pm = pm_ptr(&rt712_sdca_dmic_pm),
},
.probe = rt712_sdca_dmic_sdw_probe,
.remove = rt712_sdca_dmic_sdw_remove,