]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: rt712-sdca: detect the SMART_MIC function during the probe stage
authorPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Wed, 16 Oct 2024 10:23:28 +0000 (18:23 +0800)
committerMark Brown <broonie@kernel.org>
Thu, 17 Oct 2024 17:42:14 +0000 (18:42 +0100)
We shouldn't do any devm_ based allocation in the io_init(), this need
to happen in the probe(). Luckily, we now have an SDCA helper to look
in ACPI tables if a SMART_MIC function is exposed.

FIXME: the registers are not well handled today, the regmap lists
registers which are not really supported in all platforms. The regmap
needs to throw an error if those registers are accessed without
existing.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://patch.msgid.link/20241016102333.294448-7-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/rt712-sdca-sdw.c
sound/soc/codecs/rt712-sdca.c
sound/soc/codecs/rt712-sdca.h

index 90d5aaddbd5b946788dbc8313ba572ff2111a8e9..549aa31faed428da60914b2fe474a52437bfa2b1 100644 (file)
@@ -507,3 +507,4 @@ module_sdw_driver(rt712_sdca_sdw_driver);
 MODULE_DESCRIPTION("ASoC RT712 SDCA SDW driver");
 MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>");
 MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS(SND_SOC_SDCA);
index e210c574bb74a1f0e9d96f93367ff36ba728cfb8..78dbf9eed494bb6f50c1d89c41a1f800582dde3d 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pm_runtime.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
+#include <sound/sdca.h>
 #include <linux/soundwire/sdw_registers.h>
 #include <linux/slab.h>
 #include <sound/soc-dapm.h>
@@ -1652,6 +1653,17 @@ int rt712_sdca_init(struct device *dev, struct regmap *regmap,
        if (ret < 0)
                return ret;
 
+       /* only add the dmic component if a SMART_MIC function is exposed in ACPI */
+       if (sdca_device_quirk_match(slave, SDCA_QUIRKS_RT712_VB)) {
+               ret =  devm_snd_soc_register_component(dev,
+                                                      &soc_sdca_dev_rt712_dmic,
+                                                      rt712_sdca_dmic_dai,
+                                                      ARRAY_SIZE(rt712_sdca_dmic_dai));
+               if (ret < 0)
+                       return ret;
+               rt712->dmic_function_found = true;
+       }
+
        /* set autosuspend parameters */
        pm_runtime_set_autosuspend_delay(dev, 3000);
        pm_runtime_use_autosuspend(dev);
@@ -1799,7 +1811,6 @@ static void rt712_sdca_vb_io_init(struct rt712_sdca_priv *rt712)
 int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)
 {
        struct rt712_sdca_priv *rt712 = dev_get_drvdata(dev);
-       int ret = 0;
        unsigned int val;
        struct sdw_slave_prop *prop = &slave->prop;
 
@@ -1829,15 +1840,22 @@ int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)
        rt712->version_id = (val & 0x0f00) >> 8;
        dev_dbg(&slave->dev, "%s hw_id=0x%x, version_id=0x%x\n", __func__, rt712->hw_id, rt712->version_id);
 
-       if (rt712->version_id == RT712_VA)
+       if (rt712->version_id == RT712_VA) {
+               if (rt712->dmic_function_found) {
+                       dev_err(&slave->dev, "%s RT712 VA detected but SMART_MIC function exposed in ACPI\n",
+                               __func__);
+                       goto suspend;
+               }
+
                rt712_sdca_va_io_init(rt712);
-       else {
-               /* multilanes and DMIC are supported by rt712vb */
-               ret =  devm_snd_soc_register_component(dev,
-                       &soc_sdca_dev_rt712_dmic, rt712_sdca_dmic_dai, ARRAY_SIZE(rt712_sdca_dmic_dai));
-               if (ret < 0)
-                       return ret;
+       else {
+               if (!rt712->dmic_function_found) {
+                       dev_err(&slave->dev, "%s RT712 VB detected but no SMART_MIC function exposed in ACPI\n",
+                               __func__);
+                       goto suspend;
+               }
 
+               /* multilanes and DMIC are supported by rt712vb */
                prop->lane_control_support = true;
                rt712_sdca_vb_io_init(rt712);
        }
@@ -1862,10 +1880,12 @@ int rt712_sdca_io_init(struct device *dev, struct sdw_slave *slave)
        /* Mark Slave initialization complete */
        rt712->hw_init = true;
 
+       dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
+
+suspend:
        pm_runtime_mark_last_busy(&slave->dev);
        pm_runtime_put_autosuspend(&slave->dev);
 
-       dev_dbg(&slave->dev, "%s hw_init complete\n", __func__);
        return 0;
 }
 
index 2169f2f726b9fb91bb23b15d59dc72185179eb5a..a08491496d9013dae0978b4b7f3e0c4fc661cba2 100644 (file)
@@ -36,6 +36,7 @@ struct  rt712_sdca_priv {
        unsigned int scp_sdca_stat2;
        unsigned int hw_id;
        unsigned int version_id;
+       bool dmic_function_found;
        bool fu0f_dapm_mute;
        bool fu0f_mixer_l_mute;
        bool fu0f_mixer_r_mute;