diff options
Diffstat (limited to 'sound/soc/intel')
50 files changed, 1468 insertions, 851 deletions
diff --git a/sound/soc/intel/atom/sst/sst_acpi.c b/sound/soc/intel/atom/sst/sst_acpi.c index d3973936426a..29d44c989e5f 100644 --- a/sound/soc/intel/atom/sst/sst_acpi.c +++ b/sound/soc/intel/atom/sst/sst_acpi.c @@ -15,7 +15,6 @@ #include <linux/io.h> #include <linux/platform_device.h> #include <linux/firmware.h> -#include <linux/pm_runtime.h> #include <linux/pm_qos.h> #include <linux/dmi.h> #include <linux/acpi.h> diff --git a/sound/soc/intel/atom/sst/sst_ipc.c b/sound/soc/intel/atom/sst/sst_ipc.c index 4e039c7173d8..3fc2c9a6c44d 100644 --- a/sound/soc/intel/atom/sst/sst_ipc.c +++ b/sound/soc/intel/atom/sst/sst_ipc.c @@ -15,7 +15,6 @@ #include <linux/firmware.h> #include <linux/sched.h> #include <linux/delay.h> -#include <linux/pm_runtime.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> diff --git a/sound/soc/intel/atom/sst/sst_loader.c b/sound/soc/intel/atom/sst/sst_loader.c index eea889001c24..bf4ba6bcc429 100644 --- a/sound/soc/intel/atom/sst/sst_loader.c +++ b/sound/soc/intel/atom/sst/sst_loader.c @@ -20,7 +20,6 @@ #include <linux/sched.h> #include <linux/firmware.h> #include <linux/dmaengine.h> -#include <linux/pm_runtime.h> #include <linux/pm_qos.h> #include <sound/core.h> #include <sound/pcm.h> diff --git a/sound/soc/intel/atom/sst/sst_pci.c b/sound/soc/intel/atom/sst/sst_pci.c index 5862fe968083..4058b4f80a0c 100644 --- a/sound/soc/intel/atom/sst/sst_pci.c +++ b/sound/soc/intel/atom/sst/sst_pci.c @@ -15,7 +15,6 @@ #include <linux/pci.h> #include <linux/fs.h> #include <linux/firmware.h> -#include <linux/pm_runtime.h> #include <sound/core.h> #include <sound/soc.h> #include <asm/platform_sst_audio.h> diff --git a/sound/soc/intel/atom/sst/sst_stream.c b/sound/soc/intel/atom/sst/sst_stream.c index ea1ef8a61fa6..862a19ae5429 100644 --- a/sound/soc/intel/atom/sst/sst_stream.c +++ b/sound/soc/intel/atom/sst/sst_stream.c @@ -15,7 +15,6 @@ #include <linux/firmware.h> #include <linux/sched.h> #include <linux/delay.h> -#include <linux/pm_runtime.h> #include <sound/core.h> #include <sound/pcm.h> #include <sound/soc.h> diff --git a/sound/soc/intel/avs/apl.c b/sound/soc/intel/avs/apl.c index 02683dce277a..1860099c782a 100644 --- a/sound/soc/intel/avs/apl.c +++ b/sound/soc/intel/avs/apl.c @@ -169,6 +169,7 @@ static bool apl_lp_streaming(struct avs_dev *adev) { struct avs_path *path; + spin_lock(&adev->path_list_lock); /* Any gateway without buffer allocated in LP area disqualifies D0IX. */ list_for_each_entry(path, &adev->path_list, node) { struct avs_path_pipeline *ppl; @@ -188,11 +189,14 @@ static bool apl_lp_streaming(struct avs_dev *adev) if (cfg->copier.dma_type == INVALID_OBJECT_ID) continue; - if (!mod->gtw_attrs.lp_buffer_alloc) + if (!mod->gtw_attrs.lp_buffer_alloc) { + spin_unlock(&adev->path_list_lock); return false; + } } } } + spin_unlock(&adev->path_list_lock); return true; } diff --git a/sound/soc/intel/avs/avs.h b/sound/soc/intel/avs/avs.h index d7fccdcb9c16..0cf38c9e768e 100644 --- a/sound/soc/intel/avs/avs.h +++ b/sound/soc/intel/avs/avs.h @@ -283,8 +283,8 @@ void avs_release_firmwares(struct avs_dev *adev); int avs_dsp_init_module(struct avs_dev *adev, u16 module_id, u8 ppl_instance_id, u8 core_id, u8 domain, void *param, u32 param_size, - u16 *instance_id); -void avs_dsp_delete_module(struct avs_dev *adev, u16 module_id, u16 instance_id, + u8 *instance_id); +void avs_dsp_delete_module(struct avs_dev *adev, u16 module_id, u8 instance_id, u8 ppl_instance_id, u8 core_id); int avs_dsp_create_pipeline(struct avs_dev *adev, u16 req_size, u8 priority, bool lp, u16 attributes, u8 *instance_id); diff --git a/sound/soc/intel/avs/board_selection.c b/sound/soc/intel/avs/board_selection.c index b2823c2107f7..60f8fb0bff95 100644 --- a/sound/soc/intel/avs/board_selection.c +++ b/sound/soc/intel/avs/board_selection.c @@ -443,7 +443,7 @@ static int avs_register_i2s_boards(struct avs_dev *adev) } for (mach = boards->machs; mach->id[0]; mach++) { - if (!acpi_dev_present(mach->id, NULL, -1)) + if (!acpi_dev_present(mach->id, mach->uid, -1)) continue; if (mach->machine_quirk) diff --git a/sound/soc/intel/avs/boards/da7219.c b/sound/soc/intel/avs/boards/da7219.c index 1a1d572cc1d0..964a763732ab 100644 --- a/sound/soc/intel/avs/boards/da7219.c +++ b/sound/soc/intel/avs/boards/da7219.c @@ -181,38 +181,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - const int num_base = ARRAY_SIZE(card_base_routes); - const int num_dr = num_base + 2; - int idx; - - dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - memcpy(dr, card_base_routes, num_base * sizeof(*dr)); - - idx = num_base; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "Capture"); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - *routes = dr; - *num_routes = num_dr; - - return 0; -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, DA7219_DAI_NAME); @@ -230,14 +198,13 @@ static int avs_card_resume_post(struct snd_soc_card *card) static int avs_da7219_probe(struct platform_device *pdev) { - struct snd_soc_dapm_route *routes; struct snd_soc_dai_link *dai_link; struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int num_routes, ssp_port, ret; + int ssp_port, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; @@ -249,12 +216,6 @@ static int avs_da7219_probe(struct platform_device *pdev) return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); - if (ret) { - dev_err(dev, "Failed to create dapm routes: %d", ret); - return ret; - } - jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!jack || !card) @@ -271,8 +232,8 @@ static int avs_da7219_probe(struct platform_device *pdev) card->num_controls = ARRAY_SIZE(card_controls); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); - card->dapm_routes = routes; - card->num_dapm_routes = num_routes; + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); diff --git a/sound/soc/intel/avs/boards/dmic.c b/sound/soc/intel/avs/boards/dmic.c index 90a921638572..c270646faf86 100644 --- a/sound/soc/intel/avs/boards/dmic.c +++ b/sound/soc/intel/avs/boards/dmic.c @@ -44,8 +44,6 @@ static const struct snd_soc_dapm_widget card_widgets[] = { static const struct snd_soc_dapm_route card_routes[] = { {"DMic", NULL, "SoC DMIC"}, - {"DMIC Rx", NULL, "Capture"}, - {"DMIC WoV Rx", NULL, "Capture"}, }; static int avs_dmic_probe(struct platform_device *pdev) diff --git a/sound/soc/intel/avs/boards/hdaudio.c b/sound/soc/intel/avs/boards/hdaudio.c index a542a67e21d0..cb00bc86ac94 100644 --- a/sound/soc/intel/avs/boards/hdaudio.c +++ b/sound/soc/intel/avs/boards/hdaudio.c @@ -64,56 +64,6 @@ static int avs_create_dai_links(struct device *dev, struct hda_codec *codec, int return 0; } -static int avs_create_dapm_routes(struct device *dev, struct hda_codec *codec, int pcm_count, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - struct hda_pcm *pcm; - const char *cname = dev_name(&codec->core.dev); - int i, n = 0; - - /* at max twice the number of pcms */ - dr = devm_kcalloc(dev, pcm_count * 2, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list); - - for (i = 0; i < pcm_count; i++, pcm = list_next_entry(pcm, list)) { - struct hda_pcm_stream *stream; - int dir; - - dir = SNDRV_PCM_STREAM_PLAYBACK; - stream = &pcm->stream[dir]; - if (!stream->substreams) - goto capture_routes; - - dr[n].sink = devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, - snd_pcm_direction_name(dir)); - dr[n].source = devm_kasprintf(dev, GFP_KERNEL, "%s-cpu%d Tx", cname, i); - if (!dr[n].sink || !dr[n].source) - return -ENOMEM; - n++; - -capture_routes: - dir = SNDRV_PCM_STREAM_CAPTURE; - stream = &pcm->stream[dir]; - if (!stream->substreams) - continue; - - dr[n].sink = devm_kasprintf(dev, GFP_KERNEL, "%s-cpu%d Rx", cname, i); - dr[n].source = devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, - snd_pcm_direction_name(dir)); - if (!dr[n].sink || !dr[n].source) - return -ENOMEM; - n++; - } - - *routes = dr; - *num_routes = n; - return 0; -} - /* Should be aligned with SectionPCM's name from topology */ #define FEDAI_NAME_PREFIX "HDMI" @@ -172,13 +122,12 @@ static int avs_card_late_probe(struct snd_soc_card *card) static int avs_probing_link_init(struct snd_soc_pcm_runtime *rtm) { - struct snd_soc_dapm_route *routes; struct snd_soc_acpi_mach *mach; struct snd_soc_dai_link *links = NULL; struct snd_soc_card *card = rtm->card; struct hda_codec *codec; struct hda_pcm *pcm; - int ret, n, pcm_count = 0; + int ret, pcm_count = 0; mach = dev_get_platdata(card->dev); codec = mach->pdata; @@ -200,18 +149,6 @@ static int avs_probing_link_init(struct snd_soc_pcm_runtime *rtm) return ret; } - ret = avs_create_dapm_routes(card->dev, codec, pcm_count, &routes, &n); - if (ret < 0) { - dev_err(card->dev, "create routes failed: %d\n", ret); - return ret; - } - - ret = snd_soc_dapm_add_routes(&card->dapm, routes, n); - if (ret < 0) { - dev_err(card->dev, "add routes failed: %d\n", ret); - return ret; - } - return 0; } diff --git a/sound/soc/intel/avs/boards/i2s_test.c b/sound/soc/intel/avs/boards/i2s_test.c index 8f0fd87bc866..bc3065c6ceda 100644 --- a/sound/soc/intel/avs/boards/i2s_test.c +++ b/sound/soc/intel/avs/boards/i2s_test.c @@ -28,13 +28,11 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in dl->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-Codec", ssp_port); dl->cpus = devm_kzalloc(dev, sizeof(*dl->cpus), GFP_KERNEL); - dl->codecs = devm_kzalloc(dev, sizeof(*dl->codecs), GFP_KERNEL); - if (!dl->name || !dl->cpus || !dl->codecs) + if (!dl->name || !dl->cpus) return -ENOMEM; dl->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", ssp_port); - dl->codecs->name = devm_kasprintf(dev, GFP_KERNEL, "snd-soc-dummy"); - dl->codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL, "snd-soc-dummy-dai"); + dl->codecs = &asoc_dummy_dlc; if (!dl->cpus->dai_name || !dl->codecs->name || !dl->codecs->dai_name) return -ENOMEM; diff --git a/sound/soc/intel/avs/boards/max98357a.c b/sound/soc/intel/avs/boards/max98357a.c index 183123d08c5a..b9b20562c691 100644 --- a/sound/soc/intel/avs/boards/max98357a.c +++ b/sound/soc/intel/avs/boards/max98357a.c @@ -86,41 +86,14 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - const int num_base = ARRAY_SIZE(card_base_routes); - const int num_dr = num_base + 1; - int idx; - - dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - memcpy(dr, card_base_routes, num_base * sizeof(*dr)); - - idx = num_base; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "HiFi Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - *routes = dr; - *num_routes = num_dr; - - return 0; -} - static int avs_max98357a_probe(struct platform_device *pdev) { - struct snd_soc_dapm_route *routes; struct snd_soc_dai_link *dai_link; struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; struct device *dev = &pdev->dev; const char *pname; - int num_routes, ssp_port, ret; + int ssp_port, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; @@ -132,12 +105,6 @@ static int avs_max98357a_probe(struct platform_device *pdev) return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); - if (ret) { - dev_err(dev, "Failed to create dapm routes: %d", ret); - return ret; - } - card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) return -ENOMEM; @@ -151,8 +118,8 @@ static int avs_max98357a_probe(struct platform_device *pdev) card->num_controls = ARRAY_SIZE(card_controls); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); - card->dapm_routes = routes; - card->num_dapm_routes = num_routes; + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; ret = snd_soc_fixup_dai_links_platform_name(card, pname); diff --git a/sound/soc/intel/avs/boards/max98373.c b/sound/soc/intel/avs/boards/max98373.c index 8e221ecd34b0..3833251ade26 100644 --- a/sound/soc/intel/avs/boards/max98373.c +++ b/sound/soc/intel/avs/boards/max98373.c @@ -141,47 +141,14 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - const int num_base = ARRAY_SIZE(card_base_routes); - const int num_dr = num_base + 2; - int idx; - - dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - memcpy(dr, card_base_routes, num_base * sizeof(*dr)); - - idx = num_base; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Left HiFi Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Right HiFi Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - *routes = dr; - *num_routes = num_dr; - - return 0; -} - static int avs_max98373_probe(struct platform_device *pdev) { - struct snd_soc_dapm_route *routes; struct snd_soc_dai_link *dai_link; struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; struct device *dev = &pdev->dev; const char *pname; - int num_routes, ssp_port, ret; + int ssp_port, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; @@ -193,12 +160,6 @@ static int avs_max98373_probe(struct platform_device *pdev) return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); - if (ret) { - dev_err(dev, "Failed to create dapm routes: %d", ret); - return ret; - } - card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) return -ENOMEM; @@ -214,8 +175,8 @@ static int avs_max98373_probe(struct platform_device *pdev) card->num_controls = ARRAY_SIZE(card_controls); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); - card->dapm_routes = routes; - card->num_dapm_routes = num_routes; + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; ret = snd_soc_fixup_dai_links_platform_name(card, pname); diff --git a/sound/soc/intel/avs/boards/max98927.c b/sound/soc/intel/avs/boards/max98927.c index 7cccce99f92e..09b231bf4e6d 100644 --- a/sound/soc/intel/avs/boards/max98927.c +++ b/sound/soc/intel/avs/boards/max98927.c @@ -138,47 +138,14 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - const int num_base = ARRAY_SIZE(card_base_routes); - const int num_dr = num_base + 2; - int idx; - - dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - memcpy(dr, card_base_routes, num_base * sizeof(*dr)); - - idx = num_base; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Left HiFi Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Right HiFi Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - *routes = dr; - *num_routes = num_dr; - - return 0; -} - static int avs_max98927_probe(struct platform_device *pdev) { - struct snd_soc_dapm_route *routes; struct snd_soc_dai_link *dai_link; struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; struct device *dev = &pdev->dev; const char *pname; - int num_routes, ssp_port, ret; + int ssp_port, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; @@ -190,12 +157,6 @@ static int avs_max98927_probe(struct platform_device *pdev) return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); - if (ret) { - dev_err(dev, "Failed to create dapm routes: %d", ret); - return ret; - } - card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) return -ENOMEM; @@ -211,8 +172,8 @@ static int avs_max98927_probe(struct platform_device *pdev) card->num_controls = ARRAY_SIZE(card_controls); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); - card->dapm_routes = routes; - card->num_dapm_routes = num_routes; + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; ret = snd_soc_fixup_dai_links_platform_name(card, pname); diff --git a/sound/soc/intel/avs/boards/nau8825.c b/sound/soc/intel/avs/boards/nau8825.c index b69fc5567135..38c5087d98e9 100644 --- a/sound/soc/intel/avs/boards/nau8825.c +++ b/sound/soc/intel/avs/boards/nau8825.c @@ -215,38 +215,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - const int num_base = ARRAY_SIZE(card_base_routes); - const int num_dr = num_base + 2; - int idx; - - dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - memcpy(dr, card_base_routes, num_base * sizeof(*dr)); - - idx = num_base; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "Capture"); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - *routes = dr; - *num_routes = num_dr; - - return 0; -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, SKL_NUVOTON_CODEC_DAI); @@ -274,14 +242,13 @@ static int avs_card_resume_post(struct snd_soc_card *card) static int avs_nau8825_probe(struct platform_device *pdev) { - struct snd_soc_dapm_route *routes; struct snd_soc_dai_link *dai_link; struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int num_routes, ssp_port, ret; + int ssp_port, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; @@ -293,12 +260,6 @@ static int avs_nau8825_probe(struct platform_device *pdev) return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); - if (ret) { - dev_err(dev, "Failed to create dapm routes: %d", ret); - return ret; - } - jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!jack || !card) @@ -315,8 +276,8 @@ static int avs_nau8825_probe(struct platform_device *pdev) card->num_controls = ARRAY_SIZE(card_controls); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); - card->dapm_routes = routes; - card->num_dapm_routes = num_routes; + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); diff --git a/sound/soc/intel/avs/boards/rt274.c b/sound/soc/intel/avs/boards/rt274.c index 6a1e121f082f..ebfee54814ce 100644 --- a/sound/soc/intel/avs/boards/rt274.c +++ b/sound/soc/intel/avs/boards/rt274.c @@ -188,38 +188,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - const int num_base = ARRAY_SIZE(card_base_routes); - const int num_dr = num_base + 2; - int idx; - - dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - memcpy(dr, card_base_routes, num_base * sizeof(*dr)); - - idx = num_base; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Capture"); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - *routes = dr; - *num_routes = num_dr; - - return 0; -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, RT274_CODEC_DAI); @@ -237,14 +205,13 @@ static int avs_card_resume_post(struct snd_soc_card *card) static int avs_rt274_probe(struct platform_device *pdev) { - struct snd_soc_dapm_route *routes; struct snd_soc_dai_link *dai_link; struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int num_routes, ssp_port, ret; + int ssp_port, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; @@ -256,12 +223,6 @@ static int avs_rt274_probe(struct platform_device *pdev) return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); - if (ret) { - dev_err(dev, "Failed to create dapm routes: %d", ret); - return ret; - } - jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!jack || !card) @@ -278,8 +239,8 @@ static int avs_rt274_probe(struct platform_device *pdev) card->num_controls = ARRAY_SIZE(card_controls); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); - card->dapm_routes = routes; - card->num_dapm_routes = num_routes; + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); diff --git a/sound/soc/intel/avs/boards/rt286.c b/sound/soc/intel/avs/boards/rt286.c index 3551a05bd599..84cf9a0c8dfe 100644 --- a/sound/soc/intel/avs/boards/rt286.c +++ b/sound/soc/intel/avs/boards/rt286.c @@ -158,38 +158,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - const int num_base = ARRAY_SIZE(card_base_routes); - const int num_dr = num_base + 2; - int idx; - - dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - memcpy(dr, card_base_routes, num_base * sizeof(*dr)); - - idx = num_base; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Capture"); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - *routes = dr; - *num_routes = num_dr; - - return 0; -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, RT286_CODEC_DAI); @@ -207,14 +175,13 @@ static int avs_card_resume_post(struct snd_soc_card *card) static int avs_rt286_probe(struct platform_device *pdev) { - struct snd_soc_dapm_route *routes; struct snd_soc_dai_link *dai_link; struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int num_routes, ssp_port, ret; + int ssp_port, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; @@ -226,12 +193,6 @@ static int avs_rt286_probe(struct platform_device *pdev) return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); - if (ret) { - dev_err(dev, "Failed to create dapm routes: %d", ret); - return ret; - } - jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!jack || !card) @@ -248,8 +209,8 @@ static int avs_rt286_probe(struct platform_device *pdev) card->num_controls = ARRAY_SIZE(card_controls); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); - card->dapm_routes = routes; - card->num_dapm_routes = num_routes; + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); diff --git a/sound/soc/intel/avs/boards/rt298.c b/sound/soc/intel/avs/boards/rt298.c index 2923f3805bbe..3b0e2b1a3251 100644 --- a/sound/soc/intel/avs/boards/rt298.c +++ b/sound/soc/intel/avs/boards/rt298.c @@ -178,38 +178,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - const int num_base = ARRAY_SIZE(card_base_routes); - const int num_dr = num_base + 2; - int idx; - - dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - memcpy(dr, card_base_routes, num_base * sizeof(*dr)); - - idx = num_base; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Capture"); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - *routes = dr; - *num_routes = num_dr; - - return 0; -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, RT298_CODEC_DAI); @@ -227,14 +195,13 @@ static int avs_card_resume_post(struct snd_soc_card *card) static int avs_rt298_probe(struct platform_device *pdev) { - struct snd_soc_dapm_route *routes; struct snd_soc_dai_link *dai_link; struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int num_routes, ssp_port, ret; + int ssp_port, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; @@ -246,12 +213,6 @@ static int avs_rt298_probe(struct platform_device *pdev) return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); - if (ret) { - dev_err(dev, "Failed to create dapm routes: %d", ret); - return ret; - } - jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!jack || !card) @@ -268,8 +229,8 @@ static int avs_rt298_probe(struct platform_device *pdev) card->num_controls = ARRAY_SIZE(card_controls); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); - card->dapm_routes = routes; - card->num_dapm_routes = num_routes; + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); diff --git a/sound/soc/intel/avs/boards/rt5682.c b/sound/soc/intel/avs/boards/rt5682.c index b2c2ba93dcb5..7142a67900bf 100644 --- a/sound/soc/intel/avs/boards/rt5682.c +++ b/sound/soc/intel/avs/boards/rt5682.c @@ -234,38 +234,6 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - const int num_base = ARRAY_SIZE(card_base_routes); - const int num_dr = num_base + 2; - int idx; - - dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - memcpy(dr, card_base_routes, num_base * sizeof(*dr)); - - idx = num_base; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "AIF1 Capture"); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - *routes = dr; - *num_routes = num_dr; - - return 0; -} - static int avs_card_suspend_pre(struct snd_soc_card *card) { struct snd_soc_dai *codec_dai = snd_soc_card_get_codec_dai(card, AVS_RT5682_CODEC_DAI_NAME); @@ -283,14 +251,13 @@ static int avs_card_resume_post(struct snd_soc_card *card) static int avs_rt5682_probe(struct platform_device *pdev) { - struct snd_soc_dapm_route *routes; struct snd_soc_dai_link *dai_link; struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; struct snd_soc_jack *jack; struct device *dev = &pdev->dev; const char *pname; - int num_routes, ssp_port, ret; + int ssp_port, ret; if (pdev->id_entry && pdev->id_entry->driver_data) avs_rt5682_quirk = (unsigned long)pdev->id_entry->driver_data; @@ -308,12 +275,6 @@ static int avs_rt5682_probe(struct platform_device *pdev) return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); - if (ret) { - dev_err(dev, "Failed to create dapm routes: %d", ret); - return ret; - } - jack = devm_kzalloc(dev, sizeof(*jack), GFP_KERNEL); card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!jack || !card) @@ -330,8 +291,8 @@ static int avs_rt5682_probe(struct platform_device *pdev) card->num_controls = ARRAY_SIZE(card_controls); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); - card->dapm_routes = routes; - card->num_dapm_routes = num_routes; + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; snd_soc_card_set_drvdata(card, jack); diff --git a/sound/soc/intel/avs/boards/ssm4567.c b/sound/soc/intel/avs/boards/ssm4567.c index 2b7f5ad92aca..7324869d6132 100644 --- a/sound/soc/intel/avs/boards/ssm4567.c +++ b/sound/soc/intel/avs/boards/ssm4567.c @@ -129,59 +129,14 @@ static int avs_create_dai_link(struct device *dev, const char *platform_name, in return 0; } -static int avs_create_dapm_routes(struct device *dev, int ssp_port, - struct snd_soc_dapm_route **routes, int *num_routes) -{ - struct snd_soc_dapm_route *dr; - const int num_base = ARRAY_SIZE(card_base_routes); - const int num_dr = num_base + 4; - int idx; - - dr = devm_kcalloc(dev, num_dr, sizeof(*dr), GFP_KERNEL); - if (!dr) - return -ENOMEM; - - memcpy(dr, card_base_routes, num_base * sizeof(*dr)); - - idx = num_base; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Left Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "Right Playback"); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Tx", ssp_port); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "Left Capture Sense"); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - idx++; - dr[idx].sink = devm_kasprintf(dev, GFP_KERNEL, "ssp%d Rx", ssp_port); - dr[idx].source = devm_kasprintf(dev, GFP_KERNEL, "Right Capture Sense"); - if (!dr[idx].sink || !dr[idx].source) - return -ENOMEM; - - *routes = dr; - *num_routes = num_dr; - - return 0; -} - static int avs_ssm4567_probe(struct platform_device *pdev) { - struct snd_soc_dapm_route *routes; struct snd_soc_dai_link *dai_link; struct snd_soc_acpi_mach *mach; struct snd_soc_card *card; struct device *dev = &pdev->dev; const char *pname; - int num_routes, ssp_port, ret; + int ssp_port, ret; mach = dev_get_platdata(dev); pname = mach->mach_params.platform; @@ -193,12 +148,6 @@ static int avs_ssm4567_probe(struct platform_device *pdev) return ret; } - ret = avs_create_dapm_routes(dev, ssp_port, &routes, &num_routes); - if (ret) { - dev_err(dev, "Failed to create dapm routes: %d", ret); - return ret; - } - card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL); if (!card) return -ENOMEM; @@ -214,8 +163,8 @@ static int avs_ssm4567_probe(struct platform_device *pdev) card->num_controls = ARRAY_SIZE(card_controls); card->dapm_widgets = card_widgets; card->num_dapm_widgets = ARRAY_SIZE(card_widgets); - card->dapm_routes = routes; - card->num_dapm_routes = num_routes; + card->dapm_routes = card_base_routes; + card->num_dapm_routes = ARRAY_SIZE(card_base_routes); card->fully_routed = true; card->disable_route_checks = true; diff --git a/sound/soc/intel/avs/control.c b/sound/soc/intel/avs/control.c index a8b14b784f8a..3dfa2e9816db 100644 --- a/sound/soc/intel/avs/control.c +++ b/sound/soc/intel/avs/control.c @@ -21,17 +21,25 @@ static struct avs_dev *avs_get_kcontrol_adev(struct snd_kcontrol *kcontrol) return to_avs_dev(w->dapm->component->dev); } -static struct avs_path_module *avs_get_kcontrol_module(struct avs_dev *adev, u32 id) +static struct avs_path_module *avs_get_volume_module(struct avs_dev *adev, u32 id) { struct avs_path *path; struct avs_path_pipeline *ppl; struct avs_path_module *mod; - list_for_each_entry(path, &adev->path_list, node) - list_for_each_entry(ppl, &path->ppl_list, node) - list_for_each_entry(mod, &ppl->mod_list, node) - if (mod->template->ctl_id && mod->template->ctl_id == id) + spin_lock(&adev->path_list_lock); + list_for_each_entry(path, &adev->path_list, node) { + list_for_each_entry(ppl, &path->ppl_list, node) { + list_for_each_entry(mod, &ppl->mod_list, node) { + if (guid_equal(&mod->template->cfg_ext->type, &AVS_PEAKVOL_MOD_UUID) + && mod->template->ctl_id == id) { + spin_unlock(&adev->path_list_lock); return mod; + } + } + } + } + spin_unlock(&adev->path_list_lock); return NULL; } @@ -49,7 +57,7 @@ int avs_control_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va /* prevent access to modules while path is being constructed */ mutex_lock(&adev->path_mutex); - active_module = avs_get_kcontrol_module(adev, ctl_data->id); + active_module = avs_get_volume_module(adev, ctl_data->id); if (active_module) { ret = avs_ipc_peakvol_get_volume(adev, active_module->module_id, active_module->instance_id, &dspvols, @@ -89,7 +97,7 @@ int avs_control_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va changed = 1; } - active_module = avs_get_kcontrol_module(adev, ctl_data->id); + active_module = avs_get_volume_module(adev, ctl_data->id); if (active_module) { dspvol.channel_id = AVS_ALL_CHANNELS_MASK; dspvol.target_volume = *volume; diff --git a/sound/soc/intel/avs/dsp.c b/sound/soc/intel/avs/dsp.c index b881100d3e02..aa03af4473e9 100644 --- a/sound/soc/intel/avs/dsp.c +++ b/sound/soc/intel/avs/dsp.c @@ -225,7 +225,7 @@ err: int avs_dsp_init_module(struct avs_dev *adev, u16 module_id, u8 ppl_instance_id, u8 core_id, u8 domain, void *param, u32 param_size, - u16 *instance_id) + u8 *instance_id) { struct avs_module_entry mentry; bool was_loaded = false; @@ -272,7 +272,7 @@ err_mod_entry: return ret; } -void avs_dsp_delete_module(struct avs_dev *adev, u16 module_id, u16 instance_id, +void avs_dsp_delete_module(struct avs_dev *adev, u16 module_id, u8 instance_id, u8 ppl_instance_id, u8 core_id) { struct avs_module_entry mentry; diff --git a/sound/soc/intel/avs/messages.h b/sound/soc/intel/avs/messages.h index d3b60ae7d743..7f23a304b4a9 100644 --- a/sound/soc/intel/avs/messages.h +++ b/sound/soc/intel/avs/messages.h @@ -619,7 +619,7 @@ enum avs_channel_config { AVS_CHANNEL_CONFIG_DUAL_MONO = 9, AVS_CHANNEL_CONFIG_I2S_DUAL_STEREO_0 = 10, AVS_CHANNEL_CONFIG_I2S_DUAL_STEREO_1 = 11, - AVS_CHANNEL_CONFIG_4_CHANNEL = 12, + AVS_CHANNEL_CONFIG_7_1 = 12, AVS_CHANNEL_CONFIG_INVALID }; diff --git a/sound/soc/intel/avs/path.h b/sound/soc/intel/avs/path.h index 197222c5e008..657f7b093e80 100644 --- a/sound/soc/intel/avs/path.h +++ b/sound/soc/intel/avs/path.h @@ -37,7 +37,7 @@ struct avs_path_pipeline { struct avs_path_module { u16 module_id; - u16 instance_id; + u8 instance_id; union avs_gtw_attributes gtw_attrs; struct avs_tplg_module *template; diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c index 31c032a0f7e4..1fbb2c2fadb5 100644 --- a/sound/soc/intel/avs/pcm.c +++ b/sound/soc/intel/avs/pcm.c @@ -468,21 +468,34 @@ static int avs_dai_fe_startup(struct snd_pcm_substream *substream, struct snd_so host_stream = snd_hdac_ext_stream_assign(bus, substream, HDAC_EXT_STREAM_TYPE_HOST); if (!host_stream) { - kfree(data); - return -EBUSY; + ret = -EBUSY; + goto err; } data->host_stream = host_stream; - snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) + goto err; + /* avoid wrap-around with wall-clock */ - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000); - snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_rates); + ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_TIME, 20, 178000000); + if (ret < 0) + goto err; + + ret = snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_rates); + if (ret < 0) + goto err; + snd_pcm_set_sync(substream); dev_dbg(dai->dev, "%s fe STARTUP tag %d str %p", __func__, hdac_stream(host_stream)->stream_tag, substream); return 0; + +err: + kfree(data); + return ret; } static void avs_dai_fe_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c index 70a94201d6a5..275928281c6c 100644 --- a/sound/soc/intel/avs/probes.c +++ b/sound/soc/intel/avs/probes.c @@ -18,7 +18,7 @@ static int avs_dsp_init_probe(struct avs_dev *adev, union avs_connector_node_id { struct avs_probe_cfg cfg = {{0}}; struct avs_module_entry mentry; - u16 dummy; + u8 dummy; avs_get_module_entry(adev, &AVS_PROBE_MOD_UUID, &mentry); diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index 99308ed85277..f472f603ab75 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -662,11 +662,14 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH depends on MFD_INTEL_LPSS || COMPILE_TEST depends on SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES || COMPILE_TEST depends on SOUNDWIRE + select SND_SOC_MAX98363 select SND_SOC_MAX98373_I2C select SND_SOC_MAX98373_SDW select SND_SOC_RT700_SDW select SND_SOC_RT711_SDW select SND_SOC_RT711_SDCA_SDW + select SND_SOC_RT712_SDCA_SDW + select SND_SOC_RT712_SDCA_DMIC_SDW select SND_SOC_RT1308_SDW select SND_SOC_RT1308 select SND_SOC_RT1316_SDW @@ -674,6 +677,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH select SND_SOC_RT715_SDW select SND_SOC_RT715_SDCA_SDW select SND_SOC_RT5682_SDW + select SND_SOC_CS42L42_SDW select SND_SOC_DMIC select SND_SOC_INTEL_HDA_DSP_COMMON select SND_SOC_INTEL_SOF_MAXIM_COMMON diff --git a/sound/soc/intel/boards/Makefile b/sound/soc/intel/boards/Makefile index d1fd7a2b32db..931415d9cf6f 100644 --- a/sound/soc/intel/boards/Makefile +++ b/sound/soc/intel/boards/Makefile @@ -37,11 +37,13 @@ snd-soc-sof_da7219_max98373-objs := sof_da7219_max98373.o snd-soc-ehl-rt5660-objs := ehl_rt5660.o snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o snd-soc-sof-sdw-objs += sof_sdw.o \ - sof_sdw_max98373.o sof_sdw_rt_amp.o \ + sof_sdw_maxim.o sof_sdw_rt_amp.o \ sof_sdw_rt5682.o sof_sdw_rt700.o \ - sof_sdw_rt711.o sof_sdw_rt711_sdca.o \ - sof_sdw_rt715.o sof_sdw_rt715_sdca.o \ - sof_sdw_dmic.o sof_sdw_hdmi.o + sof_sdw_rt711.o sof_sdw_rt_sdca_jack_common.o \ + sof_sdw_rt712_sdca.o sof_sdw_rt715.o \ + sof_sdw_rt715_sdca.o sof_sdw_dmic.o \ + sof_sdw_cs42l42.o \ + sof_sdw_hdmi.o obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o obj-$(CONFIG_SND_SOC_INTEL_SOF_CS42L42_MACH) += snd-soc-sof_cs42l42.o obj-$(CONFIG_SND_SOC_INTEL_SOF_ES8336_MACH) += snd-soc-sof_es8336.o diff --git a/sound/soc/intel/boards/ehl_rt5660.c b/sound/soc/intel/boards/ehl_rt5660.c index d5235c294c4c..fee80638cba2 100644 --- a/sound/soc/intel/boards/ehl_rt5660.c +++ b/sound/soc/intel/boards/ehl_rt5660.c @@ -254,7 +254,6 @@ static void hdmi_link_init(struct snd_soc_card *card, struct sof_card_private *ctx, struct snd_soc_acpi_mach *mach) { - struct snd_soc_dai_link *link; int i; if (mach->mach_params.common_hdmi_codec_drv && @@ -267,11 +266,8 @@ static void hdmi_link_init(struct snd_soc_card *card, * if HDMI is not enabled in kernel config, or * hdmi codec is not supported */ - for (i = HDMI_LINK_START; i <= HDMI_LINE_END; i++) { - link = &card->dai_link[i]; - link->codecs[0].name = "snd-soc-dummy"; - link->codecs[0].dai_name = "snd-soc-dummy-dai"; - } + for (i = HDMI_LINK_START; i <= HDMI_LINE_END; i++) + card->dai_link[i].codecs[0] = asoc_dummy_dlc; } static int snd_ehl_rt5660_probe(struct platform_device *pdev) diff --git a/sound/soc/intel/boards/skl_hda_dsp_generic.c b/sound/soc/intel/boards/skl_hda_dsp_generic.c index 879ebba52832..a06e05154ae1 100644 --- a/sound/soc/intel/boards/skl_hda_dsp_generic.c +++ b/sound/soc/intel/boards/skl_hda_dsp_generic.c @@ -61,9 +61,6 @@ static const struct snd_soc_dapm_route skl_hda_map[] = { { "Alt Analog CPU Capture", NULL, "Alt Analog Codec Capture" }, }; -SND_SOC_DAILINK_DEF(dummy_codec, - DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai"))); - static int skl_hda_card_late_probe(struct snd_soc_card *card) { return skl_hda_hdmi_jack_init(card); @@ -158,9 +155,8 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params) card->num_dapm_widgets = ARRAY_SIZE(skl_hda_widgets); if (!ctx->idisp_codec) { for (i = 0; i < IDISP_DAI_COUNT; i++) { - skl_hda_be_dai_links[i].codecs = dummy_codec; - skl_hda_be_dai_links[i].num_codecs = - ARRAY_SIZE(dummy_codec); + skl_hda_be_dai_links[i].codecs = &asoc_dummy_dlc; + skl_hda_be_dai_links[i].num_codecs = 1; } } } diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index e9d190cb13b0..e6695e77d594 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -296,13 +296,6 @@ static struct snd_soc_dai_link_component dmic_component[] = { } }; -static struct snd_soc_dai_link_component dummy_component[] = { - { - .name = "snd-soc-dummy", - .dai_name = "snd-soc-dummy-dai", - } -}; - static int create_spk_amp_dai_links(struct device *dev, struct snd_soc_dai_link *links, struct snd_soc_dai_link_component *cpus, @@ -510,8 +503,8 @@ static int create_bt_offload_dai_links(struct device *dev, goto devm_err; links[*id].id = *id; - links[*id].codecs = dummy_component; - links[*id].num_codecs = ARRAY_SIZE(dummy_component); + links[*id].codecs = &asoc_dummy_dlc; + links[*id].num_codecs = 1; links[*id].platforms = platform_component; links[*id].num_platforms = ARRAY_SIZE(platform_component); diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index adf5852b2c9a..d6c38d8ea2ff 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -393,13 +393,6 @@ static struct snd_soc_dai_link_component dmic_component[] = { } }; -static struct snd_soc_dai_link_component dummy_component[] = { - { - .name = "snd-soc-dummy", - .dai_name = "snd-soc-dummy-dai", - } -}; - static int sof_es8336_late_probe(struct snd_soc_card *card) { struct sof_es8336_private *priv = snd_soc_card_get_drvdata(card); @@ -572,8 +565,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, if (!links[id].name) return NULL; links[id].id = id + hdmi_id_offset; - links[id].codecs = dummy_component; - links[id].num_codecs = ARRAY_SIZE(dummy_component); + links[id].codecs = &asoc_dummy_dlc; + links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_capture = 1; diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 6794a0249a9a..4fc6e1c6aef3 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -346,13 +346,6 @@ static struct snd_soc_dai_link_component nau8318_components[] = { } }; -static struct snd_soc_dai_link_component dummy_component[] = { - { - .name = "snd-soc-dummy", - .dai_name = "snd-soc-dummy-dai", - } -}; - static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, int ssp_codec, int ssp_amp, @@ -532,8 +525,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); if (!links[id].name) goto devm_err; - links[id].codecs = dummy_component; - links[id].num_codecs = ARRAY_SIZE(dummy_component); + links[id].codecs = &asoc_dummy_dlc; + links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_playback = 1; @@ -681,6 +674,16 @@ static const struct platform_device_id board_ids[] = { SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, + { + .name = "rpl_max98373_8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_MAX98373_SPEAKER_AMP_PRESENT | + SOF_NAU8825_SSP_AMP(1) | + SOF_NAU8825_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); diff --git a/sound/soc/intel/boards/sof_pcm512x.c b/sound/soc/intel/boards/sof_pcm512x.c index 5192e02b3cee..9f673ccf81b5 100644 --- a/sound/soc/intel/boards/sof_pcm512x.c +++ b/sound/soc/intel/boards/sof_pcm512x.c @@ -331,8 +331,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, devm_kasprintf(dev, GFP_KERNEL, "intel-hdmi-hifi%d", i); } else { - idisp_components[i - 1].name = "snd-soc-dummy"; - idisp_components[i - 1].dai_name = "snd-soc-dummy-dai"; + idisp_components[i - 1] = asoc_dummy_dlc; } if (!idisp_components[i - 1].dai_name) goto devm_err; diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 791a59c5f00d..7c034d671cf3 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -243,6 +243,20 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = { .callback = sof_rt5682_quirk_cb, .matches = { DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"), + DMI_MATCH(DMI_OEM_STRING, "AUDIO-ALC1019_ALC5682I_I2S"), + }, + .driver_data = (void *)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(2) | + SOF_SPEAKER_AMP_PRESENT | + SOF_RT1019_SPEAKER_AMP_PRESENT | + SOF_RT5682_SSP_AMP(0) | + SOF_RT5682_NUM_HDMIDEV(3) + ), + }, + { + .callback = sof_rt5682_quirk_cb, + .matches = { + DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Rex"), }, .driver_data = (void *)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(2) | @@ -607,13 +621,6 @@ static struct snd_soc_dai_link_component dmic_component[] = { } }; -static struct snd_soc_dai_link_component dummy_component[] = { - { - .name = "snd-soc-dummy", - .dai_name = "snd-soc-dummy-dai", - } -}; - #define IDISP_CODEC_MASK 0x4 static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, @@ -745,8 +752,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, if (!idisp_components[i - 1].dai_name) goto devm_err; } else { - idisp_components[i - 1].name = "snd-soc-dummy"; - idisp_components[i - 1].dai_name = "snd-soc-dummy-dai"; + idisp_components[i - 1] = asoc_dummy_dlc; } links[id].codecs = &idisp_components[i - 1]; @@ -841,8 +847,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); if (!links[id].name) goto devm_err; - links[id].codecs = dummy_component; - links[id].num_codecs = ARRAY_SIZE(dummy_component); + links[id].codecs = &asoc_dummy_dlc; + links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_playback = 1; @@ -989,14 +995,13 @@ static const struct platform_device_id board_ids[] = { .name = "sof_rt5682", }, { - .name = "tgl_mx98357_rt5682", + .name = "cml_rt1015_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | - SOF_RT5682_SSP_AMP(1) | - SOF_RT5682_NUM_HDMIDEV(4) | - SOF_BT_OFFLOAD_SSP(2) | - SOF_SSP_BT_OFFLOAD_PRESENT), + SOF_RT1015_SPEAKER_AMP_PRESENT | + SOF_RT5682_SSP_AMP(1)), }, { .name = "jsl_rt5682_rt1015", @@ -1008,33 +1013,38 @@ static const struct platform_device_id board_ids[] = { SOF_RT5682_SSP_AMP(1)), }, { - .name = "tgl_mx98373_rt5682", + .name = "jsl_rt5682_mx98360", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98373_SPEAKER_AMP_PRESENT | - SOF_RT5682_SSP_AMP(1) | - SOF_RT5682_NUM_HDMIDEV(4) | - SOF_BT_OFFLOAD_SSP(2) | - SOF_SSP_BT_OFFLOAD_PRESENT), + SOF_MAX98360A_SPEAKER_AMP_PRESENT | + SOF_RT5682_SSP_AMP(1)), }, { - .name = "jsl_rt5682_mx98360", + .name = "jsl_rt5682_rt1015p", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | - SOF_MAX98360A_SPEAKER_AMP_PRESENT | + SOF_RT1015P_SPEAKER_AMP_PRESENT | SOF_RT5682_SSP_AMP(1)), }, { - .name = "cml_rt1015_rt5682", + .name = "jsl_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_MCLK_24MHZ | + SOF_RT5682_SSP_CODEC(0)), + }, + { + .name = "tgl_mx98357_rt5682", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015_SPEAKER_AMP_PRESENT | - SOF_RT5682_SSP_AMP(1)), + SOF_RT5682_SSP_AMP(1) | + SOF_RT5682_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), }, { .name = "tgl_rt1011_rt5682", @@ -1048,13 +1058,15 @@ static const struct platform_device_id board_ids[] = { SOF_SSP_BT_OFFLOAD_PRESENT), }, { - .name = "jsl_rt5682_rt1015p", + .name = "tgl_mx98373_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | SOF_RT5682_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | - SOF_RT1015P_SPEAKER_AMP_PRESENT | - SOF_RT5682_SSP_AMP(1)), + SOF_MAX98373_SPEAKER_AMP_PRESENT | + SOF_RT5682_SSP_AMP(1) | + SOF_RT5682_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), }, { .name = "adl_mx98373_rt5682", @@ -1128,6 +1140,17 @@ static const struct platform_device_id board_ids[] = { SOF_SSP_BT_OFFLOAD_PRESENT), }, { + .name = "rpl_rt1019_rt5682", + .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | + SOF_RT5682_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_RT1019_SPEAKER_AMP_PRESENT | + SOF_RT5682_SSP_AMP(1) | + SOF_RT5682_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, + { .name = "mtl_mx98357_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | SOF_RT5682_SSP_CODEC(0) | @@ -1147,10 +1170,13 @@ static const struct platform_device_id board_ids[] = { SOF_RT5682_NUM_HDMIDEV(4)), }, { - .name = "jsl_rt5682", + .name = "mtl_rt1019_rt5682", .driver_data = (kernel_ulong_t)(SOF_RT5682_MCLK_EN | - SOF_RT5682_MCLK_24MHZ | - SOF_RT5682_SSP_CODEC(0)), + SOF_RT5682_SSP_CODEC(2) | + SOF_SPEAKER_AMP_PRESENT | + SOF_RT1019_SPEAKER_AMP_PRESENT | + SOF_RT5682_SSP_AMP(0) | + SOF_RT5682_NUM_HDMIDEV(3)), }, { } }; diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c index 6faf4a43eaf5..dbee8c98ff01 100644 --- a/sound/soc/intel/boards/sof_sdw.c +++ b/sound/soc/intel/boards/sof_sdw.c @@ -22,11 +22,16 @@ MODULE_PARM_DESC(quirk, "Board-specific quirk override"); #define INC_ID(BE, CPU, LINK) do { (BE)++; (CPU)++; (LINK)++; } while (0) +#define SDW_MAX_LINKS 4 + +/* To store SDW Pin index for each SoundWire link */ +static unsigned int sdw_pin_index[SDW_MAX_LINKS]; + static void log_quirks(struct device *dev) { - if (SOF_RT711_JDSRC(sof_sdw_quirk)) + if (SOF_JACK_JDSRC(sof_sdw_quirk)) dev_dbg(dev, "quirk realtek,jack-detect-source %ld\n", - SOF_RT711_JDSRC(sof_sdw_quirk)); + SOF_JACK_JDSRC(sof_sdw_quirk)); if (sof_sdw_quirk & SOF_SDW_FOUR_SPK) dev_dbg(dev, "quirk SOF_SDW_FOUR_SPK enabled\n"); if (sof_sdw_quirk & SOF_SDW_TGL_HDMI) @@ -192,6 +197,20 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { RT711_JD1), }, { + /* + * this entry covers HP Spectre x360 where the DMI information + * changed somehow + */ + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HP"), + DMI_MATCH(DMI_BOARD_NAME, "8709"), + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + SOF_SDW_PCH_DMIC | + RT711_JD1), + }, + { /* NUC15 'Bishop County' LAPBC510 and LAPBC710 skews */ .callback = sof_sdw_quirk_cb, .matches = { @@ -360,6 +379,15 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { { .callback = sof_sdw_quirk_cb, .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0B34"), + }, + /* No Jack */ + .driver_data = (void *)SOF_SDW_TGL_HDMI, + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { DMI_MATCH(DMI_SYS_VENDOR, "HP"), DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"), }, @@ -371,6 +399,16 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .callback = sof_sdw_quirk_cb, .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), + DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0BDA") + }, + .driver_data = (void *)(SOF_SDW_TGL_HDMI | + RT711_JD2 | + SOF_SDW_FOUR_SPK), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"), DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C10"), }, /* No Jack */ @@ -413,7 +451,32 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { .matches = { DMI_MATCH(DMI_PRODUCT_FAMILY, "Intel_mtlrvp"), }, - .driver_data = (void *)(RT711_JD1 | SOF_SDW_TGL_HDMI), + .driver_data = (void *)(RT711_JD1), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Meteor Lake Client Platform"), + }, + .driver_data = (void *)(RT711_JD2_100K), + }, + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Google"), + DMI_MATCH(DMI_PRODUCT_NAME, "Rex"), + }, + .driver_data = (void *)(SOF_SDW_PCH_DMIC), + }, + /* LunarLake devices */ + { + .callback = sof_sdw_quirk_cb, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "Lunar Lake Client Platform"), + }, + .driver_data = (void *)(RT711_JD2_100K), }, {} }; @@ -497,6 +560,55 @@ int sdw_trigger(struct snd_pcm_substream *substream, int cmd) return ret; } +int sdw_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + int ch = params_channels(params); + struct snd_soc_dai *codec_dai; + struct snd_soc_dai *cpu_dai; + unsigned int ch_mask; + int num_codecs; + int step; + int i; + int j; + + if (!rtd->dai_link->codec_ch_maps) + return 0; + + /* Identical data will be sent to all codecs in playback */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + ch_mask = GENMASK(ch - 1, 0); + step = 0; + } else { + num_codecs = rtd->dai_link->num_codecs; + + if (ch < num_codecs || ch % num_codecs != 0) { + dev_err(rtd->dev, "Channels number %d is invalid when codec number = %d\n", + ch, num_codecs); + return -EINVAL; + } + + ch_mask = GENMASK(ch / num_codecs - 1, 0); + step = hweight_long(ch_mask); + + } + + /* + * The captured data will be combined from each cpu DAI if the dai + * link has more than one codec DAIs. Set codec channel mask and + * ASoC will set the corresponding channel numbers for each cpu dai. + */ + for_each_rtd_cpu_dais(rtd, i, cpu_dai) { + for_each_rtd_codec_dais(rtd, j, codec_dai) { + if (rtd->dai_link->codec_ch_maps[j].connected_cpu_id != i) + continue; + rtd->dai_link->codec_ch_maps[j].ch_mask = ch_mask << (j * step); + } + } + return 0; +} + int sdw_hw_free(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); @@ -525,6 +637,7 @@ static const struct snd_soc_ops sdw_ops = { .startup = sdw_startup, .prepare = sdw_prepare, .trigger = sdw_trigger, + .hw_params = sdw_hw_params, .hw_free = sdw_hw_free, .shutdown = sdw_shutdown, }; @@ -532,134 +645,323 @@ static const struct snd_soc_ops sdw_ops = { static struct sof_sdw_codec_info codec_info_list[] = { { .part_id = 0x700, - .direction = {true, true}, - .dai_name = "rt700-aif1", - .init = sof_sdw_rt700_init, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt700-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt700_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x711, .version_id = 3, - .direction = {true, true}, - .dai_name = "rt711-sdca-aif1", - .init = sof_sdw_rt711_sdca_init, - .exit = sof_sdw_rt711_sdca_exit, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt711-sdca-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt_sdca_jack_init, + .exit = sof_sdw_rt_sdca_jack_exit, + }, + }, + .dai_num = 1, }, { .part_id = 0x711, .version_id = 2, - .direction = {true, true}, - .dai_name = "rt711-aif1", - .init = sof_sdw_rt711_init, - .exit = sof_sdw_rt711_exit, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt711-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt711_init, + .exit = sof_sdw_rt711_exit, + }, + }, + .dai_num = 1, + }, + { + .part_id = 0x712, + .version_id = 3, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt712-sdca-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt_sdca_jack_init, + .exit = sof_sdw_rt_sdca_jack_exit, + }, + { + .direction = {true, false}, + .dai_name = "rt712-sdca-aif2", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .init = sof_sdw_rt712_spk_init, + }, + }, + .dai_num = 2, + }, + { + .part_id = 0x1712, + .version_id = 3, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt712-sdca-dmic-aif1", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt712_sdca_dmic_init, + }, + }, + .dai_num = 1, + }, + { + .part_id = 0x713, + .version_id = 3, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt712-sdca-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt_sdca_jack_init, + .exit = sof_sdw_rt_sdca_jack_exit, + }, + }, + .dai_num = 1, + }, + { + .part_id = 0x1713, + .version_id = 3, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt712-sdca-dmic-aif1", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt712_sdca_dmic_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x1308, .acpi_id = "10EC1308", - .direction = {true, false}, - .dai_name = "rt1308-aif", + .dais = { + { + .direction = {true, false}, + .dai_name = "rt1308-aif", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .init = sof_sdw_rt_amp_init, + .exit = sof_sdw_rt_amp_exit, + }, + }, + .dai_num = 1, .ops = &sof_sdw_rt1308_i2s_ops, - .init = sof_sdw_rt_amp_init, - .exit = sof_sdw_rt_amp_exit, - .codec_type = SOF_SDW_CODEC_TYPE_AMP, }, { .part_id = 0x1316, - .direction = {true, true}, - .dai_name = "rt1316-aif", - .init = sof_sdw_rt_amp_init, - .exit = sof_sdw_rt_amp_exit, - .codec_type = SOF_SDW_CODEC_TYPE_AMP, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt1316-aif", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, + .init = sof_sdw_rt_amp_init, + .exit = sof_sdw_rt_amp_exit, + }, + }, + .dai_num = 1, }, { .part_id = 0x1318, - .direction = {true, true}, - .dai_name = "rt1318-aif", - .init = sof_sdw_rt_amp_init, - .codec_type = SOF_SDW_CODEC_TYPE_AMP, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt1318-aif", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, + .init = sof_sdw_rt_amp_init, + .exit = sof_sdw_rt_amp_exit, + }, + }, + .dai_num = 1, }, { .part_id = 0x714, .version_id = 3, - .direction = {false, true}, .ignore_pch_dmic = true, - .dai_name = "rt715-aif2", - .init = sof_sdw_rt715_sdca_init, - .codec_type = SOF_SDW_CODEC_TYPE_MIC, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt715-aif2", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt715_sdca_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x715, .version_id = 3, - .direction = {false, true}, .ignore_pch_dmic = true, - .dai_name = "rt715-aif2", - .init = sof_sdw_rt715_sdca_init, - .codec_type = SOF_SDW_CODEC_TYPE_MIC, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt715-aif2", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt715_sdca_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x714, .version_id = 2, - .direction = {false, true}, .ignore_pch_dmic = true, - .dai_name = "rt715-aif2", - .init = sof_sdw_rt715_init, - .codec_type = SOF_SDW_CODEC_TYPE_MIC, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt715-aif2", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt715_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x715, .version_id = 2, - .direction = {false, true}, .ignore_pch_dmic = true, - .dai_name = "rt715-aif2", - .init = sof_sdw_rt715_init, - .codec_type = SOF_SDW_CODEC_TYPE_MIC, + .dais = { + { + .direction = {false, true}, + .dai_name = "rt715-aif2", + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = sof_sdw_rt715_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x8373, - .direction = {true, true}, - .dai_name = "max98373-aif1", - .init = sof_sdw_mx8373_init, - .codec_type = SOF_SDW_CODEC_TYPE_AMP, + .dais = { + { + .direction = {true, true}, + .dai_name = "max98373-aif1", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_AMP_IN_DAI_ID}, + .init = sof_sdw_maxim_init, + }, + }, + .dai_num = 1, + }, + { + .part_id = 0x8363, + .dais = { + { + .direction = {true, false}, + .dai_name = "max98363-aif1", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .init = sof_sdw_maxim_init, + }, + }, + .dai_num = 1, }, { .part_id = 0x5682, - .direction = {true, true}, - .dai_name = "rt5682-sdw", - .init = sof_sdw_rt5682_init, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "rt5682-sdw", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_rt5682_init, + }, + }, + .dai_num = 1, + }, + { + .part_id = 0x4242, + .dais = { + { + .direction = {true, true}, + .dai_name = "cs42l42-sdw", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = sof_sdw_cs42l42_init, + }, + }, + .dai_num = 1, }, { .part_id = 0xaaaa, /* generic codec mockup */ .version_id = 0, - .direction = {true, true}, - .dai_name = "sdw-mockup-aif1", - .init = NULL, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "sdw-mockup-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = NULL, + }, + }, + .dai_num = 1, }, { .part_id = 0xaa55, /* headset codec mockup */ .version_id = 0, - .direction = {true, true}, - .dai_name = "sdw-mockup-aif1", - .init = NULL, - .codec_type = SOF_SDW_CODEC_TYPE_JACK, + .dais = { + { + .direction = {true, true}, + .dai_name = "sdw-mockup-aif1", + .dai_type = SOF_SDW_DAI_TYPE_JACK, + .dailink = {SDW_JACK_OUT_DAI_ID, SDW_JACK_IN_DAI_ID}, + .init = NULL, + }, + }, + .dai_num = 1, }, { .part_id = 0x55aa, /* amplifier mockup */ .version_id = 0, - .direction = {true, false}, - .dai_name = "sdw-mockup-aif1", - .init = NULL, - .codec_type = SOF_SDW_CODEC_TYPE_AMP, + .dais = { + { + .direction = {true, false}, + .dai_name = "sdw-mockup-aif1", + .dai_type = SOF_SDW_DAI_TYPE_AMP, + .dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID}, + .init = NULL, + }, + }, + .dai_num = 1, }, { .part_id = 0x5555, .version_id = 0, - .direction = {false, true}, - .dai_name = "sdw-mockup-aif1", - .codec_type = SOF_SDW_CODEC_TYPE_MIC, + .dais = { + { + .dai_name = "sdw-mockup-aif1", + .direction = {false, true}, + .dai_type = SOF_SDW_DAI_TYPE_MIC, + .dailink = {SDW_UNUSED_DAI_ID, SDW_DMIC_DAI_ID}, + .init = NULL, + }, + }, + .dai_num = 1, }, }; @@ -711,10 +1013,10 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li int *sdw_be_num, int *sdw_cpu_dai_num) { const struct snd_soc_acpi_link_adr *link; - int _codec_type = SOF_SDW_CODEC_TYPE_JACK; bool group_visited[SDW_MAX_GROUPS]; bool no_aggregation; int i; + int j; no_aggregation = sof_sdw_quirk & SOF_SDW_NO_AGGREGATION; *sdw_cpu_dai_num = 0; @@ -728,6 +1030,7 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li for (link = links; link->num_adr; link++) { const struct snd_soc_acpi_endpoint *endpoint; + struct sof_sdw_codec_info *codec_info; int codec_index; int stream; u64 adr; @@ -737,26 +1040,23 @@ static int get_sdw_dailink_info(struct device *dev, const struct snd_soc_acpi_li codec_index = find_codec_info_part(adr); if (codec_index < 0) return codec_index; - - if (codec_info_list[codec_index].codec_type < _codec_type) - dev_warn(dev, - "Unexpected address table ordering. Expected order: jack -> amp -> mic\n"); - - _codec_type = codec_info_list[codec_index].codec_type; + codec_info = &codec_info_list[codec_index]; endpoint = link->adr_d[i].endpoints; - /* count DAI number for playback and capture */ - for_each_pcm_streams(stream) { - if (!codec_info_list[codec_index].direction[stream]) - continue; + for (j = 0; j < codec_info->dai_num; j++) { + /* count DAI number for playback and capture */ + for_each_pcm_streams(stream) { + if (!codec_info->dais[j].direction[stream]) + continue; - (*sdw_cpu_dai_num)++; + (*sdw_cpu_dai_num)++; - /* count BE for each non-aggregated slave or group */ - if (!endpoint->aggregated || no_aggregation || - !group_visited[endpoint->group_id]) - (*sdw_be_num)++; + /* count BE for each non-aggregated slave or group */ + if (!endpoint->aggregated || no_aggregation || + !group_visited[endpoint->group_id]) + (*sdw_be_num)++; + } } if (endpoint->aggregated) @@ -832,7 +1132,8 @@ static int create_codec_dai_name(struct device *dev, struct snd_soc_codec_conf *codec_conf, int codec_count, int *codec_conf_index, - int adr_index) + int adr_index, + int dai_index) { int _codec_index = -1; int i; @@ -888,7 +1189,7 @@ static int create_codec_dai_name(struct device *dev, _codec_index = codec_index; codec[comp_index].dai_name = - codec_info_list[codec_index].dai_name; + codec_info_list[codec_index].dais[dai_index].dai_name; codec_conf[*codec_conf_index].dlc = codec[comp_index]; codec_conf[*codec_conf_index].name_prefix = link->adr_d[i].name_prefix; @@ -902,35 +1203,43 @@ static int create_codec_dai_name(struct device *dev, static int set_codec_init_func(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, - bool playback, int group_id) + bool playback, int group_id, int adr_index, int dai_index) { - int i; + int i = adr_index; do { /* * Initialize the codec. If codec is part of an aggregated * group (group_id>0), initialize all codecs belonging to * same group. + * The first link should start with link->adr_d[adr_index] + * because that is the device that we want to initialize and + * we should end immediately if it is not aggregated (group_id=0) */ - for (i = 0; i < link->num_adr; i++) { + for ( ; i < link->num_adr; i++) { int codec_index; codec_index = find_codec_info_part(link->adr_d[i].adr); if (codec_index < 0) return codec_index; + /* The group_id is > 0 iff the codec is aggregated */ if (link->adr_d[i].endpoints->group_id != group_id) continue; - if (codec_info_list[codec_index].init) - codec_info_list[codec_index].init(card, + + if (codec_info_list[codec_index].dais[dai_index].init) + codec_info_list[codec_index].dais[dai_index].init(card, link, dai_links, &codec_info_list[codec_index], playback); + if (!group_id) + return 0; } + i = 0; link++; - } while (link->mask && group_id); + } while (link->mask); return 0; } @@ -1022,6 +1331,17 @@ static int get_slave_info(const struct snd_soc_acpi_link_adr *adr_link, return 0; } +static void set_dailink_map(struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_maps, + int codec_num, int cpu_num) +{ + int step; + int i; + + step = codec_num / cpu_num; + for (i = 0; i < codec_num; i++) + sdw_codec_ch_maps[i].connected_cpu_id = i / step; +} + static const char * const type_strings[] = {"SimpleJack", "SmartAmp", "SmartMic"}; static int create_sdw_dailink(struct snd_soc_card *card, @@ -1035,19 +1355,21 @@ static int create_sdw_dailink(struct snd_soc_card *card, int codec_count, int *link_id, int *codec_conf_index, bool *ignore_pch_dmic, - bool append_codec_type, - int adr_index) + bool append_dai_type, + int adr_index, + int dai_index) { const struct snd_soc_acpi_link_adr *link_next; struct snd_soc_dai_link_component *codecs; + struct sof_sdw_codec_info *codec_info; int cpu_dai_id[SDW_MAX_CPU_DAIS]; int cpu_dai_num, cpu_dai_index; unsigned int group_id; int codec_idx = 0; - int i = 0, j = 0; int codec_index; int codec_num; int stream; + int i = 0; int ret; int k; @@ -1075,7 +1397,8 @@ static int create_sdw_dailink(struct snd_soc_card *card, continue; ret = create_codec_dai_name(dev, link_next, codecs, codec_idx, - codec_conf, codec_count, codec_conf_index, adr_index); + codec_conf, codec_count, codec_conf_index, + adr_index, dai_index); if (ret < 0) return ret; @@ -1088,25 +1411,14 @@ static int create_sdw_dailink(struct snd_soc_card *card, codec_index = find_codec_info_part(link->adr_d[adr_index].adr); if (codec_index < 0) return codec_index; + codec_info = &codec_info_list[codec_index]; - if (codec_info_list[codec_index].ignore_pch_dmic) + if (codec_info->ignore_pch_dmic) *ignore_pch_dmic = true; - /* Shift the first amplifier's *link_id to SDW_AMP_DAI_ID */ - if (codec_info_list[codec_index].codec_type == SOF_SDW_CODEC_TYPE_AMP && - *link_id < SDW_AMP_DAI_ID) - *link_id = SDW_AMP_DAI_ID; - - /* - * DAI ID is fixed at SDW_DMIC_DAI_ID for MICs to - * keep sdw DMIC and HDMI setting static in UCM - */ - if (codec_info_list[codec_index].codec_type == SOF_SDW_CODEC_TYPE_MIC && - *link_id < SDW_DMIC_DAI_ID) - *link_id = SDW_DMIC_DAI_ID; - cpu_dai_index = *cpu_id; for_each_pcm_streams(stream) { + struct snd_soc_dai_link_codec_ch_map *sdw_codec_ch_maps; char *name, *cpu_name; int playback, capture; static const char * const sdw_stream_name[] = { @@ -1116,14 +1428,25 @@ static int create_sdw_dailink(struct snd_soc_card *card, "SDW%d-Capture-%s", }; - if (!codec_info_list[codec_index].direction[stream]) + if (!codec_info->dais[dai_index].direction[stream]) continue; + *link_id = codec_info->dais[dai_index].dailink[stream]; + if (*link_id < 0) { + dev_err(dev, "Invalid dailink id %d\n", *link_id); + return -EINVAL; + } + + sdw_codec_ch_maps = devm_kcalloc(dev, codec_num, + sizeof(*sdw_codec_ch_maps), GFP_KERNEL); + if (!sdw_codec_ch_maps) + return -ENOMEM; + /* create stream name according to first link id */ - if (append_codec_type) { + if (append_dai_type) { name = devm_kasprintf(dev, GFP_KERNEL, sdw_stream_name[stream + 2], cpu_dai_id[0], - type_strings[codec_info_list[codec_index].codec_type]); + type_strings[codec_info->dais[dai_index].dai_type]); } else { name = devm_kasprintf(dev, GFP_KERNEL, sdw_stream_name[stream], cpu_dai_id[0]); @@ -1138,7 +1461,7 @@ static int create_sdw_dailink(struct snd_soc_card *card, for (k = 0; k < cpu_dai_num; k++) { cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SDW%d Pin%d", cpu_dai_id[k], - j + SDW_INTEL_BIDIR_PDI_BASE); + sdw_pin_index[cpu_dai_id[k]]++); if (!cpu_name) return -ENOMEM; @@ -1179,15 +1502,16 @@ static int create_sdw_dailink(struct snd_soc_card *card, */ dai_links[*link_index].nonatomic = true; + set_dailink_map(sdw_codec_ch_maps, codec_num, cpu_dai_num); + dai_links[*link_index].codec_ch_maps = sdw_codec_ch_maps; ret = set_codec_init_func(card, link, dai_links + (*link_index)++, - playback, group_id); + playback, group_id, adr_index, dai_index); if (ret < 0) { dev_err(dev, "failed to init codec %d", codec_index); return ret; } *cpu_id += cpu_dai_num; - j++; } return 0; @@ -1203,6 +1527,7 @@ static int sof_card_codec_conf_alloc(struct device *dev, const struct snd_soc_acpi_link_adr *adr_link; struct snd_soc_codec_conf *c_conf; int num_codecs = 0; + int codec_index; int i; adr_link = mach_params->links; @@ -1217,8 +1542,11 @@ static int sof_card_codec_conf_alloc(struct device *dev, adr_link->adr_d[i].adr); return -EINVAL; } + codec_index = find_codec_info_part(adr_link->adr_d[i].adr); + if (codec_index < 0) + return codec_index; + num_codecs += codec_info_list[codec_index].dai_num; } - num_codecs += adr_link->num_adr; } c_conf = devm_kzalloc(dev, num_codecs * sizeof(*c_conf), GFP_KERNEL); @@ -1243,7 +1571,7 @@ static int sof_card_dai_links_create(struct device *dev, const struct snd_soc_acpi_link_adr *adr_link; struct snd_soc_dai_link_component *cpus; struct snd_soc_codec_conf *codec_conf; - bool append_codec_type = false; + bool append_dai_type = false; bool ignore_pch_dmic = false; int codec_conf_count; int codec_conf_index = 0; @@ -1255,6 +1583,7 @@ static int sof_card_dai_links_create(struct device *dev, int total_cpu_dai_num; int sdw_cpu_dai_num; int i, j, be_id = 0; + int codec_index; int cpu_id = 0; int comp_num; int ret; @@ -1335,6 +1664,9 @@ static int sof_card_dai_links_create(struct device *dev, for (i = 0; i < SDW_MAX_GROUPS; i++) group_generated[i] = false; + for (i = 0; i < SDW_MAX_LINKS; i++) + sdw_pin_index[i] = SDW_INTEL_BIDIR_PDI_BASE; + for (; adr_link->num_adr; adr_link++) { /* * If there are two or more different devices on the same sdw link, we have to @@ -1343,12 +1675,20 @@ static int sof_card_dai_links_create(struct device *dev, * snd_soc_acpi_adr_device array. They won't be described in different adr_links. */ for (i = 0; i < adr_link->num_adr; i++) { + /* find codec info to get dai_num */ + codec_index = find_codec_info_part(adr_link->adr_d[i].adr); + if (codec_index < 0) + return codec_index; + if (codec_info_list[codec_index].dai_num > 1) { + append_dai_type = true; + goto out; + } for (j = 0; j < i; j++) { if ((SDW_PART_ID(adr_link->adr_d[i].adr) != SDW_PART_ID(adr_link->adr_d[j].adr)) || (SDW_MFG_ID(adr_link->adr_d[i].adr) != - SDW_MFG_ID(adr_link->adr_d[i].adr))) { - append_codec_type = true; + SDW_MFG_ID(adr_link->adr_d[j].adr))) { + append_dai_type = true; goto out; } } @@ -1373,15 +1713,22 @@ out: group_generated[endpoint->group_id]) continue; - ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num, - sdw_cpu_dai_num, cpus, adr_link, - &cpu_id, group_generated, - codec_conf, codec_conf_count, - &be_id, &codec_conf_index, - &ignore_pch_dmic, append_codec_type, i); - if (ret < 0) { - dev_err(dev, "failed to create dai link %d", link_index); - return ret; + /* find codec info to get dai_num */ + codec_index = find_codec_info_part(adr_link->adr_d[i].adr); + if (codec_index < 0) + return codec_index; + + for (j = 0; j < codec_info_list[codec_index].dai_num ; j++) { + ret = create_sdw_dailink(card, dev, &link_index, links, sdw_be_num, + sdw_cpu_dai_num, cpus, adr_link, + &cpu_id, group_generated, + codec_conf, codec_conf_count, + &be_id, &codec_conf_index, + &ignore_pch_dmic, append_dai_type, i, j); + if (ret < 0) { + dev_err(dev, "failed to create dai link %d", link_index); + return ret; + } } } } @@ -1420,18 +1767,19 @@ SSP: return -ENOMEM; ssp_components->name = codec_name; - ssp_components->dai_name = info->dai_name; + /* TODO: support multi codec dai on SSP when it is needed */ + ssp_components->dai_name = info->dais[0].dai_name; cpus[cpu_id].dai_name = cpu_name; - playback = info->direction[SNDRV_PCM_STREAM_PLAYBACK]; - capture = info->direction[SNDRV_PCM_STREAM_CAPTURE]; + playback = info->dais[0].direction[SNDRV_PCM_STREAM_PLAYBACK]; + capture = info->dais[0].direction[SNDRV_PCM_STREAM_CAPTURE]; init_dai_link(dev, links + link_index, be_id, name, playback, capture, cpus + cpu_id, 1, ssp_components, 1, NULL, info->ops); - ret = info->init(card, NULL, links + link_index, info, 0); + ret = info->dais[0].init(card, NULL, links + link_index, info, 0); if (ret < 0) return ret; @@ -1488,8 +1836,7 @@ HDMI: if (!idisp_components[i].dai_name) return -ENOMEM; } else { - idisp_components[i].name = "snd-soc-dummy"; - idisp_components[i].dai_name = "snd-soc-dummy-dai"; + idisp_components[i] = asoc_dummy_dlc; } cpu_name = devm_kasprintf(dev, GFP_KERNEL, @@ -1514,21 +1861,13 @@ HDMI: if (!name) return -ENOMEM; - ssp_components = devm_kzalloc(dev, sizeof(*ssp_components), - GFP_KERNEL); - if (!ssp_components) - return -ENOMEM; - - ssp_components->name = "snd-soc-dummy"; - ssp_components->dai_name = "snd-soc-dummy-dai"; - cpu_name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d Pin", port); if (!cpu_name) return -ENOMEM; cpus[cpu_id].dai_name = cpu_name; init_dai_link(dev, links + link_index, be_id, name, 1, 1, - cpus + cpu_id, 1, ssp_components, 1, NULL, NULL); + cpus + cpu_id, 1, &asoc_dummy_dlc, 1, NULL, NULL); } card->dai_link = links; @@ -1570,6 +1909,24 @@ static struct snd_soc_card card_sof_sdw = { .late_probe = sof_sdw_card_late_probe, }; +/* helper to get the link that the codec DAI is used */ +static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card, + const char *dai_name) +{ + struct snd_soc_dai_link *link; + int i; + int j; + + for_each_card_prelinks(card, i, link) { + for (j = 0; j < link->num_codecs; j++) { + /* Check each codec in a link */ + if (!strcmp(link->codecs[j].dai_name, dai_name)) + return link; + } + } + return NULL; +} + static void mc_dailink_exit_loop(struct snd_soc_card *card) { struct snd_soc_dai_link *link; @@ -1577,16 +1934,18 @@ static void mc_dailink_exit_loop(struct snd_soc_card *card) int i, j; for (i = 0; i < ARRAY_SIZE(codec_info_list); i++) { - if (!codec_info_list[i].exit) - continue; - /* - * We don't need to call .exit function if there is no matched - * dai link found. - */ - for_each_card_prelinks(card, j, link) { - if (!strcmp(link->codecs[0].dai_name, - codec_info_list[i].dai_name)) { - ret = codec_info_list[i].exit(card, link); + for (j = 0; j < codec_info_list[i].dai_num; j++) { + /* Check each dai in codec_info_lis to see if it is used in the link */ + if (!codec_info_list[i].dais[j].exit) + continue; + /* + * We don't need to call .exit function if there is no matched + * dai link found. + */ + link = mc_find_codec_dai_used(card, codec_info_list[i].dais[j].dai_name); + if (link) { + /* Do the .exit function if the codec dai is used in the link */ + ret = codec_info_list[i].dais[j].exit(card, link); if (ret) dev_warn(card->dev, "codec exit failed %d\n", diff --git a/sound/soc/intel/boards/sof_sdw_common.h b/sound/soc/intel/boards/sof_sdw_common.h index 081ab7eac5b6..37402170d5f9 100644 --- a/sound/soc/intel/boards/sof_sdw_common.h +++ b/sound/soc/intel/boards/sof_sdw_common.h @@ -15,7 +15,11 @@ #define MAX_NO_PROPS 2 #define MAX_HDMI_NUM 4 -#define SDW_AMP_DAI_ID 2 +#define SDW_UNUSED_DAI_ID -1 +#define SDW_JACK_OUT_DAI_ID 0 +#define SDW_JACK_IN_DAI_ID 1 +#define SDW_AMP_OUT_DAI_ID 2 +#define SDW_AMP_IN_DAI_ID 3 #define SDW_DMIC_DAI_ID 4 #define SDW_MAX_CPU_DAIS 16 #define SDW_INTEL_BIDIR_PDI_BASE 2 @@ -37,7 +41,7 @@ enum { SOF_I2S_SSP5 = BIT(5), }; -#define SOF_RT711_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) +#define SOF_JACK_JDSRC(quirk) ((quirk) & GENMASK(3, 0)) #define SOF_SDW_FOUR_SPK BIT(4) #define SOF_SDW_TGL_HDMI BIT(5) #define SOF_SDW_PCH_DMIC BIT(6) @@ -52,28 +56,37 @@ enum { (((quirk) << SOF_BT_OFFLOAD_SSP_SHIFT) & SOF_BT_OFFLOAD_SSP_MASK) #define SOF_SSP_BT_OFFLOAD_PRESENT BIT(18) -#define SOF_SDW_CODEC_TYPE_JACK 0 -#define SOF_SDW_CODEC_TYPE_AMP 1 -#define SOF_SDW_CODEC_TYPE_MIC 2 +#define SOF_SDW_DAI_TYPE_JACK 0 +#define SOF_SDW_DAI_TYPE_AMP 1 +#define SOF_SDW_DAI_TYPE_MIC 2 + +#define SOF_SDW_MAX_DAI_NUM 3 + +struct sof_sdw_codec_info; + +struct sof_sdw_dai_info { + const bool direction[2]; /* playback & capture support */ + const char *dai_name; + const int dai_type; + const int dailink[2]; /* dailink id for each direction */ + int (*init)(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); +}; struct sof_sdw_codec_info { const int part_id; const int version_id; - const int codec_type; int amp_num; const u8 acpi_id[ACPI_ID_LEN]; - const bool direction[2]; // playback & capture support const bool ignore_pch_dmic; - const char *dai_name; const struct snd_soc_ops *ops; + struct sof_sdw_dai_info dais[SOF_SDW_MAX_DAI_NUM]; + const int dai_num; - int (*init)(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback); - - int (*exit)(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); int (*codec_card_late_probe)(struct snd_soc_card *card); }; @@ -90,6 +103,8 @@ extern unsigned long sof_sdw_quirk; int sdw_startup(struct snd_pcm_substream *substream); int sdw_prepare(struct snd_pcm_substream *substream); int sdw_trigger(struct snd_pcm_substream *substream, int cmd); +int sdw_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params); int sdw_hw_free(struct snd_pcm_substream *substream); void sdw_shutdown(struct snd_pcm_substream *substream); @@ -110,12 +125,30 @@ int sof_sdw_rt711_init(struct snd_soc_card *card, int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); /* RT711-SDCA support */ -int sof_sdw_rt711_sdca_init(struct snd_soc_card *card, +int sof_sdw_rt_sdca_jack_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); +int sof_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); + +/* RT712-SDCA support */ +int sof_sdw_rt712_sdca_init(struct snd_soc_card *card, const struct snd_soc_acpi_link_adr *link, struct snd_soc_dai_link *dai_links, struct sof_sdw_codec_info *info, bool playback); -int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); +int sof_sdw_rt712_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link); +int sof_sdw_rt712_spk_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); +int sof_sdw_rt712_sdca_dmic_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); /* RT700 support */ int sof_sdw_rt700_init(struct snd_soc_card *card, @@ -151,12 +184,12 @@ int sof_sdw_rt715_sdca_init(struct snd_soc_card *card, struct sof_sdw_codec_info *info, bool playback); -/* MAX98373 support */ -int sof_sdw_mx8373_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback); +/* MAXIM codec support */ +int sof_sdw_maxim_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); /* RT5682 support */ int sof_sdw_rt5682_init(struct snd_soc_card *card, @@ -165,4 +198,11 @@ int sof_sdw_rt5682_init(struct snd_soc_card *card, struct sof_sdw_codec_info *info, bool playback); +/* CS42L42 support */ +int sof_sdw_cs42l42_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback); + #endif diff --git a/sound/soc/intel/boards/sof_sdw_cs42l42.c b/sound/soc/intel/boards/sof_sdw_cs42l42.c new file mode 100644 index 000000000000..c4a16e4c9f69 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_cs42l42.c @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2023 Intel Corporation + +/* + * sof_sdw_cs42l42 - Helpers to handle CS42L42 from generic machine driver + */ + +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/input.h> +#include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> +#include <sound/control.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include <sound/soc-dapm.h> +#include <sound/jack.h> +#include "sof_sdw_common.h" + +static const struct snd_soc_dapm_widget cs42l42_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route cs42l42_map[] = { + /* HP jack connectors - unknown if we have jack detection */ + {"Headphone", NULL, "cs42l42 HP"}, + + /* other jacks */ + {"cs42l42 HS", NULL, "Headset Mic"}, +}; + +static const struct snd_kcontrol_new cs42l42_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static struct snd_soc_jack_pin cs42l42_jack_pins[] = { + { + .pin = "Headphone", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, +}; + +static int cs42l42_rtd_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct mc_private *ctx = snd_soc_card_get_drvdata(card); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_component *component = codec_dai->component; + struct snd_soc_jack *jack; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s hs:cs42l42", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_add_card_controls(card, cs42l42_controls, + ARRAY_SIZE(cs42l42_controls)); + if (ret) { + dev_err(card->dev, "cs42l42 control addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, cs42l42_widgets, + ARRAY_SIZE(cs42l42_widgets)); + if (ret) { + dev_err(card->dev, "cs42l42 widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, cs42l42_map, + ARRAY_SIZE(cs42l42_map)); + + if (ret) { + dev_err(card->dev, "cs42l42 map addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + &ctx->sdw_headset, + cs42l42_jack_pins, + ARRAY_SIZE(cs42l42_jack_pins)); + if (ret) { + dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", + ret); + return ret; + } + + jack = &ctx->sdw_headset; + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + + ret = snd_soc_component_set_jack(component, jack, NULL); + + if (ret) + dev_err(rtd->card->dev, "Headset Jack call-back failed: %d\n", + ret); + + return ret; +} + +int sof_sdw_cs42l42_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + /* + * headset should be initialized once. + * Do it with dai link for playback. + */ + if (!playback) + return 0; + + dai_links->init = cs42l42_rtd_init; + + return 0; +} diff --git a/sound/soc/intel/boards/sof_sdw_max98373.c b/sound/soc/intel/boards/sof_sdw_maxim.c index 3d7df58c0f1d..414c4d8dac77 100644 --- a/sound/soc/intel/boards/sof_sdw_max98373.c +++ b/sound/soc/intel/boards/sof_sdw_maxim.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only // Copyright (c) 2020 Intel Corporation // -// sof_sdw_max98373 - Helpers to handle 2x MAX98373 +// sof_sdw_maxim - Helpers to handle maxim codecs // codec devices from generic machine driver #include <linux/device.h> @@ -13,12 +13,16 @@ #include "sof_sdw_common.h" #include "sof_maxim_common.h" -static const struct snd_soc_dapm_widget mx8373_widgets[] = { +static int maxim_part_id; +#define SOF_SDW_PART_ID_MAX98363 0x8363 +#define SOF_SDW_PART_ID_MAX98373 0x8373 + +static const struct snd_soc_dapm_widget maxim_widgets[] = { SND_SOC_DAPM_SPK("Left Spk", NULL), SND_SOC_DAPM_SPK("Right Spk", NULL), }; -static const struct snd_kcontrol_new mx8373_controls[] = { +static const struct snd_kcontrol_new maxim_controls[] = { SOC_DAPM_PIN_SWITCH("Left Spk"), SOC_DAPM_PIN_SWITCH("Right Spk"), }; @@ -29,22 +33,25 @@ static int spk_init(struct snd_soc_pcm_runtime *rtd) int ret; card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s spk:mx8373", - card->components); + "%s spk:mx%04x", + card->components, maxim_part_id); if (!card->components) return -ENOMEM; - ret = snd_soc_add_card_controls(card, mx8373_controls, - ARRAY_SIZE(mx8373_controls)); + dev_dbg(card->dev, "soundwire maxim card components assigned : %s\n", + card->components); + + ret = snd_soc_add_card_controls(card, maxim_controls, + ARRAY_SIZE(maxim_controls)); if (ret) { - dev_err(card->dev, "mx8373 ctrls addition failed: %d\n", ret); + dev_err(card->dev, "mx%04x ctrls addition failed: %d\n", maxim_part_id, ret); return ret; } - ret = snd_soc_dapm_new_controls(&card->dapm, mx8373_widgets, - ARRAY_SIZE(mx8373_widgets)); + ret = snd_soc_dapm_new_controls(&card->dapm, maxim_widgets, + ARRAY_SIZE(maxim_widgets)); if (ret) { - dev_err(card->dev, "mx8373 widgets addition failed: %d\n", ret); + dev_err(card->dev, "mx%04x widgets addition failed: %d\n", maxim_part_id, ret); return ret; } @@ -116,6 +123,7 @@ static const struct snd_soc_ops max_98373_sdw_ops = { .startup = sdw_startup, .prepare = mx8373_sdw_prepare, .trigger = sdw_trigger, + .hw_params = sdw_hw_params, .hw_free = mx8373_sdw_hw_free, .shutdown = sdw_shutdown, }; @@ -130,19 +138,30 @@ static int mx8373_sdw_late_probe(struct snd_soc_card *card) return snd_soc_dapm_sync(dapm); } -int sof_sdw_mx8373_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback) +int sof_sdw_maxim_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) { info->amp_num++; if (info->amp_num == 2) dai_links->init = spk_init; - info->codec_card_late_probe = mx8373_sdw_late_probe; - - dai_links->ops = &max_98373_sdw_ops; - + maxim_part_id = info->part_id; + switch (maxim_part_id) { + case SOF_SDW_PART_ID_MAX98363: + /* Default ops are set in function init_dai_link. + * called as part of function create_sdw_dailink + */ + break; + case SOF_SDW_PART_ID_MAX98373: + info->codec_card_late_probe = mx8373_sdw_late_probe; + dai_links->ops = &max_98373_sdw_ops; + break; + default: + dev_err(card->dev, "Invalid maxim_part_id %#x\n", maxim_part_id); + return -EINVAL; + } return 0; } diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c index 8291967f23f3..2b05e2a707de 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711.c +++ b/sound/soc/intel/boards/sof_sdw_rt711.c @@ -27,9 +27,9 @@ static int rt711_add_codec_device_props(struct device *sdw_dev) struct fwnode_handle *fwnode; int ret; - if (!SOF_RT711_JDSRC(sof_sdw_quirk)) + if (!SOF_JACK_JDSRC(sof_sdw_quirk)) return 0; - props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_RT711_JDSRC(sof_sdw_quirk)); + props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_JACK_JDSRC(sof_sdw_quirk)); fwnode = fwnode_create_software_node(props, NULL); if (IS_ERR(fwnode)) diff --git a/sound/soc/intel/boards/sof_sdw_rt712_sdca.c b/sound/soc/intel/boards/sof_sdw_rt712_sdca.c new file mode 100644 index 000000000000..84c8025d24e3 --- /dev/null +++ b/sound/soc/intel/boards/sof_sdw_rt712_sdca.c @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright (c) 2023 Intel Corporation + +/* + * sof_sdw_rt712_sdca - Helpers to handle RT712-SDCA from generic machine driver + */ + +#include <linux/device.h> +#include <linux/errno.h> +#include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_type.h> +#include <sound/control.h> +#include <sound/soc.h> +#include <sound/soc-acpi.h> +#include <sound/soc-dapm.h> +#include "sof_sdw_common.h" + +static const struct snd_soc_dapm_widget rt712_spk_widgets[] = { + SND_SOC_DAPM_SPK("Speaker", NULL), +}; + +/* + * dapm routes for rt712 spk will be registered dynamically according + * to the number of rt712 spk used. The first two entries will be registered + * for one codec case, and the last two entries are also registered + * if two rt712s are used. + */ +static const struct snd_soc_dapm_route rt712_spk_map[] = { + { "Speaker", NULL, "rt712 SPOL" }, + { "Speaker", NULL, "rt712 SPOR" }, +}; + +static const struct snd_kcontrol_new rt712_spk_controls[] = { + SOC_DAPM_PIN_SWITCH("Speaker"), +}; + +static int rt712_spk_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + int ret; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s spk:rt712", + card->components); + if (!card->components) + return -ENOMEM; + + ret = snd_soc_add_card_controls(card, rt712_spk_controls, + ARRAY_SIZE(rt712_spk_controls)); + if (ret) { + dev_err(card->dev, "rt712 spk controls addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_new_controls(&card->dapm, rt712_spk_widgets, + ARRAY_SIZE(rt712_spk_widgets)); + if (ret) { + dev_err(card->dev, "rt712 spk widgets addition failed: %d\n", ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&card->dapm, rt712_spk_map, ARRAY_SIZE(rt712_spk_map)); + if (ret) + dev_err(rtd->dev, "failed to add SPK map: %d\n", ret); + + return ret; +} + +int sof_sdw_rt712_spk_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + dai_links->init = rt712_spk_init; + + return 0; +} + +static int rt712_sdca_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + + card->components = devm_kasprintf(card->dev, GFP_KERNEL, + "%s mic:rt712-sdca-dmic", + card->components); + if (!card->components) + return -ENOMEM; + + return 0; +} + +int sof_sdw_rt712_sdca_dmic_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) +{ + dai_links->init = rt712_sdca_dmic_rtd_init; + + return 0; +} diff --git a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c b/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c index 7f16304d025b..623e3bebb888 100644 --- a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c +++ b/sound/soc/intel/boards/sof_sdw_rt_sdca_jack_common.c @@ -21,16 +21,16 @@ * Note this MUST be called before snd_soc_register_card(), so that the props * are in place before the codec component driver's probe function parses them. */ -static int rt711_sdca_add_codec_device_props(struct device *sdw_dev) +static int rt_sdca_jack_add_codec_device_props(struct device *sdw_dev) { struct property_entry props[MAX_NO_PROPS] = {}; struct fwnode_handle *fwnode; int ret; - if (!SOF_RT711_JDSRC(sof_sdw_quirk)) + if (!SOF_JACK_JDSRC(sof_sdw_quirk)) return 0; - props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_RT711_JDSRC(sof_sdw_quirk)); + props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_JACK_JDSRC(sof_sdw_quirk)); fwnode = fwnode_create_software_node(props, NULL); if (IS_ERR(fwnode)) @@ -43,23 +43,27 @@ static int rt711_sdca_add_codec_device_props(struct device *sdw_dev) return ret; } -static const struct snd_soc_dapm_widget rt711_sdca_widgets[] = { +static const struct snd_soc_dapm_widget rt_sdca_jack_widgets[] = { SND_SOC_DAPM_HP("Headphone", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), }; static const struct snd_soc_dapm_route rt711_sdca_map[] = { - /* Headphones */ { "Headphone", NULL, "rt711 HP" }, { "rt711 MIC2", NULL, "Headset Mic" }, }; -static const struct snd_kcontrol_new rt711_sdca_controls[] = { +static const struct snd_soc_dapm_route rt712_sdca_map[] = { + { "Headphone", NULL, "rt712 HP" }, + { "rt712 MIC2", NULL, "Headset Mic" }, +}; + +static const struct snd_kcontrol_new rt_sdca_jack_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone"), SOC_DAPM_PIN_SWITCH("Headset Mic"), }; -static struct snd_soc_jack_pin rt711_sdca_jack_pins[] = { +static struct snd_soc_jack_pin rt_sdca_jack_pins[] = { { .pin = "Headphone", .mask = SND_JACK_HEADPHONE, @@ -70,7 +74,7 @@ static struct snd_soc_jack_pin rt711_sdca_jack_pins[] = { }, }; -static int rt711_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd) +static int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; struct mc_private *ctx = snd_soc_card_get_drvdata(card); @@ -80,30 +84,38 @@ static int rt711_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd) int ret; card->components = devm_kasprintf(card->dev, GFP_KERNEL, - "%s hs:rt711-sdca", - card->components); + "%s hs:%s-sdca", + card->components, component->name_prefix); if (!card->components) return -ENOMEM; - ret = snd_soc_add_card_controls(card, rt711_sdca_controls, - ARRAY_SIZE(rt711_sdca_controls)); + ret = snd_soc_add_card_controls(card, rt_sdca_jack_controls, + ARRAY_SIZE(rt_sdca_jack_controls)); if (ret) { - dev_err(card->dev, "rt711-sdca controls addition failed: %d\n", ret); + dev_err(card->dev, "rt sdca jack controls addition failed: %d\n", ret); return ret; } - ret = snd_soc_dapm_new_controls(&card->dapm, rt711_sdca_widgets, - ARRAY_SIZE(rt711_sdca_widgets)); + ret = snd_soc_dapm_new_controls(&card->dapm, rt_sdca_jack_widgets, + ARRAY_SIZE(rt_sdca_jack_widgets)); if (ret) { - dev_err(card->dev, "rt711-sdca widgets addition failed: %d\n", ret); + dev_err(card->dev, "rt sdca jack widgets addition failed: %d\n", ret); return ret; } - ret = snd_soc_dapm_add_routes(&card->dapm, rt711_sdca_map, - ARRAY_SIZE(rt711_sdca_map)); + if (strstr(component->name_prefix, "rt711")) { + ret = snd_soc_dapm_add_routes(&card->dapm, rt711_sdca_map, + ARRAY_SIZE(rt711_sdca_map)); + } else if (strstr(component->name_prefix, "rt712")) { + ret = snd_soc_dapm_add_routes(&card->dapm, rt712_sdca_map, + ARRAY_SIZE(rt712_sdca_map)); + } else { + dev_err(card->dev, "%s is not supported\n", component->name_prefix); + return -EINVAL; + } if (ret) { - dev_err(card->dev, "rt711-sdca map addition failed: %d\n", ret); + dev_err(card->dev, "rt sdca jack map addition failed: %d\n", ret); return ret; } @@ -112,8 +124,8 @@ static int rt711_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd) SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3, &ctx->sdw_headset, - rt711_sdca_jack_pins, - ARRAY_SIZE(rt711_sdca_jack_pins)); + rt_sdca_jack_pins, + ARRAY_SIZE(rt_sdca_jack_pins)); if (ret) { dev_err(rtd->card->dev, "Headset Jack creation failed: %d\n", ret); @@ -136,24 +148,27 @@ static int rt711_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd) return ret; } -int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) +int sof_sdw_rt_sdca_jack_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link) { struct mc_private *ctx = snd_soc_card_get_drvdata(card); if (!ctx->headset_codec_dev) return 0; + if (!SOF_JACK_JDSRC(sof_sdw_quirk)) + return 0; + device_remove_software_node(ctx->headset_codec_dev); put_device(ctx->headset_codec_dev); return 0; } -int sof_sdw_rt711_sdca_init(struct snd_soc_card *card, - const struct snd_soc_acpi_link_adr *link, - struct snd_soc_dai_link *dai_links, - struct sof_sdw_codec_info *info, - bool playback) +int sof_sdw_rt_sdca_jack_init(struct snd_soc_card *card, + const struct snd_soc_acpi_link_adr *link, + struct snd_soc_dai_link *dai_links, + struct sof_sdw_codec_info *info, + bool playback) { struct mc_private *ctx = snd_soc_card_get_drvdata(card); struct device *sdw_dev; @@ -170,14 +185,14 @@ int sof_sdw_rt711_sdca_init(struct snd_soc_card *card, if (!sdw_dev) return -EPROBE_DEFER; - ret = rt711_sdca_add_codec_device_props(sdw_dev); + ret = rt_sdca_jack_add_codec_device_props(sdw_dev); if (ret < 0) { put_device(sdw_dev); return ret; } ctx->headset_codec_dev = sdw_dev; - dai_links->init = rt711_sdca_rtd_init; + dai_links->init = rt_sdca_jack_rtd_init; return 0; } diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c index ffd9c583dab1..0aef718e82b2 100644 --- a/sound/soc/intel/boards/sof_ssp_amp.c +++ b/sound/soc/intel/boards/sof_ssp_amp.c @@ -167,13 +167,6 @@ static struct snd_soc_dai_link_component dmic_component[] = { } }; -static struct snd_soc_dai_link_component dummy_component[] = { - { - .name = "snd-soc-dummy", - .dai_name = "snd-soc-dummy-dai", - } -}; - static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd) { struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card); @@ -233,8 +226,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, if (!links[id].name) return NULL; links[id].id = id; - links[id].codecs = dummy_component; - links[id].num_codecs = ARRAY_SIZE(dummy_component); + links[id].codecs = &asoc_dummy_dlc; + links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_capture = 1; @@ -331,8 +324,7 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, if (!idisp_components[i - 1].dai_name) goto devm_err; } else { - idisp_components[i - 1].name = "snd-soc-dummy"; - idisp_components[i - 1].dai_name = "snd-soc-dummy-dai"; + idisp_components[i - 1] = asoc_dummy_dlc; } links[id].codecs = &idisp_components[i - 1]; @@ -360,8 +352,8 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT", port); if (!links[id].name) goto devm_err; - links[id].codecs = dummy_component; - links[id].num_codecs = ARRAY_SIZE(dummy_component); + links[id].codecs = &asoc_dummy_dlc; + links[id].num_codecs = 1; links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_playback = 1; @@ -471,6 +463,15 @@ static const struct platform_device_id board_ids[] = { SOF_SSP_BT_OFFLOAD_PRESENT | SOF_CS35L41_SPEAKER_AMP_PRESENT), }, + { + .name = "adl_lt6911_hdmi_ssp", + .driver_data = (kernel_ulong_t)(SOF_NO_OF_HDMI_CAPTURE_SSP(2) | + SOF_HDMI_CAPTURE_1_SSP(0) | + SOF_HDMI_CAPTURE_2_SSP(2) | + SOF_SSP_HDMI_CAPTURE_PRESENT | + SOF_NO_OF_HDMI_PLAYBACK(3) | + SOF_HDMI_PLAYBACK_PRESENT), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); @@ -486,7 +487,7 @@ static struct platform_driver sof_ssp_amp_driver = { module_platform_driver(sof_ssp_amp_driver); MODULE_DESCRIPTION("ASoC Intel(R) SOF Amplifier Machine driver"); -MODULE_AUTHOR("balamurugan.c <balamurugan.c@intel.com>"); +MODULE_AUTHOR("Balamurugan C <balamurugan.c@intel.com>"); MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>"); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON); diff --git a/sound/soc/intel/common/Makefile b/sound/soc/intel/common/Makefile index 41054cf09ec9..07aa37dd90e9 100644 --- a/sound/soc/intel/common/Makefile +++ b/sound/soc/intel/common/Makefile @@ -10,6 +10,7 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m soc-acpi-intel-tgl-match.o soc-acpi-intel-ehl-match.o \ soc-acpi-intel-jsl-match.o soc-acpi-intel-adl-match.o \ soc-acpi-intel-rpl-match.o soc-acpi-intel-mtl-match.o \ + soc-acpi-intel-lnl-match.o \ soc-acpi-intel-hda-match.o \ soc-acpi-intel-sdw-mockup-match.o diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c index d8c80041388a..bcd66e0094b4 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -133,6 +133,15 @@ static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1316_1_single_adr[] = { + { + .adr = 0x000130025D131601ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt1316-1" + } +}; + static const struct snd_soc_acpi_adr_device rt1316_2_single_adr[] = { { .adr = 0x000230025D131601ull, @@ -312,6 +321,20 @@ static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link12_rt714_link0[] = {} }; +static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link1_rt714_link0[] = { + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1316_1_single_adr), + .adr_d = rt1316_1_single_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt714_0_adr), + .adr_d = rt714_0_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr adl_sdw_rt1316_link2_rt714_link3[] = { { .mask = BIT(2), @@ -557,12 +580,6 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { .quirk_data = &adl_max98360a_amp, .sof_tplg_filename = "sof-adl-max98360a-cs42l42.tplg", }, - /* place amp-only boards in the end of table */ - { - .id = "CSC3541", - .drv_name = "adl_cs35l41", - .sof_tplg_filename = "sof-adl-cs35l41.tplg", - }, { .comp_ids = &essx_83x6, .drv_name = "adl_es83x6_c1_h02", @@ -578,6 +595,17 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { SND_SOC_ACPI_TPLG_INTEL_SSP_MSB | SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER, }, + /* place amp-only boards in the end of table */ + { + .id = "CSC3541", + .drv_name = "adl_cs35l41", + .sof_tplg_filename = "sof-adl-cs35l41.tplg", + }, + { + .id = "INTC10B0", + .drv_name = "adl_lt6911_hdmi_ssp", + .sof_tplg_filename = "sof-adl-nocodec-hdmi-ssp02.tplg" + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_machines); @@ -621,6 +649,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = { .sof_tplg_filename = "sof-adl-rt1316-l2-mono-rt714-l3.tplg", }, { + .link_mask = 0x3, /* rt1316 on link1 & rt714 on link0 */ + .links = adl_sdw_rt1316_link1_rt714_link0, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-adl-rt1316-l1-mono-rt714-l0.tplg", + }, + { .link_mask = 0x7, /* rt714 on link0 & two rt1316s on link1 and link2 */ .links = adl_sdw_rt1316_link12_rt714_link0, .drv_name = "sof_sdw", diff --git a/sound/soc/intel/common/soc-acpi-intel-lnl-match.c b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c new file mode 100644 index 000000000000..9f35b77deb11 --- /dev/null +++ b/sound/soc/intel/common/soc-acpi-intel-lnl-match.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * soc-acpi-intel-lnl-match.c - tables and support for LNL ACPI enumeration. + * + * Copyright (c) 2023, Intel Corporation. All rights reserved. + * + */ + +#include <sound/soc-acpi.h> +#include <sound/soc-acpi-intel-match.h> +#include "soc-acpi-intel-sdw-mockup-match.h" + +struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_machines[] = { + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_lnl_machines); + +static const struct snd_soc_acpi_endpoint single_endpoint = { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, +}; + +static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { + { + .adr = 0x000030025D071101ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt711" + } +}; + +static const struct snd_soc_acpi_link_adr lnl_rvp[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + {} +}; + +/* this table is used when there is no I2S codec present */ +struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = { + /* mockup tests need to be first */ + { + .link_mask = GENMASK(3, 0), + .links = sdw_mockup_headset_2amps_mic, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-rt711-rt1308-rt715.tplg", + }, + { + .link_mask = BIT(0) | BIT(1) | BIT(3), + .links = sdw_mockup_headset_1amp_mic, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-rt711-rt1308-mono-rt715.tplg", + }, + { + .link_mask = GENMASK(2, 0), + .links = sdw_mockup_mic_headset_1amp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-rt715-rt711-rt1308-mono.tplg", + }, + { + .link_mask = BIT(0), + .links = lnl_rvp, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-lnl-rt711.tplg", + }, + {}, +}; +EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_lnl_sdw_machines); diff --git a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c index 7911c3af8071..ed9821adc1d9 100644 --- a/sound/soc/intel/common/soc-acpi-intel-mtl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-mtl-match.c @@ -20,6 +20,11 @@ static const struct snd_soc_acpi_codecs mtl_max98360a_amp = { .codecs = {"MX98360A"} }; +static const struct snd_soc_acpi_codecs mtl_rt1019p_amp = { + .num_codecs = 1, + .codecs = {"RTL1019"} +}; + static const struct snd_soc_acpi_codecs mtl_rt5682_rt5682s_hp = { .num_codecs = 2, .codecs = {"10EC5682", "RTL5682"}, @@ -40,6 +45,13 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_machines[] = { .quirk_data = &mtl_max98360a_amp, .sof_tplg_filename = "sof-mtl-max98360a-rt5682.tplg", }, + { + .comp_ids = &mtl_rt5682_rt5682s_hp, + .drv_name = "mtl_rt1019_rt5682", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &mtl_rt1019p_amp, + .sof_tplg_filename = "sof-mtl-rt1019-rt5682.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_machines); @@ -65,6 +77,21 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint rt712_endpoints[] = { + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { { .adr = 0x000030025D071101ull, @@ -74,6 +101,24 @@ static const struct snd_soc_acpi_adr_device rt711_sdca_0_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt712_0_single_adr[] = { + { + .adr = 0x000030025D071201ull, + .num_endpoints = ARRAY_SIZE(rt712_endpoints), + .endpoints = rt712_endpoints, + .name_prefix = "rt712" + } +}; + +static const struct snd_soc_acpi_adr_device rt1712_3_single_adr[] = { + { + .adr = 0x000330025D171201ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt712-dmic" + } +}; + static const struct snd_soc_acpi_adr_device mx8373_0_adr[] = { { .adr = 0x000023019F837300ull, @@ -98,6 +143,47 @@ static const struct snd_soc_acpi_adr_device rt5682_2_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt1316_2_group1_adr[] = { + { + .adr = 0x000230025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "rt1316-1" + } +}; + +static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = { + { + .adr = 0x000331025D131601ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "rt1316-2" + } +}; + +static const struct snd_soc_acpi_adr_device rt714_1_adr[] = { + { + .adr = 0x000130025D071401ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt714" + } +}; + +static const struct snd_soc_acpi_link_adr mtl_712_only[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt712_0_single_adr), + .adr_d = rt712_0_single_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1712_3_single_adr), + .adr_d = rt1712_3_single_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rt5682_link2_max98373_link0[] = { /* Expected order: jack -> amp */ { @@ -122,6 +208,69 @@ static const struct snd_soc_acpi_link_adr mtl_rvp[] = { {} }; +static const struct snd_soc_acpi_link_adr mtl_3_in_1_sdca[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1316_2_group1_adr), + .adr_d = rt1316_2_group1_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt1316_3_group1_adr), + .adr_d = rt1316_3_group1_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt714_1_adr), + .adr_d = rt714_1_adr, + }, + {} +}; + +static const struct snd_soc_acpi_adr_device mx8363_2_adr[] = { + { + .adr = 0x000230019F836300ull, + .num_endpoints = 1, + .endpoints = &spk_l_endpoint, + .name_prefix = "Left" + }, + { + .adr = 0x000231019F836300ull, + .num_endpoints = 1, + .endpoints = &spk_r_endpoint, + .name_prefix = "Right" + } +}; + +static const struct snd_soc_acpi_adr_device cs42l42_0_adr[] = { + { + .adr = 0x00001001FA424200ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "cs42l42" + } +}; + +static const struct snd_soc_acpi_link_adr cs42l42_link0_max98363_link2[] = { + /* Expected order: jack -> amp */ + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(cs42l42_0_adr), + .adr_d = cs42l42_0_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(mx8363_2_adr), + .adr_d = mx8363_2_adr, + }, + {} +}; + /* this table is used when there is no I2S codec present */ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { /* mockup tests need to be first */ @@ -144,6 +293,18 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .sof_tplg_filename = "sof-mtl-rt715-rt711-rt1308-mono.tplg", }, { + .link_mask = BIT(3) | BIT(0), + .links = mtl_712_only, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt712-l0-rt1712-l3.tplg", + }, + { + .link_mask = GENMASK(3, 0), + .links = mtl_3_in_1_sdca, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-rt711-l0-rt1316-l23-rt714-l1.tplg", + }, + { .link_mask = BIT(0), .links = mtl_rvp, .drv_name = "sof_sdw", @@ -155,6 +316,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = { .drv_name = "sof_sdw", .sof_tplg_filename = "sof-mtl-sdw-rt5682-l2-max98373-l0.tplg", }, + { + .link_mask = BIT(0) | BIT(2), + .links = cs42l42_link0_max98363_link2, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-mtl-sdw-cs42l42-l0-max98363-l2.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_sdw_machines); diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c index 749d371a86ae..302a08018572 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -179,6 +179,30 @@ static const struct snd_soc_acpi_link_adr rpl_sdca_3_in_1[] = { {} }; +static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link0_rt1316_link12_rt714_link3[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1316_1_group1_adr), + .adr_d = rt1316_1_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1316_2_group1_adr), + .adr_d = rt1316_2_group1_adr, + }, + { + .mask = BIT(3), + .num_adr = ARRAY_SIZE(rt714_3_adr), + .adr_d = rt714_3_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link2_rt1316_link01_rt714_link3[] = { { .mask = BIT(2), @@ -303,6 +327,16 @@ static const struct snd_soc_acpi_codecs rpl_max98360a_amp = { .codecs = {"MX98360A"}, }; +static const struct snd_soc_acpi_codecs rpl_max98373_amp = { + .num_codecs = 1, + .codecs = {"MX98373"} +}; + +static const struct snd_soc_acpi_codecs rpl_rt1019p_amp = { + .num_codecs = 1, + .codecs = {"RTL1019"} +}; + struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { { .comp_ids = &rpl_rt5682_hp, @@ -311,6 +345,20 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_machines[] = { .quirk_data = &rpl_max98360a_amp, .sof_tplg_filename = "sof-rpl-max98360a-rt5682.tplg", }, + { + .id = "10508825", + .drv_name = "rpl_max98373_8825", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &rpl_max98373_amp, + .sof_tplg_filename = "sof-rpl-max98373-nau8825.tplg", + }, + { + .comp_ids = &rpl_rt5682_hp, + .drv_name = "rpl_rt1019_rt5682", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &rpl_rt1019p_amp, + .sof_tplg_filename = "sof-rpl-rt1019-rt5682.tplg", + }, {}, }; EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_rpl_machines); @@ -331,6 +379,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { }, { .link_mask = 0xF, /* 4 active links required */ + .links = rpl_sdw_rt711_link0_rt1316_link12_rt714_link3, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-rt711-l0-rt1316-l12-rt714-l3.tplg", + }, + { + .link_mask = 0xF, /* 4 active links required */ .links = rpl_sdw_rt711_link0_rt1318_link12_rt714_link3, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-rpl-rt711-l0-rt1318-l12-rt714-l3.tplg", diff --git a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c index ef19150e7b2e..5804926c8b56 100644 --- a/sound/soc/intel/common/soc-acpi-intel-tgl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-tgl-match.c @@ -41,6 +41,21 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = { .group_id = 1, }; +static const struct snd_soc_acpi_endpoint rt712_endpoints[] = { + { + .num = 0, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, + { + .num = 1, + .aggregated = 0, + .group_position = 0, + .group_id = 0, + }, +}; + static const struct snd_soc_acpi_adr_device rt711_0_adr[] = { { .adr = 0x000020025D071100ull, @@ -170,6 +185,24 @@ static const struct snd_soc_acpi_adr_device rt1316_1_single_adr[] = { } }; +static const struct snd_soc_acpi_adr_device rt712_0_single_adr[] = { + { + .adr = 0x000030025D071201ull, + .num_endpoints = ARRAY_SIZE(rt712_endpoints), + .endpoints = rt712_endpoints, + .name_prefix = "rt712" + } +}; + +static const struct snd_soc_acpi_adr_device rt1712_1_single_adr[] = { + { + .adr = 0x000130025D171201ull, + .num_endpoints = 1, + .endpoints = &single_endpoint, + .name_prefix = "rt712-dmic" + } +}; + static const struct snd_soc_acpi_adr_device rt1316_1_group1_adr[] = { { .adr = 0x000131025D131601ull, /* unique ID is set for some reason */ @@ -353,6 +386,20 @@ static const struct snd_soc_acpi_link_adr tgl_3_in_1_sdca_mono[] = { {} }; +static const struct snd_soc_acpi_link_adr tgl_712_only[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt712_0_single_adr), + .adr_d = rt712_0_single_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1712_1_single_adr), + .adr_d = rt1712_1_single_adr, + }, + {} +}; + static const struct snd_soc_acpi_codecs tgl_max98373_amp = { .num_codecs = 1, .codecs = {"MX98373"} @@ -436,6 +483,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_tgl_sdw_machines[] = { .sof_tplg_filename = "sof-tgl-rt715-rt711-rt1308-mono.tplg", }, { + .link_mask = 0xF, /* 4 active links required */ + .links = tgl_712_only, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-tgl-rt712.tplg", + }, + { .link_mask = 0x7, .links = tgl_sdw_rt711_link1_rt1308_link2_rt715_link0, .drv_name = "sof_sdw", |