2020-05-01 09:58:50 -05:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2018-08-22 15:24:59 -05:00
|
|
|
// Copyright(c) 2015-18 Intel Corporation.
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Machine Driver for SKL+ platforms with DSP and iDisp, HDA Codecs
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/module.h>
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
#include <sound/core.h>
|
2024-09-12 20:03:03 +08:00
|
|
|
#include <sound/hda_codec.h>
|
2018-08-22 15:24:59 -05:00
|
|
|
#include <sound/jack.h>
|
|
|
|
#include <sound/pcm.h>
|
|
|
|
#include <sound/pcm_params.h>
|
|
|
|
#include <sound/soc.h>
|
2018-11-01 16:34:49 -05:00
|
|
|
#include <sound/soc-acpi.h>
|
2024-09-12 20:03:03 +08:00
|
|
|
#include "../../codecs/hdac_hda.h"
|
|
|
|
#include "../../sof/intel/hda.h"
|
|
|
|
#include "sof_board_helpers.h"
|
2018-08-22 15:24:59 -05:00
|
|
|
|
|
|
|
static int skl_hda_card_late_probe(struct snd_soc_card *card)
|
|
|
|
{
|
2024-09-12 20:03:03 +08:00
|
|
|
return sof_intel_board_card_late_probe(card);
|
2018-08-22 15:24:59 -05:00
|
|
|
}
|
|
|
|
|
2020-04-09 13:58:16 -05:00
|
|
|
#define HDA_CODEC_AUTOSUSPEND_DELAY_MS 1000
|
|
|
|
|
|
|
|
static void skl_set_hda_codec_autosuspend_delay(struct snd_soc_card *card)
|
|
|
|
{
|
2020-04-20 23:54:31 +03:00
|
|
|
struct snd_soc_pcm_runtime *rtd;
|
2020-04-09 13:58:16 -05:00
|
|
|
struct hdac_hda_priv *hda_pvt;
|
2020-04-20 23:54:31 +03:00
|
|
|
struct snd_soc_dai *dai;
|
|
|
|
|
|
|
|
for_each_card_rtds(card, rtd) {
|
2020-07-22 19:35:24 +02:00
|
|
|
if (!strstr(rtd->dai_link->codecs->name, "ehdaudio0D0"))
|
2020-04-20 23:54:31 +03:00
|
|
|
continue;
|
2023-09-26 06:24:24 +00:00
|
|
|
dai = snd_soc_rtd_to_codec(rtd, 0);
|
2020-04-20 23:54:31 +03:00
|
|
|
hda_pvt = snd_soc_component_get_drvdata(dai->component);
|
|
|
|
if (hda_pvt) {
|
|
|
|
/*
|
|
|
|
* all codecs are on the same bus, so it's sufficient
|
|
|
|
* to look up only the first one
|
|
|
|
*/
|
2022-08-16 13:17:24 +02:00
|
|
|
snd_hda_set_power_save(hda_pvt->codec->bus,
|
2020-04-20 23:54:31 +03:00
|
|
|
HDA_CODEC_AUTOSUSPEND_DELAY_MS);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-04-09 13:58:16 -05:00
|
|
|
}
|
|
|
|
|
2024-09-12 20:03:03 +08:00
|
|
|
#define IDISP_HDMI_BE_ID 1
|
|
|
|
#define HDA_BE_ID 4
|
|
|
|
#define DMIC01_BE_ID 6
|
|
|
|
#define DMIC16K_BE_ID 7
|
|
|
|
#define BT_OFFLOAD_BE_ID 8
|
|
|
|
|
|
|
|
#define HDA_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_IDISP_HDMI, \
|
|
|
|
SOF_LINK_HDA, \
|
|
|
|
SOF_LINK_DMIC01, \
|
|
|
|
SOF_LINK_DMIC16K, \
|
|
|
|
SOF_LINK_BT_OFFLOAD, \
|
|
|
|
SOF_LINK_NONE, \
|
|
|
|
SOF_LINK_NONE)
|
|
|
|
|
|
|
|
#define HDA_LINK_IDS SOF_LINK_ORDER(IDISP_HDMI_BE_ID, \
|
|
|
|
HDA_BE_ID, \
|
|
|
|
DMIC01_BE_ID, \
|
|
|
|
DMIC16K_BE_ID, \
|
|
|
|
BT_OFFLOAD_BE_ID, \
|
|
|
|
0, \
|
|
|
|
0)
|
|
|
|
|
|
|
|
static unsigned long
|
|
|
|
skl_hda_get_board_quirk(struct snd_soc_acpi_mach_params *mach_params)
|
|
|
|
{
|
|
|
|
unsigned long board_quirk = 0;
|
|
|
|
int ssp_bt;
|
|
|
|
|
|
|
|
if (hweight_long(mach_params->bt_link_mask) == 1) {
|
|
|
|
ssp_bt = fls(mach_params->bt_link_mask) - 1;
|
|
|
|
board_quirk |= SOF_SSP_PORT_BT_OFFLOAD(ssp_bt) |
|
|
|
|
SOF_BT_OFFLOAD_PRESENT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return board_quirk;
|
|
|
|
}
|
|
|
|
|
2025-06-19 11:42:21 +03:00
|
|
|
static int skl_hda_add_dai_link(struct snd_soc_card *card,
|
|
|
|
struct snd_soc_dai_link *link)
|
|
|
|
{
|
|
|
|
struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
|
|
|
|
|
|
|
|
/* Ignore the HDMI PCM link if iDisp is not present */
|
|
|
|
if (strstr(link->stream_name, "HDMI") && !ctx->hdmi.idisp_codec)
|
|
|
|
link->ignore = true;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-08-22 15:24:59 -05:00
|
|
|
static int skl_hda_audio_probe(struct platform_device *pdev)
|
|
|
|
{
|
2024-08-27 20:32:10 +08:00
|
|
|
struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
|
2024-09-12 20:03:03 +08:00
|
|
|
struct sof_card_private *ctx;
|
2024-04-26 10:21:12 -05:00
|
|
|
struct snd_soc_card *card;
|
2024-09-12 20:03:03 +08:00
|
|
|
unsigned long board_quirk = skl_hda_get_board_quirk(&mach->mach_params);
|
2018-08-22 15:24:59 -05:00
|
|
|
int ret;
|
|
|
|
|
2024-09-12 20:03:03 +08:00
|
|
|
card = devm_kzalloc(&pdev->dev, sizeof(struct snd_soc_card), GFP_KERNEL);
|
|
|
|
if (!card)
|
2018-08-22 15:24:59 -05:00
|
|
|
return -ENOMEM;
|
|
|
|
|
2024-09-05 10:20:17 +08:00
|
|
|
card->name = "hda-dsp";
|
|
|
|
card->owner = THIS_MODULE;
|
|
|
|
card->fully_routed = true;
|
|
|
|
card->late_probe = skl_hda_card_late_probe;
|
2025-06-19 11:42:21 +03:00
|
|
|
card->add_dai_link = skl_hda_add_dai_link;
|
2024-04-26 10:21:12 -05:00
|
|
|
|
2024-09-12 20:03:03 +08:00
|
|
|
dev_dbg(&pdev->dev, "board_quirk = %lx\n", board_quirk);
|
|
|
|
|
|
|
|
/* initialize ctx with board quirk */
|
|
|
|
ctx = sof_intel_board_get_ctx(&pdev->dev, board_quirk);
|
|
|
|
if (!ctx)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
if (HDA_EXT_CODEC(mach->mach_params.codec_mask))
|
|
|
|
ctx->hda_codec_present = true;
|
2020-07-14 16:28:04 +03:00
|
|
|
|
2024-08-27 20:32:11 +08:00
|
|
|
if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
|
|
|
|
ctx->hdmi.idisp_codec = true;
|
|
|
|
|
2024-09-12 20:03:03 +08:00
|
|
|
ctx->link_order_overwrite = HDA_LINK_ORDER;
|
|
|
|
ctx->link_id_overwrite = HDA_LINK_IDS;
|
2024-08-27 20:32:07 +08:00
|
|
|
|
2024-09-12 20:03:03 +08:00
|
|
|
/* update dai_link */
|
|
|
|
ret = sof_intel_board_set_dai_link(&pdev->dev, card, ctx);
|
|
|
|
if (ret)
|
2018-08-22 15:24:59 -05:00
|
|
|
return ret;
|
|
|
|
|
2024-04-26 10:21:12 -05:00
|
|
|
card->dev = &pdev->dev;
|
2018-08-22 15:24:59 -05:00
|
|
|
|
2019-12-04 15:15:44 -06:00
|
|
|
if (mach->mach_params.dmic_num > 0) {
|
2024-04-26 10:21:13 -05:00
|
|
|
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
|
|
|
|
"cfg-dmics:%d",
|
|
|
|
mach->mach_params.dmic_num);
|
|
|
|
if (!card->components)
|
|
|
|
return -ENOMEM;
|
2019-12-04 15:15:44 -06:00
|
|
|
}
|
|
|
|
|
2024-09-12 20:03:03 +08:00
|
|
|
ret = snd_soc_fixup_dai_links_platform_name(card,
|
|
|
|
mach->mach_params.platform);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
snd_soc_card_set_drvdata(card, ctx);
|
|
|
|
|
2024-04-26 10:21:12 -05:00
|
|
|
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
2020-04-09 13:58:16 -05:00
|
|
|
if (!ret)
|
2024-04-26 10:21:12 -05:00
|
|
|
skl_set_hda_codec_autosuspend_delay(card);
|
2020-04-09 13:58:16 -05:00
|
|
|
|
|
|
|
return ret;
|
2018-08-22 15:24:59 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct platform_driver skl_hda_audio = {
|
|
|
|
.probe = skl_hda_audio_probe,
|
|
|
|
.driver = {
|
|
|
|
.name = "skl_hda_dsp_generic",
|
|
|
|
.pm = &snd_soc_pm_ops,
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
module_platform_driver(skl_hda_audio)
|
|
|
|
|
|
|
|
/* Module information */
|
|
|
|
MODULE_DESCRIPTION("SKL/KBL/BXT/APL HDA Generic Machine driver");
|
|
|
|
MODULE_AUTHOR("Rakesh Ughreja <rakesh.a.ughreja@intel.com>");
|
|
|
|
MODULE_LICENSE("GPL v2");
|
|
|
|
MODULE_ALIAS("platform:skl_hda_dsp_generic");
|
module: Convert symbol namespace to string literal
Clean up the existing export namespace code along the same lines of
commit 33def8498fdd ("treewide: Convert macro and uses of __section(foo)
to __section("foo")") and for the same reason, it is not desired for the
namespace argument to be a macro expansion itself.
Scripted using
git grep -l -e MODULE_IMPORT_NS -e EXPORT_SYMBOL_NS | while read file;
do
awk -i inplace '
/^#define EXPORT_SYMBOL_NS/ {
gsub(/__stringify\(ns\)/, "ns");
print;
next;
}
/^#define MODULE_IMPORT_NS/ {
gsub(/__stringify\(ns\)/, "ns");
print;
next;
}
/MODULE_IMPORT_NS/ {
$0 = gensub(/MODULE_IMPORT_NS\(([^)]*)\)/, "MODULE_IMPORT_NS(\"\\1\")", "g");
}
/EXPORT_SYMBOL_NS/ {
if ($0 ~ /(EXPORT_SYMBOL_NS[^(]*)\(([^,]+),/) {
if ($0 !~ /(EXPORT_SYMBOL_NS[^(]*)\(([^,]+), ([^)]+)\)/ &&
$0 !~ /(EXPORT_SYMBOL_NS[^(]*)\(\)/ &&
$0 !~ /^my/) {
getline line;
gsub(/[[:space:]]*\\$/, "");
gsub(/[[:space:]]/, "", line);
$0 = $0 " " line;
}
$0 = gensub(/(EXPORT_SYMBOL_NS[^(]*)\(([^,]+), ([^)]+)\)/,
"\\1(\\2, \"\\3\")", "g");
}
}
{ print }' $file;
done
Requested-by: Masahiro Yamada <masahiroy@kernel.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://mail.google.com/mail/u/2/#inbox/FMfcgzQXKWgMmjdFwwdsfgxzKpVHWPlc
Acked-by: Greg KH <gregkh@linuxfoundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2024-12-02 15:59:47 +01:00
|
|
|
MODULE_IMPORT_NS("SND_SOC_INTEL_SOF_BOARD_HELPERS");
|