* [PATCH 1/2] ASoC: aw88399: pass firmware name as argument
2026-10-18 17:43 [PATCH 0/2] ALSA: hda: aw88399: Add per-model firmware loading Marco Giunta
@ 2026-10-18 17:43 ` Marco Giunta
2026-10-18 17:43 ` [PATCH 2/2] ALSA: hda: aw88399: use SSID-specific firmware name Marco Giunta
2026-10-19 18:02 ` [PATCH 0/2] ALSA: hda: aw88399: Add per-model firmware loading Takashi Iwai
2 siblings, 0 replies; 4+ messages in thread
From: Marco Giunta @ 2026-10-18 17:43 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown
Cc: Jaroslav Kysela, Liam Girdwood, Mark Pearson, Wayne Sun,
Jimmy Zhang, Ben Yi, Xia Yun'an, Marco Giunta, linux-sound,
linux-kernel
Pass the ACF firmware filename as an argument to
aw88399_request_firmware_file() instead of hardcoding AW88399_ACF_FILE.
Both existing callers (ASoC and HDA) pass AW88399_ACF_FILE to preserve
current behavior. Also add missing newlines to the log messages of the
modified lines.
This allows the HDA side codec driver to request per-model firmware files
in the next patch.
Tested-by: Xia Yun'an <imitoy@imitoy.top>
Signed-off-by: Marco Giunta <marco_giunta@outlook.it>
---
include/sound/aw88399.h | 2 +-
sound/hda/codecs/side-codecs/aw88399_hda.c | 2 +-
sound/soc/codecs/aw88399-lib.c | 10 +++++-----
sound/soc/codecs/aw88399.c | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/sound/aw88399.h b/include/sound/aw88399.h
index 38d9bd6abd8b..d72c491ee866 100644
--- a/include/sound/aw88399.h
+++ b/include/sound/aw88399.h
@@ -617,7 +617,7 @@ void aw88399_dev_set_channel(struct aw88399 *aw88399, int channel);
void aw88399_hw_reset(struct aw88399 *aw88399);
int aw88399_init(struct aw88399 *aw88399, struct i2c_client *i2c, struct regmap *regmap);
extern const struct regmap_config aw88399_remap_config;
-int aw88399_request_firmware_file(struct aw88399 *aw88399);
+int aw88399_request_firmware_file(struct aw88399 *aw88399, const char *fw_name);
void aw88399_start(struct aw88399 *aw88399, bool sync_start);
void aw88399_startup_work(struct work_struct *work);
int aw88399_stop(struct aw_device *aw_dev);
diff --git a/sound/hda/codecs/side-codecs/aw88399_hda.c b/sound/hda/codecs/side-codecs/aw88399_hda.c
index 9c6e01c29651..78bafe3c1b64 100644
--- a/sound/hda/codecs/side-codecs/aw88399_hda.c
+++ b/sound/hda/codecs/side-codecs/aw88399_hda.c
@@ -129,7 +129,7 @@ static int aw88399_hda_init(struct aw88399_hda *aw88399)
if (core->aw_pa)
aw88399_dev_set_channel(core, aw88399->channel);
- ret = aw88399_request_firmware_file(core);
+ ret = aw88399_request_firmware_file(core, AW88399_ACF_FILE);
if (ret)
return ret;
diff --git a/sound/soc/codecs/aw88399-lib.c b/sound/soc/codecs/aw88399-lib.c
index 75a533c9b752..b4e8aae56805 100644
--- a/sound/soc/codecs/aw88399-lib.c
+++ b/sound/soc/codecs/aw88399-lib.c
@@ -1284,21 +1284,21 @@ static int aw88399_dev_init(struct aw88399 *aw88399, struct aw_container *aw_cfg
return 0;
}
-int aw88399_request_firmware_file(struct aw88399 *aw88399)
+int aw88399_request_firmware_file(struct aw88399 *aw88399, const char *fw_name)
{
const struct firmware *cont __free(firmware) = NULL;
int ret;
aw88399->aw_pa->fw_status = AW88399_DEV_FW_FAILED;
- ret = request_firmware(&cont, AW88399_ACF_FILE, aw88399->aw_pa->dev);
+ ret = request_firmware(&cont, fw_name, aw88399->aw_pa->dev);
if (ret) {
- dev_err(aw88399->aw_pa->dev, "request [%s] failed!", AW88399_ACF_FILE);
+ dev_err(aw88399->aw_pa->dev, "request [%s] failed!\n", fw_name);
return ret;
}
dev_dbg(aw88399->aw_pa->dev, "loaded %s - size: %zu\n",
- AW88399_ACF_FILE, cont ? cont->size : 0);
+ fw_name, cont ? cont->size : 0);
aw88399->aw_cfg = devm_kzalloc(aw88399->aw_pa->dev,
struct_size(aw88399->aw_cfg, data, cont->size), GFP_KERNEL);
@@ -1310,7 +1310,7 @@ int aw88399_request_firmware_file(struct aw88399 *aw88399)
ret = aw88395_dev_load_acf_check(aw88399->aw_pa, aw88399->aw_cfg);
if (ret) {
- dev_err(aw88399->aw_pa->dev, "load [%s] failed!", AW88399_ACF_FILE);
+ dev_err(aw88399->aw_pa->dev, "load [%s] failed!\n", fw_name);
return ret;
}
diff --git a/sound/soc/codecs/aw88399.c b/sound/soc/codecs/aw88399.c
index e9dab5e7bae3..320dc1b87841 100644
--- a/sound/soc/codecs/aw88399.c
+++ b/sound/soc/codecs/aw88399.c
@@ -727,7 +727,7 @@ static int aw88399_codec_probe(struct snd_soc_component *component)
INIT_DELAYED_WORK(&aw88399->start_work, aw88399_startup_work);
- ret = aw88399_request_firmware_file(aw88399);
+ ret = aw88399_request_firmware_file(aw88399, AW88399_ACF_FILE);
if (ret)
dev_err(aw88399->aw_pa->dev, "%s failed\n", __func__);
--
2.56.0
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH 2/2] ALSA: hda: aw88399: use SSID-specific firmware name
2026-10-18 17:43 [PATCH 0/2] ALSA: hda: aw88399: Add per-model firmware loading Marco Giunta
2026-10-18 17:43 ` [PATCH 1/2] ASoC: aw88399: pass firmware name as argument Marco Giunta
@ 2026-10-18 17:43 ` Marco Giunta
2026-10-19 18:02 ` [PATCH 0/2] ALSA: hda: aw88399: Add per-model firmware loading Takashi Iwai
2 siblings, 0 replies; 4+ messages in thread
From: Marco Giunta @ 2026-10-18 17:43 UTC (permalink / raw)
To: Takashi Iwai, Mark Brown
Cc: Jaroslav Kysela, Liam Girdwood, Mark Pearson, Wayne Sun,
Jimmy Zhang, Ben Yi, Xia Yun'an, Marco Giunta, linux-sound,
linux-kernel
Use the ACPI subsystem ID to construct per-model firmware filenames
(e.g. "awinic/aw88399_acf_17aa3938.bin") when loading firmware on HDA
systems. This makes the driver compatible with the linux-firmware
repository's per-device naming convention.
Also, since the ACPI SSID is now required for firmware loading, change
the error handling for a missing SSID from silently succeeding
to an early -ENODEV return in aw88399_hda_acpi_probe().
Tested-by: Xia Yun'an <imitoy@imitoy.top>
Signed-off-by: Marco Giunta <marco_giunta@outlook.it>
---
sound/hda/codecs/side-codecs/aw88399_hda.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/sound/hda/codecs/side-codecs/aw88399_hda.c b/sound/hda/codecs/side-codecs/aw88399_hda.c
index 78bafe3c1b64..1cfda25dce57 100644
--- a/sound/hda/codecs/side-codecs/aw88399_hda.c
+++ b/sound/hda/codecs/side-codecs/aw88399_hda.c
@@ -12,6 +12,7 @@
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
#include <linux/string.h>
+#include <linux/string_helpers.h>
#include <sound/hda_codec.h>
#include "../generic.h"
#include "hda_component.h"
@@ -129,10 +130,17 @@ static int aw88399_hda_init(struct aw88399_hda *aw88399)
if (core->aw_pa)
aw88399_dev_set_channel(core, aw88399->channel);
- ret = aw88399_request_firmware_file(core, AW88399_ACF_FILE);
+ char *fw_name __free(kfree) =
+ kasprintf(GFP_KERNEL, "awinic/aw88399_acf_%s.bin", aw88399->acpi_subsystem_id);
+ if (!fw_name)
+ return -ENOMEM;
+ string_lower(fw_name, fw_name);
+ ret = aw88399_request_firmware_file(core, fw_name);
if (ret)
return ret;
+ dev_info(dev, "Loaded firmware %s\n", fw_name);
+
aw88399->core = core;
aw88399->aw_dev = core->aw_pa;
@@ -193,8 +201,10 @@ static int aw88399_hda_acpi_probe(struct aw88399_hda *aw88399)
return -ENODEV;
sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev));
- if (IS_ERR_OR_NULL(sub))
- return 0;
+ if (IS_ERR_OR_NULL(sub)) {
+ dev_err(aw88399->dev, "ACPI subsystem ID not available\n");
+ return -ENODEV;
+ }
aw88399->acpi_subsystem_id = devm_kstrdup(aw88399->dev, sub, GFP_KERNEL);
kfree(sub);
@@ -347,4 +357,4 @@ MODULE_DESCRIPTION("AW88399 HDA driver");
MODULE_AUTHOR("Yakov Till <yakov.till@gmail.com>");
MODULE_AUTHOR("Marco Giunta <marco_giunta@outlook.it>");
MODULE_LICENSE("GPL");
-MODULE_FIRMWARE("aw88399_acf.bin");
+MODULE_FIRMWARE("awinic/aw88399_acf_*.bin");
--
2.56.0
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH 0/2] ALSA: hda: aw88399: Add per-model firmware loading
2026-10-18 17:43 [PATCH 0/2] ALSA: hda: aw88399: Add per-model firmware loading Marco Giunta
2026-10-18 17:43 ` [PATCH 1/2] ASoC: aw88399: pass firmware name as argument Marco Giunta
2026-10-18 17:43 ` [PATCH 2/2] ALSA: hda: aw88399: use SSID-specific firmware name Marco Giunta
@ 2026-10-19 18:02 ` Takashi Iwai
2 siblings, 0 replies; 4+ messages in thread
From: Takashi Iwai @ 2026-10-19 18:02 UTC (permalink / raw)
To: Marco Giunta
Cc: Takashi Iwai, Mark Brown, Jaroslav Kysela, Liam Girdwood,
Mark Pearson, Wayne Sun, Jimmy Zhang, Ben Yi, Xia Yun'an,
linux-sound, linux-kernel
On Sun, 18 Oct 2026 19:43:55 +0200,
Marco Giunta wrote:
>
> The AW88399 HDA side codec driver currently requests firmware using
> the same hardcoded generic filename ("aw88399_acf.bin") as the ASoC driver
> it was derived from.
> This requires users to manually extract the firmware from the
> Windows driver, rename it with this model-independent name, and place
> it in /lib/firmware, which is not sustainable for distribution packaging.
>
> This series adds support for per-model firmware filenames based on the
> ACPI subsystem ID (e.g. "awinic/aw88399_acf_17aa3938.bin"), making the
> driver compatible with the linux-firmware repository's per-device naming
> convention.
> ACF firmware binaries for the currently supported Lenovo Legion models
> have been submitted to the linux-firmware ML by AWINIC [1] (currently
> pending review).
>
> The series is as follows:
>
> * Patch 1 adds a name parameter to the shared firmware request function
> so callers can specify the filename.
>
> * Patch 2 uses the ACPI subsystem ID to construct model-specific firmware
> names in the HDA driver.
>
> Note: since there are still some AW88399 patches either pending merge or
> that have yet to cross the ASoC/HDA bridge (see the note in [2]), I based
> this series on linux-next, meaning a rebase may be needed before merging.
> Apologies for the extra noise; I'm sending the series now for review
> as I'd rather not miss the 7.4 merge window.
Applied both patches now. Thanks.
Takashi
^ permalink raw reply [flat|nested] 4+ messages in thread