Unverified Commit 46c8b4d2 authored by Stefan Binding's avatar Stefan Binding Committed by Mark Brown
Browse files

ASoC: cs35l41: Fallback to reading Subsystem ID property if not ACPI



If ACPI is not used, then there is currently no way of reading a
Subsystem ID property used for a system name to uniquely identify
the system in order to load the correct firmware and tuning.
Add a new property which can be read from device tree to be able to set
the system name.

Signed-off-by: default avatarStefan Binding <sbinding@opensource.cirrus.com>
Link: https://patch.msgid.link/20250917153722.94978-3-sbinding@opensource.cirrus.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent f8673e40
Loading
Loading
Loading
Loading
+44 −33
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
// Author: David Rhodes <david.rhodes@cirrus.com>

#include <linux/acpi.h>
#include <acpi/acpi_bus.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/init.h>
@@ -1147,45 +1148,55 @@ static int cs35l41_dsp_init(struct cs35l41_private *cs35l41)
	return ret;
}

#ifdef CONFIG_ACPI
static int cs35l41_acpi_get_name(struct cs35l41_private *cs35l41)
static int cs35l41_get_system_name(struct cs35l41_private *cs35l41)
{
	struct acpi_device *adev = ACPI_COMPANION(cs35l41->dev);
	acpi_handle handle = acpi_device_handle(adev);
	const char *hid;
	const char *sub;
	const char *sub = NULL;
	const char *tmp;
	int ret = 0;

	/* If there is no acpi_device, there is no ACPI for this system, return 0 */
	if (!adev)
		return 0;
	/* If there is no acpi_device, there is no ACPI for this system, skip checking ACPI */
	if (adev) {
		acpi_handle handle = acpi_device_handle(adev);

		sub = acpi_get_subsystem_id(handle);
	if (IS_ERR(sub)) {
		ret = PTR_ERR_OR_ZERO(sub);
		if (ret) {
			sub = NULL;
			/* If no _SUB, fallback to _HID, otherwise fail */
		if (PTR_ERR(sub) == -ENODATA) {
			hid = acpi_device_hid(adev);
			if (ret == -ENODATA) {
				tmp = acpi_device_hid(adev);
				/* If dummy hid, return 0 and fallback to legacy firmware path */
			if (!strcmp(hid, "device"))
				return 0;
			sub = kstrdup(hid, GFP_KERNEL);
			if (!sub)
				sub = ERR_PTR(-ENOMEM);

		} else
			return PTR_ERR(sub);
				if (!strcmp(tmp, "device")) {
					ret = 0;
					goto err;
				}
				sub = kstrdup(tmp, GFP_KERNEL);
				if (!sub) {
					ret = -ENOMEM;
					goto err;
				}
			}
		}
	} else {
		if (!device_property_read_string(cs35l41->dev, "cirrus,subsystem-id", &tmp)) {
			sub = kstrdup(tmp, GFP_KERNEL);
			if (!sub) {
				ret = -ENOMEM;
				goto err;
			}
		}
	}

err:
	if (sub) {
		cs35l41->dsp.system_name = sub;
	dev_dbg(cs35l41->dev, "Subsystem ID: %s\n", cs35l41->dsp.system_name);
		dev_info(cs35l41->dev, "Subsystem ID: %s\n", cs35l41->dsp.system_name);
	} else
		dev_warn(cs35l41->dev, "Subsystem ID not found\n");

	return 0;
}
#else
static int cs35l41_acpi_get_name(struct cs35l41_private *cs35l41)
{
	return 0;
	return ret;
}
#endif /* CONFIG_ACPI */

int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg)
{
@@ -1317,7 +1328,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
		goto err;
	}

	ret = cs35l41_acpi_get_name(cs35l41);
	ret = cs35l41_get_system_name(cs35l41);
	if (ret < 0)
		goto err;