summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/hdac_hda.c
diff options
context:
space:
mode:
authorBard Liao <yung-chuan.liao@linux.intel.com>2023-09-19 16:32:09 +0800
committerMark Brown <broonie@kernel.org>2023-09-19 13:49:16 +0100
commit842a62a75e709b3efb5020a25a225fa51748c5f9 (patch)
tree771a2dfb9a89c91a1fa1054f45e8cb19fa8b9c61 /sound/soc/codecs/hdac_hda.c
parent88e20c1f8c1c0018a2dad50b991b87ef028b9c1c (diff)
ASoC: hdac_hda: add HDA patch loader support
HDA patch loader is supported by legacy HDA driver. Implement it on ASoC HDA driver, too. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Link: https://lore.kernel.org/r/20230919083209.1919921-1-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/codecs/hdac_hda.c')
-rw-r--r--sound/soc/codecs/hdac_hda.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/sound/soc/codecs/hdac_hda.c b/sound/soc/codecs/hdac_hda.c
index be66853afbe2..8f5d97949d3d 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -7,6 +7,7 @@
* codec drivers using hdac_ext_bus_ops ops.
*/
+#include <linux/firmware.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/module.h>
@@ -35,6 +36,13 @@
SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
SNDRV_PCM_RATE_192000)
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+static char *loadable_patch[SNDRV_CARDS];
+
+module_param_array_named(patch, loadable_patch, charp, NULL, 0444);
+MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
+#endif
+
static int hdac_hda_dai_open(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai);
static void hdac_hda_dai_close(struct snd_pcm_substream *substream,
@@ -423,6 +431,26 @@ static int hdac_hda_codec_probe(struct snd_soc_component *component)
dev_err(&hdev->dev, "failed to create hda codec %d\n", ret);
goto error_no_pm;
}
+
+#ifdef CONFIG_SND_HDA_PATCH_LOADER
+ if (loadable_patch[hda_pvt->dev_index] && *loadable_patch[hda_pvt->dev_index]) {
+ dev_info(&hdev->dev, "Applying patch firmware '%s'\n",
+ loadable_patch[hda_pvt->dev_index]);
+ ret = request_firmware(&hda_pvt->fw, loadable_patch[hda_pvt->dev_index],
+ &hdev->dev);
+ if (ret < 0)
+ goto error_no_pm;
+ if (hda_pvt->fw) {
+ ret = snd_hda_load_patch(hcodec->bus, hda_pvt->fw->size, hda_pvt->fw->data);
+ if (ret < 0) {
+ dev_err(&hdev->dev, "failed to load hda patch %d\n", ret);
+ goto error_no_pm;
+ }
+ release_firmware(hda_pvt->fw);
+ hda_pvt->fw = NULL;
+ }
+ }
+#endif
/*
* Overwrite type to HDA_DEV_ASOC since it is a ASoC driver
* hda_codec.c will check this flag to determine if unregister