]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: SOF: Intel: hda: support BT link mask in mach_params
authorBrent Lu <brent.lu@intel.com>
Tue, 27 Aug 2024 12:32:06 +0000 (20:32 +0800)
committerMark Brown <broonie@kernel.org>
Wed, 28 Aug 2024 12:01:57 +0000 (13:01 +0100)
Add an new variable bt_link_mask to snd_soc_acpi_mach_params structure.
SSP port mask of BT offload found in NHLT table will be sent to
machine driver to setup BE dai link with correct SSP port number.

This patch only detects and enables the BT dailink. The functionality
will only be unlocked with a topology file that makes a reference to
that BT dailink. For backwards-compatibility reasons, this topology
will not be used by default. Chromebooks and Linux users willing to
experiment shall use the tplg_name kernel parameter to force the use
of an enhanced topology.

Signed-off-by: Brent Lu <brent.lu@intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Link: https://patch.msgid.link/20240827123215.258859-9-yung-chuan.liao@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
include/sound/soc-acpi.h
sound/soc/sof/intel/hda.c

index b6d301946244e6509f581f5eaa90d9d595af0dec..c1552bc6e31cd44bd7a91d291804d55b5285981f 100644 (file)
@@ -73,6 +73,7 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
  * @subsystem_rev: optional PCI SSID revision value
  * @subsystem_id_set: true if a value has been written to
  *                   subsystem_vendor and subsystem_device.
+ * @bt_link_mask: BT offload link enabled on the board
  */
 struct snd_soc_acpi_mach_params {
        u32 acpi_ipc_irq_index;
@@ -89,6 +90,7 @@ struct snd_soc_acpi_mach_params {
        unsigned short subsystem_device;
        unsigned short subsystem_rev;
        bool subsystem_id_set;
+       u32 bt_link_mask;
 };
 
 /**
index 2f24b5abc91bcf5dd473364a67cf7e11f013afc5..d0a41e8e6334be1df7bf1e353a7c5f7ea36d1121 100644 (file)
@@ -444,6 +444,10 @@ static int mclk_id_override = -1;
 module_param_named(mclk_id, mclk_id_override, int, 0444);
 MODULE_PARM_DESC(mclk_id, "SOF SSP mclk_id");
 
+static int bt_link_mask_override;
+module_param_named(bt_link_mask, bt_link_mask_override, int, 0444);
+MODULE_PARM_DESC(bt_link_mask, "SOF BT offload link mask");
+
 static int hda_init(struct snd_sof_dev *sdev)
 {
        struct hda_bus *hbus;
@@ -529,7 +533,7 @@ static int check_dmic_num(struct snd_sof_dev *sdev)
        return dmic_num;
 }
 
-static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev)
+static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev, u8 device_type)
 {
        struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
        struct nhlt_acpi_table *nhlt;
@@ -540,9 +544,11 @@ static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev)
                return ssp_mask;
 
        if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_SSP)) {
-               ssp_mask = intel_nhlt_ssp_endpoint_mask(nhlt, NHLT_DEVICE_I2S);
+               ssp_mask = intel_nhlt_ssp_endpoint_mask(nhlt, device_type);
                if (ssp_mask)
-                       dev_info(sdev->dev, "NHLT_DEVICE_I2S detected, ssp_mask %#x\n", ssp_mask);
+                       dev_info(sdev->dev, "NHLT device %s(%d) detected, ssp_mask %#x\n",
+                                device_type == NHLT_DEVICE_BT ? "BT" : "I2S",
+                                device_type, ssp_mask);
        }
 
        return ssp_mask;
@@ -1235,8 +1241,29 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
         * Otherwise, set certain mach params.
         */
        hda_generic_machine_select(sdev, &mach);
-       if (!mach)
+       if (!mach) {
                dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
+               return NULL;
+       }
+
+       /* report BT offload link mask to machine driver */
+       mach->mach_params.bt_link_mask = check_nhlt_ssp_mask(sdev, NHLT_DEVICE_BT);
+
+       dev_info(sdev->dev, "BT link detected in NHLT tables: %#x\n",
+                mach->mach_params.bt_link_mask);
+
+       /* allow for module parameter override */
+       if (bt_link_mask_override) {
+               dev_dbg(sdev->dev, "overriding BT link detected in NHLT tables %#x by kernel param %#x\n",
+                       mach->mach_params.bt_link_mask, bt_link_mask_override);
+               mach->mach_params.bt_link_mask = bt_link_mask_override;
+       }
+
+       if (hweight_long(mach->mach_params.bt_link_mask) > 1) {
+               dev_warn(sdev->dev, "invalid BT link mask %#x found, reset the mask\n",
+                       mach->mach_params.bt_link_mask);
+               mach->mach_params.bt_link_mask = 0;
+       }
 
        /*
         * Fixup tplg file name by appending dmic num, ssp num, codec/amplifier
@@ -1312,7 +1339,7 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
                }
 
                /* report SSP link mask to machine driver */
-               mach->mach_params.i2s_link_mask = check_nhlt_ssp_mask(sdev);
+               mach->mach_params.i2s_link_mask = check_nhlt_ssp_mask(sdev, NHLT_DEVICE_I2S);
 
                if (tplg_fixup &&
                    mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER &&