mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
ASoC: Intel: boards: updates for 6.7
Merge series from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>: A couple of new boards, one DMI quirk fix and a nice cleanup from Brent Lu to make all HDMI stuff common across drivers.
This commit is contained in:
commit
2e1a4596dc
17 changed files with 458 additions and 613 deletions
|
@ -44,6 +44,9 @@ config SND_SOC_INTEL_SOF_NUVOTON_COMMON
|
|||
config SND_SOC_INTEL_SOF_SSP_COMMON
|
||||
tristate
|
||||
|
||||
config SND_SOC_INTEL_SOF_BOARD_HELPERS
|
||||
tristate
|
||||
|
||||
if SND_SOC_INTEL_CATPT
|
||||
|
||||
config SND_SOC_INTEL_HASWELL_MACH
|
||||
|
@ -495,8 +498,8 @@ config SND_SOC_INTEL_SOF_RT5682_MACH
|
|||
select SND_SOC_RT5682_I2C
|
||||
select SND_SOC_RT5682S
|
||||
select SND_SOC_DMIC
|
||||
select SND_SOC_HDAC_HDMI
|
||||
select SND_SOC_INTEL_HDA_DSP_COMMON
|
||||
select SND_SOC_INTEL_SOF_BOARD_HELPERS
|
||||
select SND_SOC_INTEL_SOF_MAXIM_COMMON
|
||||
select SND_SOC_INTEL_SOF_REALTEK_COMMON
|
||||
select SND_SOC_INTEL_SOF_SSP_COMMON
|
||||
|
@ -514,8 +517,8 @@ config SND_SOC_INTEL_SOF_CS42L42_MACH
|
|||
select SND_SOC_CS42L42
|
||||
select SND_SOC_MAX98357A
|
||||
select SND_SOC_DMIC
|
||||
select SND_SOC_HDAC_HDMI
|
||||
select SND_SOC_INTEL_HDA_DSP_COMMON
|
||||
select SND_SOC_INTEL_SOF_BOARD_HELPERS
|
||||
select SND_SOC_INTEL_SOF_MAXIM_COMMON
|
||||
select SND_SOC_INTEL_SOF_SSP_COMMON
|
||||
help
|
||||
|
@ -565,8 +568,8 @@ config SND_SOC_INTEL_SOF_NAU8825_MACH
|
|||
select SND_SOC_MAX98357A
|
||||
select SND_SOC_NAU8315
|
||||
select SND_SOC_DMIC
|
||||
select SND_SOC_HDAC_HDMI
|
||||
select SND_SOC_INTEL_HDA_DSP_COMMON
|
||||
select SND_SOC_INTEL_SOF_BOARD_HELPERS
|
||||
select SND_SOC_INTEL_SOF_MAXIM_COMMON
|
||||
select SND_SOC_INTEL_SOF_NUVOTON_COMMON
|
||||
select SND_SOC_INTEL_SOF_REALTEK_COMMON
|
||||
|
@ -637,8 +640,8 @@ config SND_SOC_INTEL_SOF_SSP_AMP_MACH
|
|||
select SND_SOC_RT1308
|
||||
select SND_SOC_CS35L41_I2C
|
||||
select SND_SOC_DMIC
|
||||
select SND_SOC_HDAC_HDMI
|
||||
select SND_SOC_INTEL_HDA_DSP_COMMON
|
||||
select SND_SOC_INTEL_SOF_BOARD_HELPERS
|
||||
select SND_SOC_INTEL_SOF_REALTEK_COMMON
|
||||
select SND_SOC_INTEL_SOF_CIRRUS_COMMON
|
||||
select SND_SOC_INTEL_SOF_SSP_COMMON
|
||||
|
|
|
@ -102,3 +102,6 @@ obj-$(CONFIG_SND_SOC_INTEL_SOF_NUVOTON_COMMON) += snd-soc-intel-sof-nuvoton-comm
|
|||
|
||||
snd-soc-intel-sof-ssp-common-objs += sof_ssp_common.o
|
||||
obj-$(CONFIG_SND_SOC_INTEL_SOF_SSP_COMMON) += snd-soc-intel-sof-ssp-common.o
|
||||
|
||||
snd-soc-intel-sof-board-helpers-objs += sof_board_helpers.o
|
||||
obj-$(CONFIG_SND_SOC_INTEL_SOF_BOARD_HELPERS) += snd-soc-intel-sof-board-helpers.o
|
||||
|
|
112
sound/soc/intel/boards/sof_board_helpers.c
Normal file
112
sound/soc/intel/boards/sof_board_helpers.c
Normal file
|
@ -0,0 +1,112 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
//
|
||||
// Copyright(c) 2023 Intel Corporation. All rights reserved.
|
||||
|
||||
#include <sound/soc.h>
|
||||
#include "hda_dsp_common.h"
|
||||
#include "sof_board_helpers.h"
|
||||
|
||||
/*
|
||||
* Intel HDMI DAI Link
|
||||
*/
|
||||
static int hdmi_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
|
||||
|
||||
ctx->hdmi.hdmi_comp = dai->component;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sof_intel_board_card_late_probe(struct snd_soc_card *card)
|
||||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
|
||||
|
||||
if (!ctx->hdmi_num)
|
||||
return 0;
|
||||
|
||||
if (!ctx->hdmi.idisp_codec)
|
||||
return 0;
|
||||
|
||||
if (!ctx->hdmi.hdmi_comp)
|
||||
return -EINVAL;
|
||||
|
||||
return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp);
|
||||
}
|
||||
EXPORT_SYMBOL_NS(sof_intel_board_card_late_probe, SND_SOC_INTEL_SOF_BOARD_HELPERS);
|
||||
|
||||
/*
|
||||
* DAI Link Helpers
|
||||
*/
|
||||
static struct snd_soc_dai_link_component platform_component[] = {
|
||||
{
|
||||
/* name might be overridden during probe */
|
||||
.name = "0000:00:1f.3"
|
||||
}
|
||||
};
|
||||
|
||||
int sof_intel_board_set_intel_hdmi_link(struct device *dev,
|
||||
struct snd_soc_dai_link *link, int be_id,
|
||||
int hdmi_id, bool idisp_codec)
|
||||
{
|
||||
struct snd_soc_dai_link_component *cpus, *codecs;
|
||||
|
||||
dev_dbg(dev, "link %d: intel hdmi, hdmi id %d, idisp codec %d\n",
|
||||
be_id, hdmi_id, idisp_codec);
|
||||
|
||||
/* link name */
|
||||
link->name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", hdmi_id);
|
||||
if (!link->name)
|
||||
return -ENOMEM;
|
||||
|
||||
/* cpus */
|
||||
cpus = devm_kzalloc(dev, sizeof(struct snd_soc_dai_link_component),
|
||||
GFP_KERNEL);
|
||||
if (!cpus)
|
||||
return -ENOMEM;
|
||||
|
||||
cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", hdmi_id);
|
||||
if (!cpus->dai_name)
|
||||
return -ENOMEM;
|
||||
|
||||
link->cpus = cpus;
|
||||
link->num_cpus = 1;
|
||||
|
||||
/* codecs */
|
||||
if (idisp_codec) {
|
||||
codecs = devm_kzalloc(dev,
|
||||
sizeof(struct snd_soc_dai_link_component),
|
||||
GFP_KERNEL);
|
||||
if (!codecs)
|
||||
return -ENOMEM;
|
||||
|
||||
codecs->name = "ehdaudio0D2";
|
||||
codecs->dai_name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"intel-hdmi-hifi%d", hdmi_id);
|
||||
if (!codecs->dai_name)
|
||||
return -ENOMEM;
|
||||
|
||||
link->codecs = codecs;
|
||||
} else {
|
||||
link->codecs = &snd_soc_dummy_dlc;
|
||||
}
|
||||
link->num_codecs = 1;
|
||||
|
||||
/* platforms */
|
||||
link->platforms = platform_component;
|
||||
link->num_platforms = ARRAY_SIZE(platform_component);
|
||||
|
||||
link->id = be_id;
|
||||
link->init = (hdmi_id == 1) ? hdmi_init : NULL;
|
||||
link->no_pcm = 1;
|
||||
link->dpcm_playback = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_NS(sof_intel_board_set_intel_hdmi_link, SND_SOC_INTEL_SOF_BOARD_HELPERS);
|
||||
|
||||
MODULE_DESCRIPTION("ASoC Intel SOF Machine Driver Board Helpers");
|
||||
MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
|
54
sound/soc/intel/boards/sof_board_helpers.h
Normal file
54
sound/soc/intel/boards/sof_board_helpers.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright(c) 2023 Intel Corporation.
|
||||
*/
|
||||
|
||||
#ifndef __SOF_INTEL_BOARD_HELPERS_H
|
||||
#define __SOF_INTEL_BOARD_HELPERS_H
|
||||
|
||||
#include <sound/soc.h>
|
||||
#include "sof_hdmi_common.h"
|
||||
#include "sof_ssp_common.h"
|
||||
|
||||
/*
|
||||
* sof_rt5682_private: private data for rt5682 machine driver
|
||||
*
|
||||
* @mclk: mclk clock data
|
||||
* @is_legacy_cpu: true for BYT/CHT boards
|
||||
*/
|
||||
struct sof_rt5682_private {
|
||||
struct clk *mclk;
|
||||
bool is_legacy_cpu;
|
||||
};
|
||||
|
||||
/*
|
||||
* sof_card_private: common data for machine drivers
|
||||
*
|
||||
* @headset_jack: headset jack data
|
||||
* @hdmi: init data for hdmi dai link
|
||||
* @codec_type: type of headset codec
|
||||
* @amp_type: type of speaker amplifier
|
||||
* @hdmi_num: number of Intel HDMI BE link
|
||||
* @rt5682: private data for rt5682 machine driver
|
||||
*/
|
||||
struct sof_card_private {
|
||||
struct snd_soc_jack headset_jack;
|
||||
struct sof_hdmi_private hdmi;
|
||||
|
||||
enum sof_ssp_codec codec_type;
|
||||
enum sof_ssp_codec amp_type;
|
||||
|
||||
int hdmi_num;
|
||||
|
||||
union {
|
||||
struct sof_rt5682_private rt5682;
|
||||
};
|
||||
};
|
||||
|
||||
int sof_intel_board_card_late_probe(struct snd_soc_card *card);
|
||||
|
||||
int sof_intel_board_set_intel_hdmi_link(struct device *dev,
|
||||
struct snd_soc_dai_link *link, int be_id,
|
||||
int hdmi_id, bool idisp_codec);
|
||||
|
||||
#endif /* __SOF_INTEL_BOARD_HELPERS_H */
|
|
@ -19,14 +19,11 @@
|
|||
#include <sound/sof.h>
|
||||
#include <sound/soc-acpi.h>
|
||||
#include <dt-bindings/sound/cs42l42.h>
|
||||
#include "../../codecs/hdac_hdmi.h"
|
||||
#include "../common/soc-intel-quirks.h"
|
||||
#include "hda_dsp_common.h"
|
||||
#include "sof_board_helpers.h"
|
||||
#include "sof_maxim_common.h"
|
||||
#include "sof_ssp_common.h"
|
||||
|
||||
#define NAME_SIZE 32
|
||||
|
||||
#define SOF_CS42L42_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0))
|
||||
#define SOF_CS42L42_SSP_CODEC_MASK (GENMASK(2, 0))
|
||||
#define SOF_CS42L42_SSP_AMP_SHIFT 4
|
||||
|
@ -70,40 +67,6 @@ static struct snd_soc_jack_pin jack_pins[] = {
|
|||
/* Default: SSP2 */
|
||||
static unsigned long sof_cs42l42_quirk = SOF_CS42L42_SSP_CODEC(2);
|
||||
|
||||
struct sof_hdmi_pcm {
|
||||
struct list_head head;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
struct snd_soc_jack hdmi_jack;
|
||||
int device;
|
||||
};
|
||||
|
||||
struct sof_card_private {
|
||||
struct snd_soc_jack headset_jack;
|
||||
struct list_head hdmi_pcm_list;
|
||||
bool common_hdmi_codec_drv;
|
||||
enum sof_ssp_codec codec_type;
|
||||
enum sof_ssp_codec amp_type;
|
||||
};
|
||||
|
||||
static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
|
||||
struct sof_hdmi_pcm *pcm;
|
||||
|
||||
pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
|
||||
if (!pcm)
|
||||
return -ENOMEM;
|
||||
|
||||
/* dai_link id is 1:1 mapped to the PCM device */
|
||||
pcm->device = rtd->dai_link->id;
|
||||
pcm->codec_dai = dai;
|
||||
|
||||
list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sof_cs42l42_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
||||
|
@ -184,39 +147,7 @@ static struct snd_soc_dai_link_component platform_component[] = {
|
|||
|
||||
static int sof_card_late_probe(struct snd_soc_card *card)
|
||||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
|
||||
struct snd_soc_component *component = NULL;
|
||||
char jack_name[NAME_SIZE];
|
||||
struct sof_hdmi_pcm *pcm;
|
||||
int err;
|
||||
|
||||
if (list_empty(&ctx->hdmi_pcm_list))
|
||||
return -EINVAL;
|
||||
|
||||
if (ctx->common_hdmi_codec_drv) {
|
||||
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
|
||||
head);
|
||||
component = pcm->codec_dai->component;
|
||||
return hda_dsp_hdmi_build_controls(card, component);
|
||||
}
|
||||
|
||||
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
|
||||
component = pcm->codec_dai->component;
|
||||
snprintf(jack_name, sizeof(jack_name),
|
||||
"HDMI/DP, pcm=%d Jack", pcm->device);
|
||||
err = snd_soc_card_jack_new(card, jack_name,
|
||||
SND_JACK_AVOUT, &pcm->hdmi_jack);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
|
||||
&pcm->hdmi_jack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return hdac_hdmi_jack_port_init(component, &card->dapm);
|
||||
return sof_intel_board_card_late_probe(card);
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new sof_controls[] = {
|
||||
|
@ -432,65 +363,6 @@ static int create_dmic_dai_links(struct device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int create_hdmi_dai_links(struct device *dev,
|
||||
struct snd_soc_dai_link *links,
|
||||
struct snd_soc_dai_link_component *cpus,
|
||||
int *id, int hdmi_num)
|
||||
{
|
||||
struct snd_soc_dai_link_component *idisp_components;
|
||||
int i;
|
||||
|
||||
/* HDMI */
|
||||
if (hdmi_num <= 0)
|
||||
return 0;
|
||||
|
||||
idisp_components = devm_kcalloc(dev,
|
||||
hdmi_num,
|
||||
sizeof(struct snd_soc_dai_link_component), GFP_KERNEL);
|
||||
if (!idisp_components)
|
||||
goto devm_err;
|
||||
|
||||
for (i = 1; i <= hdmi_num; i++) {
|
||||
links[*id].name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"iDisp%d", i);
|
||||
if (!links[*id].name)
|
||||
goto devm_err;
|
||||
|
||||
links[*id].id = *id;
|
||||
links[*id].cpus = &cpus[*id];
|
||||
links[*id].num_cpus = 1;
|
||||
links[*id].cpus->dai_name = devm_kasprintf(dev,
|
||||
GFP_KERNEL,
|
||||
"iDisp%d Pin",
|
||||
i);
|
||||
if (!links[*id].cpus->dai_name)
|
||||
goto devm_err;
|
||||
|
||||
idisp_components[i - 1].name = "ehdaudio0D2";
|
||||
idisp_components[i - 1].dai_name = devm_kasprintf(dev,
|
||||
GFP_KERNEL,
|
||||
"intel-hdmi-hifi%d",
|
||||
i);
|
||||
if (!idisp_components[i - 1].dai_name)
|
||||
goto devm_err;
|
||||
|
||||
links[*id].codecs = &idisp_components[i - 1];
|
||||
links[*id].num_codecs = 1;
|
||||
links[*id].platforms = platform_component;
|
||||
links[*id].num_platforms = ARRAY_SIZE(platform_component);
|
||||
links[*id].init = sof_hdmi_init;
|
||||
links[*id].dpcm_playback = 1;
|
||||
links[*id].no_pcm = 1;
|
||||
|
||||
(*id)++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
devm_err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int create_bt_offload_dai_links(struct device *dev,
|
||||
struct snd_soc_dai_link *links,
|
||||
struct snd_soc_dai_link_component *cpus,
|
||||
|
@ -534,11 +406,14 @@ static int create_bt_offload_dai_links(struct device *dev,
|
|||
static struct snd_soc_dai_link *
|
||||
sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
|
||||
int ssp_codec, int ssp_amp, int ssp_bt,
|
||||
int dmic_be_num, int hdmi_num)
|
||||
int dmic_be_num, int hdmi_num, bool idisp_codec)
|
||||
{
|
||||
struct snd_soc_dai_link_component *cpus;
|
||||
struct snd_soc_dai_link *links;
|
||||
int ret, id = 0, link_seq;
|
||||
int ret;
|
||||
int id = 0;
|
||||
int link_seq;
|
||||
int i;
|
||||
|
||||
links = devm_kcalloc(dev, sof_audio_card_cs42l42.num_links,
|
||||
sizeof(struct snd_soc_dai_link), GFP_KERNEL);
|
||||
|
@ -579,11 +454,18 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
|
|||
}
|
||||
break;
|
||||
case LINK_HDMI:
|
||||
ret = create_hdmi_dai_links(dev, links, cpus, &id, hdmi_num);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "fail to create hdmi dai links, ret %d\n",
|
||||
ret);
|
||||
goto devm_err;
|
||||
for (i = 1; i <= hdmi_num; i++) {
|
||||
ret = sof_intel_board_set_intel_hdmi_link(dev,
|
||||
&links[id],
|
||||
id, i,
|
||||
idisp_codec);
|
||||
if (ret) {
|
||||
dev_err(dev, "fail to create hdmi link, ret %d\n",
|
||||
ret);
|
||||
goto devm_err;
|
||||
}
|
||||
|
||||
id++;
|
||||
}
|
||||
break;
|
||||
case LINK_BT:
|
||||
|
@ -611,10 +493,10 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
|
|||
|
||||
static int sof_audio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
|
||||
struct snd_soc_dai_link *dai_links;
|
||||
struct snd_soc_acpi_mach *mach;
|
||||
struct sof_card_private *ctx;
|
||||
int dmic_be_num, hdmi_num;
|
||||
int dmic_be_num;
|
||||
int ret, ssp_bt, ssp_amp, ssp_codec;
|
||||
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
||||
|
@ -624,23 +506,24 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
if (pdev->id_entry && pdev->id_entry->driver_data)
|
||||
sof_cs42l42_quirk = (unsigned long)pdev->id_entry->driver_data;
|
||||
|
||||
mach = pdev->dev.platform_data;
|
||||
|
||||
ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev);
|
||||
ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev);
|
||||
|
||||
if (soc_intel_is_glk()) {
|
||||
dmic_be_num = 1;
|
||||
hdmi_num = 3;
|
||||
ctx->hdmi_num = 3;
|
||||
} else {
|
||||
dmic_be_num = 2;
|
||||
hdmi_num = (sof_cs42l42_quirk & SOF_CS42L42_NUM_HDMIDEV_MASK) >>
|
||||
ctx->hdmi_num = (sof_cs42l42_quirk & SOF_CS42L42_NUM_HDMIDEV_MASK) >>
|
||||
SOF_CS42L42_NUM_HDMIDEV_SHIFT;
|
||||
/* default number of HDMI DAI's */
|
||||
if (!hdmi_num)
|
||||
hdmi_num = 3;
|
||||
if (!ctx->hdmi_num)
|
||||
ctx->hdmi_num = 3;
|
||||
}
|
||||
|
||||
if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
|
||||
ctx->hdmi.idisp_codec = true;
|
||||
|
||||
dev_dbg(&pdev->dev, "sof_cs42l42_quirk = %lx\n", sof_cs42l42_quirk);
|
||||
|
||||
ssp_bt = (sof_cs42l42_quirk & SOF_CS42L42_SSP_BT_MASK) >>
|
||||
|
@ -652,7 +535,7 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
ssp_codec = sof_cs42l42_quirk & SOF_CS42L42_SSP_CODEC_MASK;
|
||||
|
||||
/* compute number of dai links */
|
||||
sof_audio_card_cs42l42.num_links = 1 + dmic_be_num + hdmi_num;
|
||||
sof_audio_card_cs42l42.num_links = 1 + dmic_be_num + ctx->hdmi_num;
|
||||
|
||||
if (ctx->amp_type != CODEC_NONE)
|
||||
sof_audio_card_cs42l42.num_links++;
|
||||
|
@ -661,14 +544,13 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
|
||||
dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type,
|
||||
ssp_codec, ssp_amp, ssp_bt,
|
||||
dmic_be_num, hdmi_num);
|
||||
dmic_be_num, ctx->hdmi_num,
|
||||
ctx->hdmi.idisp_codec);
|
||||
if (!dai_links)
|
||||
return -ENOMEM;
|
||||
|
||||
sof_audio_card_cs42l42.dai_link = dai_links;
|
||||
|
||||
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
|
||||
|
||||
sof_audio_card_cs42l42.dev = &pdev->dev;
|
||||
|
||||
/* set platform name for each dailink */
|
||||
|
@ -677,8 +559,6 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
|
||||
|
||||
snd_soc_card_set_drvdata(&sof_audio_card_cs42l42, ctx);
|
||||
|
||||
return devm_snd_soc_register_card(&pdev->dev,
|
||||
|
@ -725,6 +605,6 @@ module_platform_driver(sof_audio)
|
|||
MODULE_DESCRIPTION("SOF Audio Machine driver for CS42L42");
|
||||
MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <sound/sof.h>
|
||||
#include "../../codecs/da7219.h"
|
||||
#include "hda_dsp_common.h"
|
||||
#include "sof_hdmi_common.h"
|
||||
#include "sof_maxim_common.h"
|
||||
#include "sof_ssp_common.h"
|
||||
|
||||
|
@ -24,16 +25,9 @@
|
|||
|
||||
#define DIALOG_CODEC_DAI "da7219-hifi"
|
||||
|
||||
struct hdmi_pcm {
|
||||
struct list_head head;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
int device;
|
||||
};
|
||||
|
||||
struct card_private {
|
||||
struct snd_soc_jack headset_jack;
|
||||
struct list_head hdmi_pcm_list;
|
||||
struct snd_soc_jack hdmi[3];
|
||||
struct sof_hdmi_private hdmi;
|
||||
enum sof_ssp_codec codec_type;
|
||||
enum sof_ssp_codec amp_type;
|
||||
|
||||
|
@ -232,16 +226,8 @@ static int hdmi_init(struct snd_soc_pcm_runtime *rtd)
|
|||
{
|
||||
struct card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
|
||||
struct hdmi_pcm *pcm;
|
||||
|
||||
pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
|
||||
if (!pcm)
|
||||
return -ENOMEM;
|
||||
|
||||
pcm->device = dai->id;
|
||||
pcm->codec_dai = dai;
|
||||
|
||||
list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
|
||||
ctx->hdmi.hdmi_comp = dai->component;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -249,17 +235,14 @@ static int hdmi_init(struct snd_soc_pcm_runtime *rtd)
|
|||
static int card_late_probe(struct snd_soc_card *card)
|
||||
{
|
||||
struct card_private *ctx = snd_soc_card_get_drvdata(card);
|
||||
struct snd_soc_acpi_mach *mach = (card->dev)->platform_data;
|
||||
struct hdmi_pcm *pcm;
|
||||
|
||||
if (mach->mach_params.common_hdmi_codec_drv) {
|
||||
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm,
|
||||
head);
|
||||
return hda_dsp_hdmi_build_controls(card,
|
||||
pcm->codec_dai->component);
|
||||
}
|
||||
if (!ctx->hdmi.idisp_codec)
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
if (!ctx->hdmi.hdmi_comp)
|
||||
return -EINVAL;
|
||||
|
||||
return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp);
|
||||
}
|
||||
|
||||
SND_SOC_DAILINK_DEF(ssp0_pin,
|
||||
|
@ -479,6 +462,9 @@ static int audio_probe(struct platform_device *pdev)
|
|||
ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev);
|
||||
ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev);
|
||||
|
||||
if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
|
||||
ctx->hdmi.idisp_codec = true;
|
||||
|
||||
if (board_quirk & SOF_DA7219_JSL_BOARD) {
|
||||
/* backward-compatible with existing devices */
|
||||
switch (ctx->amp_type) {
|
||||
|
@ -534,8 +520,6 @@ static int audio_probe(struct platform_device *pdev)
|
|||
|
||||
card_da7219.dai_link = dai_links;
|
||||
|
||||
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
|
||||
|
||||
card_da7219.dev = &pdev->dev;
|
||||
|
||||
ret = snd_soc_fixup_dai_links_platform_name(&card_da7219,
|
||||
|
|
24
sound/soc/intel/boards/sof_hdmi_common.h
Normal file
24
sound/soc/intel/boards/sof_hdmi_common.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright(c) 2023 Intel Corporation.
|
||||
*/
|
||||
|
||||
#ifndef __SOF_HDMI_COMMON_H
|
||||
#define __SOF_HDMI_COMMON_H
|
||||
|
||||
#include <sound/soc.h>
|
||||
|
||||
#define IDISP_CODEC_MASK 0x4
|
||||
|
||||
/*
|
||||
* sof_hdmi_private: data for Intel HDMI dai link (idisp) initialization
|
||||
*
|
||||
* @hdmi_comp: ASoC component of idisp codec
|
||||
* @idisp_codec: true to indicate idisp codec is present
|
||||
*/
|
||||
struct sof_hdmi_private {
|
||||
struct snd_soc_component *hdmi_comp;
|
||||
bool idisp_codec;
|
||||
};
|
||||
|
||||
#endif /* __SOF_HDMI_COMMON_H */
|
|
@ -20,14 +20,12 @@
|
|||
#include <sound/soc-acpi.h>
|
||||
#include "../../codecs/nau8825.h"
|
||||
#include "../common/soc-intel-quirks.h"
|
||||
#include "hda_dsp_common.h"
|
||||
#include "sof_board_helpers.h"
|
||||
#include "sof_realtek_common.h"
|
||||
#include "sof_maxim_common.h"
|
||||
#include "sof_nuvoton_common.h"
|
||||
#include "sof_ssp_common.h"
|
||||
|
||||
#define NAME_SIZE 32
|
||||
|
||||
#define SOF_NAU8825_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0))
|
||||
#define SOF_NAU8825_SSP_CODEC_MASK (GENMASK(2, 0))
|
||||
#define SOF_NAU8825_SSP_AMP_SHIFT 4
|
||||
|
@ -48,39 +46,6 @@
|
|||
|
||||
static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0);
|
||||
|
||||
struct sof_hdmi_pcm {
|
||||
struct list_head head;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
int device;
|
||||
};
|
||||
|
||||
struct sof_card_private {
|
||||
struct clk *mclk;
|
||||
struct snd_soc_jack sof_headset;
|
||||
struct list_head hdmi_pcm_list;
|
||||
enum sof_ssp_codec codec_type;
|
||||
enum sof_ssp_codec amp_type;
|
||||
};
|
||||
|
||||
static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
|
||||
struct sof_hdmi_pcm *pcm;
|
||||
|
||||
pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
|
||||
if (!pcm)
|
||||
return -ENOMEM;
|
||||
|
||||
/* dai_link id is 1:1 mapped to the PCM device */
|
||||
pcm->device = rtd->dai_link->id;
|
||||
pcm->codec_dai = dai;
|
||||
|
||||
list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_jack_pin jack_pins[] = {
|
||||
{
|
||||
.pin = "Headphone Jack",
|
||||
|
@ -96,8 +61,7 @@ static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
|
||||
|
||||
struct snd_soc_jack *jack;
|
||||
struct snd_soc_jack *jack = &ctx->headset_jack;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
|
@ -108,7 +72,7 @@ static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||
SND_JACK_HEADSET | SND_JACK_BTN_0 |
|
||||
SND_JACK_BTN_1 | SND_JACK_BTN_2 |
|
||||
SND_JACK_BTN_3,
|
||||
&ctx->sof_headset,
|
||||
jack,
|
||||
jack_pins,
|
||||
ARRAY_SIZE(jack_pins));
|
||||
if (ret) {
|
||||
|
@ -116,14 +80,12 @@ static int sof_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
jack = &ctx->sof_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);
|
||||
|
||||
ret = snd_soc_component_set_jack(component, jack, NULL);
|
||||
if (ret) {
|
||||
dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
|
||||
return ret;
|
||||
|
@ -187,7 +149,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
|
|||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
|
||||
struct snd_soc_dapm_context *dapm = &card->dapm;
|
||||
struct sof_hdmi_pcm *pcm;
|
||||
int err;
|
||||
|
||||
if (ctx->amp_type == CODEC_MAX98373) {
|
||||
|
@ -199,12 +160,7 @@ static int sof_card_late_probe(struct snd_soc_card *card)
|
|||
return err;
|
||||
}
|
||||
|
||||
if (list_empty(&ctx->hdmi_pcm_list))
|
||||
return -EINVAL;
|
||||
|
||||
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm, head);
|
||||
|
||||
return hda_dsp_hdmi_build_controls(card, pcm->codec_dai->component);
|
||||
return sof_intel_board_card_late_probe(card);
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new sof_controls[] = {
|
||||
|
@ -292,12 +248,13 @@ static struct snd_soc_dai_link_component dmic_component[] = {
|
|||
static struct snd_soc_dai_link *
|
||||
sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
|
||||
int ssp_codec, int ssp_amp, int dmic_be_num,
|
||||
int hdmi_num)
|
||||
int hdmi_num, bool idisp_codec)
|
||||
{
|
||||
struct snd_soc_dai_link_component *idisp_components;
|
||||
struct snd_soc_dai_link_component *cpus;
|
||||
struct snd_soc_dai_link *links;
|
||||
int i, id = 0;
|
||||
int i;
|
||||
int id = 0;
|
||||
int ret;
|
||||
|
||||
links = devm_kcalloc(dev, sof_audio_card_nau8825.num_links,
|
||||
sizeof(struct snd_soc_dai_link), GFP_KERNEL);
|
||||
|
@ -364,43 +321,12 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
|
|||
}
|
||||
|
||||
/* HDMI */
|
||||
if (hdmi_num > 0) {
|
||||
idisp_components = devm_kcalloc(dev,
|
||||
hdmi_num,
|
||||
sizeof(struct snd_soc_dai_link_component),
|
||||
GFP_KERNEL);
|
||||
if (!idisp_components)
|
||||
goto devm_err;
|
||||
}
|
||||
for (i = 1; i <= hdmi_num; i++) {
|
||||
links[id].name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"iDisp%d", i);
|
||||
if (!links[id].name)
|
||||
goto devm_err;
|
||||
ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], id,
|
||||
i, idisp_codec);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
links[id].id = id;
|
||||
links[id].cpus = &cpus[id];
|
||||
links[id].num_cpus = 1;
|
||||
links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"iDisp%d Pin", i);
|
||||
if (!links[id].cpus->dai_name)
|
||||
goto devm_err;
|
||||
|
||||
idisp_components[i - 1].name = "ehdaudio0D2";
|
||||
idisp_components[i - 1].dai_name = devm_kasprintf(dev,
|
||||
GFP_KERNEL,
|
||||
"intel-hdmi-hifi%d",
|
||||
i);
|
||||
if (!idisp_components[i - 1].dai_name)
|
||||
goto devm_err;
|
||||
|
||||
links[id].codecs = &idisp_components[i - 1];
|
||||
links[id].num_codecs = 1;
|
||||
links[id].platforms = platform_component;
|
||||
links[id].num_platforms = ARRAY_SIZE(platform_component);
|
||||
links[id].init = sof_hdmi_init;
|
||||
links[id].dpcm_playback = 1;
|
||||
links[id].no_pcm = 1;
|
||||
id++;
|
||||
}
|
||||
|
||||
|
@ -485,10 +411,10 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
|
|||
|
||||
static int sof_audio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
|
||||
struct snd_soc_dai_link *dai_links;
|
||||
struct snd_soc_acpi_mach *mach;
|
||||
struct sof_card_private *ctx;
|
||||
int dmic_be_num, hdmi_num;
|
||||
int dmic_be_num;
|
||||
int ret, ssp_amp, ssp_codec;
|
||||
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
||||
|
@ -498,8 +424,6 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
if (pdev->id_entry && pdev->id_entry->driver_data)
|
||||
sof_nau8825_quirk = (unsigned long)pdev->id_entry->driver_data;
|
||||
|
||||
mach = pdev->dev.platform_data;
|
||||
|
||||
ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev);
|
||||
ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev);
|
||||
|
||||
|
@ -507,11 +431,14 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
|
||||
/* default number of DMIC DAI's */
|
||||
dmic_be_num = 2;
|
||||
hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >>
|
||||
ctx->hdmi_num = (sof_nau8825_quirk & SOF_NAU8825_NUM_HDMIDEV_MASK) >>
|
||||
SOF_NAU8825_NUM_HDMIDEV_SHIFT;
|
||||
/* default number of HDMI DAI's */
|
||||
if (!hdmi_num)
|
||||
hdmi_num = 3;
|
||||
if (!ctx->hdmi_num)
|
||||
ctx->hdmi_num = 3;
|
||||
|
||||
if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
|
||||
ctx->hdmi.idisp_codec = true;
|
||||
|
||||
ssp_amp = (sof_nau8825_quirk & SOF_NAU8825_SSP_AMP_MASK) >>
|
||||
SOF_NAU8825_SSP_AMP_SHIFT;
|
||||
|
@ -519,7 +446,7 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
ssp_codec = sof_nau8825_quirk & SOF_NAU8825_SSP_CODEC_MASK;
|
||||
|
||||
/* compute number of dai links */
|
||||
sof_audio_card_nau8825.num_links = 1 + dmic_be_num + hdmi_num;
|
||||
sof_audio_card_nau8825.num_links = 1 + dmic_be_num + ctx->hdmi_num;
|
||||
|
||||
if (ctx->amp_type != CODEC_NONE)
|
||||
sof_audio_card_nau8825.num_links++;
|
||||
|
@ -529,7 +456,8 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
|
||||
dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type,
|
||||
ssp_codec, ssp_amp, dmic_be_num,
|
||||
hdmi_num);
|
||||
ctx->hdmi_num,
|
||||
ctx->hdmi.idisp_codec);
|
||||
if (!dai_links)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -554,8 +482,6 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
|
||||
|
||||
sof_audio_card_nau8825.dev = &pdev->dev;
|
||||
|
||||
/* set platform name for each dailink */
|
||||
|
@ -655,7 +581,7 @@ MODULE_AUTHOR("David Lin <ctlin0@nuvoton.com>");
|
|||
MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
|
||||
MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_NUVOTON_COMMON);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);
|
||||
|
|
|
@ -23,15 +23,12 @@
|
|||
#include "../../codecs/rt5682.h"
|
||||
#include "../../codecs/rt5682s.h"
|
||||
#include "../../codecs/rt5645.h"
|
||||
#include "../../codecs/hdac_hdmi.h"
|
||||
#include "../common/soc-intel-quirks.h"
|
||||
#include "hda_dsp_common.h"
|
||||
#include "sof_board_helpers.h"
|
||||
#include "sof_maxim_common.h"
|
||||
#include "sof_realtek_common.h"
|
||||
#include "sof_ssp_common.h"
|
||||
|
||||
#define NAME_SIZE 32
|
||||
|
||||
#define SOF_RT5682_SSP_CODEC(quirk) ((quirk) & GENMASK(2, 0))
|
||||
#define SOF_RT5682_SSP_CODEC_MASK (GENMASK(2, 0))
|
||||
#define SOF_RT5682_MCLK_EN BIT(3)
|
||||
|
@ -62,25 +59,6 @@
|
|||
static unsigned long sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
|
||||
SOF_RT5682_SSP_CODEC(0);
|
||||
|
||||
static int is_legacy_cpu;
|
||||
|
||||
struct sof_hdmi_pcm {
|
||||
struct list_head head;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
struct snd_soc_jack hdmi_jack;
|
||||
int device;
|
||||
};
|
||||
|
||||
struct sof_card_private {
|
||||
struct clk *mclk;
|
||||
struct snd_soc_jack sof_headset;
|
||||
struct list_head hdmi_pcm_list;
|
||||
bool common_hdmi_codec_drv;
|
||||
bool idisp_codec;
|
||||
enum sof_ssp_codec codec_type;
|
||||
enum sof_ssp_codec amp_type;
|
||||
};
|
||||
|
||||
static int sof_rt5682_quirk_cb(const struct dmi_system_id *id)
|
||||
{
|
||||
sof_rt5682_quirk = (unsigned long)id->driver_data;
|
||||
|
@ -232,25 +210,6 @@ static const struct dmi_system_id sof_rt5682_quirk_table[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
|
||||
struct sof_hdmi_pcm *pcm;
|
||||
|
||||
pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
|
||||
if (!pcm)
|
||||
return -ENOMEM;
|
||||
|
||||
/* dai_link id is 1:1 mapped to the PCM device */
|
||||
pcm->device = rtd->dai_link->id;
|
||||
pcm->codec_dai = dai;
|
||||
|
||||
list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct snd_soc_jack_pin jack_pins[] = {
|
||||
{
|
||||
.pin = "Headphone Jack",
|
||||
|
@ -266,7 +225,7 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;
|
||||
struct snd_soc_jack *jack;
|
||||
struct snd_soc_jack *jack = &ctx->headset_jack;
|
||||
int extra_jack_data;
|
||||
int ret, mclk_freq;
|
||||
|
||||
|
@ -322,11 +281,11 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||
* to disable a clock that has not been enabled,
|
||||
* we need to enable the clock first.
|
||||
*/
|
||||
ret = clk_prepare_enable(ctx->mclk);
|
||||
ret = clk_prepare_enable(ctx->rt5682.mclk);
|
||||
if (!ret)
|
||||
clk_disable_unprepare(ctx->mclk);
|
||||
clk_disable_unprepare(ctx->rt5682.mclk);
|
||||
|
||||
ret = clk_set_rate(ctx->mclk, 19200000);
|
||||
ret = clk_set_rate(ctx->rt5682.mclk, 19200000);
|
||||
|
||||
if (ret)
|
||||
dev_err(rtd->dev, "unable to set MCLK rate\n");
|
||||
|
@ -341,7 +300,7 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||
SND_JACK_HEADSET | SND_JACK_BTN_0 |
|
||||
SND_JACK_BTN_1 | SND_JACK_BTN_2 |
|
||||
SND_JACK_BTN_3,
|
||||
&ctx->sof_headset,
|
||||
jack,
|
||||
jack_pins,
|
||||
ARRAY_SIZE(jack_pins));
|
||||
if (ret) {
|
||||
|
@ -349,8 +308,6 @@ static int sof_rt5682_codec_init(struct snd_soc_pcm_runtime *rtd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
jack = &ctx->sof_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);
|
||||
|
@ -387,7 +344,7 @@ static int sof_rt5682_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
|
||||
if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
|
||||
ret = clk_prepare_enable(ctx->mclk);
|
||||
ret = clk_prepare_enable(ctx->rt5682.mclk);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev,
|
||||
"could not configure MCLK state");
|
||||
|
@ -516,10 +473,7 @@ static struct snd_soc_dai_link_component platform_component[] = {
|
|||
static int sof_card_late_probe(struct snd_soc_card *card)
|
||||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
|
||||
struct snd_soc_component *component = NULL;
|
||||
struct snd_soc_dapm_context *dapm = &card->dapm;
|
||||
char jack_name[NAME_SIZE];
|
||||
struct sof_hdmi_pcm *pcm;
|
||||
int err;
|
||||
|
||||
if (ctx->amp_type == CODEC_MAX98373) {
|
||||
|
@ -531,37 +485,7 @@ static int sof_card_late_probe(struct snd_soc_card *card)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* HDMI is not supported by SOF on Baytrail/CherryTrail */
|
||||
if (is_legacy_cpu || !ctx->idisp_codec)
|
||||
return 0;
|
||||
|
||||
if (list_empty(&ctx->hdmi_pcm_list))
|
||||
return -EINVAL;
|
||||
|
||||
if (ctx->common_hdmi_codec_drv) {
|
||||
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
|
||||
head);
|
||||
component = pcm->codec_dai->component;
|
||||
return hda_dsp_hdmi_build_controls(card, component);
|
||||
}
|
||||
|
||||
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
|
||||
component = pcm->codec_dai->component;
|
||||
snprintf(jack_name, sizeof(jack_name),
|
||||
"HDMI/DP, pcm=%d Jack", pcm->device);
|
||||
err = snd_soc_card_jack_new(card, jack_name,
|
||||
SND_JACK_AVOUT, &pcm->hdmi_jack);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
|
||||
&pcm->hdmi_jack);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return hdac_hdmi_jack_port_init(component, &card->dapm);
|
||||
return sof_intel_board_card_late_probe(card);
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new sof_controls[] = {
|
||||
|
@ -684,18 +608,17 @@ static struct snd_soc_dai_link_component dmic_component[] = {
|
|||
}
|
||||
};
|
||||
|
||||
#define IDISP_CODEC_MASK 0x4
|
||||
|
||||
static struct snd_soc_dai_link *
|
||||
sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec codec_type,
|
||||
enum sof_ssp_codec amp_type, int ssp_codec,
|
||||
int ssp_amp, int dmic_be_num, int hdmi_num,
|
||||
bool idisp_codec)
|
||||
bool idisp_codec, bool is_legacy_cpu)
|
||||
{
|
||||
struct snd_soc_dai_link_component *idisp_components;
|
||||
struct snd_soc_dai_link_component *cpus;
|
||||
struct snd_soc_dai_link *links;
|
||||
int i, id = 0;
|
||||
int i;
|
||||
int id = 0;
|
||||
int ret;
|
||||
int hdmi_id_offset = 0;
|
||||
|
||||
links = devm_kcalloc(dev, sof_audio_card_rt5682.num_links,
|
||||
|
@ -796,47 +719,12 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec codec_type,
|
|||
}
|
||||
|
||||
/* HDMI */
|
||||
if (hdmi_num > 0) {
|
||||
idisp_components = devm_kcalloc(dev,
|
||||
hdmi_num,
|
||||
sizeof(struct snd_soc_dai_link_component),
|
||||
GFP_KERNEL);
|
||||
if (!idisp_components)
|
||||
goto devm_err;
|
||||
}
|
||||
for (i = 1; i <= hdmi_num; i++) {
|
||||
links[id].name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"iDisp%d", i);
|
||||
if (!links[id].name)
|
||||
goto devm_err;
|
||||
ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], id,
|
||||
i, idisp_codec);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
links[id].id = id;
|
||||
links[id].cpus = &cpus[id];
|
||||
links[id].num_cpus = 1;
|
||||
links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"iDisp%d Pin", i);
|
||||
if (!links[id].cpus->dai_name)
|
||||
goto devm_err;
|
||||
|
||||
if (idisp_codec) {
|
||||
idisp_components[i - 1].name = "ehdaudio0D2";
|
||||
idisp_components[i - 1].dai_name = devm_kasprintf(dev,
|
||||
GFP_KERNEL,
|
||||
"intel-hdmi-hifi%d",
|
||||
i);
|
||||
if (!idisp_components[i - 1].dai_name)
|
||||
goto devm_err;
|
||||
} else {
|
||||
idisp_components[i - 1] = snd_soc_dummy_dlc;
|
||||
}
|
||||
|
||||
links[id].codecs = &idisp_components[i - 1];
|
||||
links[id].num_codecs = 1;
|
||||
links[id].platforms = platform_component;
|
||||
links[id].num_platforms = ARRAY_SIZE(platform_component);
|
||||
links[id].init = sof_hdmi_init;
|
||||
links[id].dpcm_playback = 1;
|
||||
links[id].no_pcm = 1;
|
||||
id++;
|
||||
}
|
||||
|
||||
|
@ -974,10 +862,10 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec codec_type,
|
|||
|
||||
static int sof_audio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
|
||||
struct snd_soc_dai_link *dai_links;
|
||||
struct snd_soc_acpi_mach *mach;
|
||||
struct sof_card_private *ctx;
|
||||
int dmic_be_num, hdmi_num;
|
||||
int dmic_be_num;
|
||||
int ret, ssp_amp, ssp_codec;
|
||||
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
||||
|
@ -989,8 +877,6 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
|
||||
dmi_check_system(sof_rt5682_quirk_table);
|
||||
|
||||
mach = pdev->dev.platform_data;
|
||||
|
||||
ctx->codec_type = sof_ssp_detect_codec_type(&pdev->dev);
|
||||
ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev);
|
||||
|
||||
|
@ -1004,30 +890,31 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
}
|
||||
|
||||
if (soc_intel_is_byt() || soc_intel_is_cht()) {
|
||||
is_legacy_cpu = 1;
|
||||
ctx->rt5682.is_legacy_cpu = true;
|
||||
dmic_be_num = 0;
|
||||
hdmi_num = 0;
|
||||
/* HDMI is not supported by SOF on Baytrail/CherryTrail */
|
||||
ctx->hdmi_num = 0;
|
||||
/* default quirk for legacy cpu */
|
||||
sof_rt5682_quirk = SOF_RT5682_MCLK_EN |
|
||||
SOF_RT5682_MCLK_BYTCHT_EN |
|
||||
SOF_RT5682_SSP_CODEC(2);
|
||||
} else {
|
||||
dmic_be_num = 2;
|
||||
hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
|
||||
ctx->hdmi_num = (sof_rt5682_quirk & SOF_RT5682_NUM_HDMIDEV_MASK) >>
|
||||
SOF_RT5682_NUM_HDMIDEV_SHIFT;
|
||||
/* default number of HDMI DAI's */
|
||||
if (!hdmi_num)
|
||||
hdmi_num = 3;
|
||||
if (!ctx->hdmi_num)
|
||||
ctx->hdmi_num = 3;
|
||||
|
||||
if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
|
||||
ctx->idisp_codec = true;
|
||||
ctx->hdmi.idisp_codec = true;
|
||||
}
|
||||
|
||||
/* need to get main clock from pmc */
|
||||
if (sof_rt5682_quirk & SOF_RT5682_MCLK_BYTCHT_EN) {
|
||||
ctx->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
|
||||
if (IS_ERR(ctx->mclk)) {
|
||||
ret = PTR_ERR(ctx->mclk);
|
||||
ctx->rt5682.mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
|
||||
if (IS_ERR(ctx->rt5682.mclk)) {
|
||||
ret = PTR_ERR(ctx->rt5682.mclk);
|
||||
|
||||
dev_err(&pdev->dev,
|
||||
"Failed to get MCLK from pmc_plt_clk_3: %d\n",
|
||||
|
@ -1035,7 +922,7 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(ctx->mclk);
|
||||
ret = clk_prepare_enable(ctx->rt5682.mclk);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"could not configure MCLK state");
|
||||
|
@ -1051,7 +938,7 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
ssp_codec = sof_rt5682_quirk & SOF_RT5682_SSP_CODEC_MASK;
|
||||
|
||||
/* compute number of dai links */
|
||||
sof_audio_card_rt5682.num_links = 1 + dmic_be_num + hdmi_num;
|
||||
sof_audio_card_rt5682.num_links = 1 + dmic_be_num + ctx->hdmi_num;
|
||||
|
||||
if (ctx->amp_type != CODEC_NONE)
|
||||
sof_audio_card_rt5682.num_links++;
|
||||
|
@ -1066,8 +953,9 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
|
||||
dai_links = sof_card_dai_links_create(&pdev->dev, ctx->codec_type,
|
||||
ctx->amp_type, ssp_codec, ssp_amp,
|
||||
dmic_be_num, hdmi_num,
|
||||
ctx->idisp_codec);
|
||||
dmic_be_num, ctx->hdmi_num,
|
||||
ctx->hdmi.idisp_codec,
|
||||
ctx->rt5682.is_legacy_cpu);
|
||||
if (!dai_links)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -1102,8 +990,6 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
|
||||
|
||||
sof_audio_card_rt5682.dev = &pdev->dev;
|
||||
|
||||
/* set platform name for each dailink */
|
||||
|
@ -1112,8 +998,6 @@ static int sof_audio_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
|
||||
|
||||
snd_soc_card_set_drvdata(&sof_audio_card_rt5682, ctx);
|
||||
|
||||
return devm_snd_soc_register_card(&pdev->dev,
|
||||
|
@ -1331,7 +1215,7 @@ MODULE_AUTHOR("Sathya Prakash M R <sathya.prakash.m.r@intel.com>");
|
|||
MODULE_AUTHOR("Brent Lu <brent.lu@intel.com>");
|
||||
MODULE_AUTHOR("Mac Chiang <mac.chiang@intel.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_HDA_DSP_COMMON);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_MAXIM_COMMON);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON);
|
||||
|
|
|
@ -402,7 +402,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
|
|||
.callback = sof_sdw_quirk_cb,
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16-k0xxx"),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "OMEN by HP Gaming Laptop 16"),
|
||||
},
|
||||
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
|
||||
RT711_JD2),
|
||||
|
@ -1542,8 +1542,6 @@ static int create_sdw_dailink(struct snd_soc_card *card, int *link_index,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define IDISP_CODEC_MASK 0x4
|
||||
|
||||
static int sof_card_dai_links_create(struct snd_soc_card *card)
|
||||
{
|
||||
struct device *dev = card->dev;
|
||||
|
@ -1587,7 +1585,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
|
|||
}
|
||||
|
||||
if (mach_params->codec_mask & IDISP_CODEC_MASK) {
|
||||
ctx->idisp_codec = true;
|
||||
ctx->hdmi.idisp_codec = true;
|
||||
|
||||
if (sof_sdw_quirk & SOF_SDW_TGL_HDMI)
|
||||
hdmi_num = SOF_TGL_HDMI_COUNT;
|
||||
|
@ -1757,7 +1755,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
|
|||
name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d", i + 1);
|
||||
cpu_dai_name = devm_kasprintf(dev, GFP_KERNEL, "iDisp%d Pin", i + 1);
|
||||
|
||||
if (ctx->idisp_codec) {
|
||||
if (ctx->hdmi.idisp_codec) {
|
||||
codec_name = "ehdaudio0D2";
|
||||
codec_dai_name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"intel-hdmi-hifi%d", i + 1);
|
||||
|
@ -1769,7 +1767,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
|
|||
ret = init_simple_dai_link(dev, dai_links + link_index, &be_id, name,
|
||||
1, 0, // HDMI only supports playback
|
||||
cpu_dai_name, codec_name, codec_dai_name,
|
||||
sof_sdw_hdmi_init, NULL);
|
||||
i == 0 ? sof_sdw_hdmi_init : NULL, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1814,7 +1812,7 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card)
|
|||
}
|
||||
}
|
||||
|
||||
if (ctx->idisp_codec)
|
||||
if (ctx->hdmi.idisp_codec)
|
||||
ret = sof_sdw_hdmi_card_late_probe(card);
|
||||
|
||||
return ret;
|
||||
|
@ -1893,8 +1891,6 @@ static int mc_probe(struct platform_device *pdev)
|
|||
if (!ctx)
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
|
||||
|
||||
snd_soc_card_set_drvdata(card, ctx);
|
||||
|
||||
dmi_check_system(sof_sdw_quirk_table);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <linux/bits.h>
|
||||
#include <linux/types.h>
|
||||
#include <sound/soc.h>
|
||||
#include "sof_hdmi_common.h"
|
||||
|
||||
#define MAX_NO_PROPS 2
|
||||
#define MAX_HDMI_NUM 4
|
||||
|
@ -94,9 +95,8 @@ struct sof_sdw_codec_info {
|
|||
};
|
||||
|
||||
struct mc_private {
|
||||
struct list_head hdmi_pcm_list;
|
||||
bool idisp_codec;
|
||||
struct snd_soc_jack sdw_headset;
|
||||
struct sof_hdmi_private hdmi;
|
||||
struct device *headset_codec_dev; /* only one headset per card */
|
||||
struct device *amp_dev1, *amp_dev2;
|
||||
/* To store SDW Pin index for each SoundWire link */
|
||||
|
|
|
@ -15,47 +15,25 @@
|
|||
#include "sof_sdw_common.h"
|
||||
#include "hda_dsp_common.h"
|
||||
|
||||
struct hdmi_pcm {
|
||||
struct list_head head;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
int device;
|
||||
};
|
||||
|
||||
int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct mc_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
|
||||
struct hdmi_pcm *pcm;
|
||||
|
||||
pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
|
||||
if (!pcm)
|
||||
return -ENOMEM;
|
||||
|
||||
/* dai_link id is 1:1 mapped to the PCM device */
|
||||
pcm->device = rtd->dai_link->id;
|
||||
pcm->codec_dai = dai;
|
||||
|
||||
list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
|
||||
ctx->hdmi.hdmi_comp = dai->component;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define NAME_SIZE 32
|
||||
int sof_sdw_hdmi_card_late_probe(struct snd_soc_card *card)
|
||||
{
|
||||
struct mc_private *ctx = snd_soc_card_get_drvdata(card);
|
||||
struct hdmi_pcm *pcm;
|
||||
struct snd_soc_component *component = NULL;
|
||||
|
||||
if (!ctx->idisp_codec)
|
||||
if (!ctx->hdmi.idisp_codec)
|
||||
return 0;
|
||||
|
||||
if (list_empty(&ctx->hdmi_pcm_list))
|
||||
if (!ctx->hdmi.hdmi_comp)
|
||||
return -EINVAL;
|
||||
|
||||
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm,
|
||||
head);
|
||||
component = pcm->codec_dai->component;
|
||||
|
||||
return hda_dsp_hdmi_build_controls(card, component);
|
||||
return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp);
|
||||
}
|
||||
|
|
|
@ -80,10 +80,12 @@ int sof_sdw_rt712_spk_init(struct snd_soc_card *card,
|
|||
static int rt712_sdca_dmic_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
|
||||
struct snd_soc_component *component = codec_dai->component;
|
||||
|
||||
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
|
||||
"%s mic:rt712-sdca-dmic",
|
||||
card->components);
|
||||
"%s mic:%s",
|
||||
card->components, component->name_prefix);
|
||||
if (!card->components)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -58,6 +58,11 @@ static const struct snd_soc_dapm_route rt712_sdca_map[] = {
|
|||
{ "rt712 MIC2", NULL, "Headset Mic" },
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route rt713_sdca_map[] = {
|
||||
{ "Headphone", NULL, "rt713 HP" },
|
||||
{ "rt713 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"),
|
||||
|
@ -109,6 +114,9 @@ static int rt_sdca_jack_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
|||
} else if (strstr(component->name_prefix, "rt712")) {
|
||||
ret = snd_soc_dapm_add_routes(&card->dapm, rt712_sdca_map,
|
||||
ARRAY_SIZE(rt712_sdca_map));
|
||||
} else if (strstr(component->name_prefix, "rt713")) {
|
||||
ret = snd_soc_dapm_add_routes(&card->dapm, rt713_sdca_map,
|
||||
ARRAY_SIZE(rt713_sdca_map));
|
||||
} else {
|
||||
dev_err(card->dev, "%s is not supported\n", component->name_prefix);
|
||||
return -EINVAL;
|
||||
|
|
|
@ -17,14 +17,11 @@
|
|||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/sof.h>
|
||||
#include "../../codecs/hdac_hdmi.h"
|
||||
#include "hda_dsp_common.h"
|
||||
#include "sof_board_helpers.h"
|
||||
#include "sof_realtek_common.h"
|
||||
#include "sof_cirrus_common.h"
|
||||
#include "sof_ssp_common.h"
|
||||
|
||||
#define NAME_SIZE 32
|
||||
|
||||
/* SSP port ID for speaker amplifier */
|
||||
#define SOF_AMPLIFIER_SSP(quirk) ((quirk) & GENMASK(3, 0))
|
||||
#define SOF_AMPLIFIER_SSP_MASK (GENMASK(3, 0))
|
||||
|
@ -63,20 +60,6 @@
|
|||
/* Default: SSP2 */
|
||||
static unsigned long sof_ssp_amp_quirk = SOF_AMPLIFIER_SSP(2);
|
||||
|
||||
struct sof_hdmi_pcm {
|
||||
struct list_head head;
|
||||
struct snd_soc_jack sof_hdmi;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
int device;
|
||||
};
|
||||
|
||||
struct sof_card_private {
|
||||
struct list_head hdmi_pcm_list;
|
||||
bool common_hdmi_codec_drv;
|
||||
bool idisp_codec;
|
||||
enum sof_ssp_codec amp_type;
|
||||
};
|
||||
|
||||
static const struct dmi_system_id chromebook_platforms[] = {
|
||||
{
|
||||
.ident = "Google Chromebooks",
|
||||
|
@ -98,46 +81,7 @@ static const struct snd_soc_dapm_route sof_ssp_amp_dapm_routes[] = {
|
|||
|
||||
static int sof_card_late_probe(struct snd_soc_card *card)
|
||||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
|
||||
struct snd_soc_component *component = NULL;
|
||||
char jack_name[NAME_SIZE];
|
||||
struct sof_hdmi_pcm *pcm;
|
||||
int err;
|
||||
|
||||
if (!(sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT))
|
||||
return 0;
|
||||
|
||||
/* HDMI is not supported by SOF on Baytrail/CherryTrail */
|
||||
if (!ctx->idisp_codec)
|
||||
return 0;
|
||||
|
||||
if (list_empty(&ctx->hdmi_pcm_list))
|
||||
return -EINVAL;
|
||||
|
||||
if (ctx->common_hdmi_codec_drv) {
|
||||
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
|
||||
head);
|
||||
component = pcm->codec_dai->component;
|
||||
return hda_dsp_hdmi_build_controls(card, component);
|
||||
}
|
||||
|
||||
list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
|
||||
component = pcm->codec_dai->component;
|
||||
snprintf(jack_name, sizeof(jack_name),
|
||||
"HDMI/DP, pcm=%d Jack", pcm->device);
|
||||
err = snd_soc_card_jack_new(card, jack_name,
|
||||
SND_JACK_AVOUT, &pcm->sof_hdmi);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
|
||||
&pcm->sof_hdmi);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return hdac_hdmi_jack_port_init(component, &card->dapm);
|
||||
return sof_intel_board_card_late_probe(card);
|
||||
}
|
||||
|
||||
static struct snd_soc_card sof_ssp_amp_card = {
|
||||
|
@ -165,27 +109,6 @@ static struct snd_soc_dai_link_component dmic_component[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static int sof_hdmi_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct sof_card_private *ctx = snd_soc_card_get_drvdata(rtd->card);
|
||||
struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
|
||||
struct sof_hdmi_pcm *pcm;
|
||||
|
||||
pcm = devm_kzalloc(rtd->card->dev, sizeof(*pcm), GFP_KERNEL);
|
||||
if (!pcm)
|
||||
return -ENOMEM;
|
||||
|
||||
/* dai_link id is 1:1 mapped to the PCM device */
|
||||
pcm->device = rtd->dai_link->id;
|
||||
pcm->codec_dai = dai;
|
||||
|
||||
list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define IDISP_CODEC_MASK 0x4
|
||||
|
||||
/* BE ID defined in sof-tgl-rt1308-hdmi-ssp.m4 */
|
||||
#define HDMI_IN_BE_ID 0
|
||||
#define SPK_BE_ID 2
|
||||
|
@ -197,11 +120,13 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
|
|||
int ssp_codec, int dmic_be_num, int hdmi_num,
|
||||
bool idisp_codec)
|
||||
{
|
||||
struct snd_soc_dai_link_component *idisp_components;
|
||||
struct snd_soc_dai_link_component *cpus;
|
||||
struct snd_soc_dai_link *links;
|
||||
int i, id = 0;
|
||||
int i;
|
||||
int id = 0;
|
||||
int ret;
|
||||
bool fixed_be = false;
|
||||
int be_id;
|
||||
|
||||
links = devm_kcalloc(dev, sof_ssp_amp_card.num_links,
|
||||
sizeof(struct snd_soc_dai_link), GFP_KERNEL);
|
||||
|
@ -308,51 +233,14 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
|
|||
}
|
||||
|
||||
/* HDMI playback */
|
||||
if (sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT) {
|
||||
/* HDMI */
|
||||
if (hdmi_num > 0) {
|
||||
idisp_components = devm_kcalloc(dev,
|
||||
hdmi_num,
|
||||
sizeof(struct snd_soc_dai_link_component),
|
||||
GFP_KERNEL);
|
||||
if (!idisp_components)
|
||||
goto devm_err;
|
||||
}
|
||||
for (i = 1; i <= hdmi_num; i++) {
|
||||
links[id].name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"iDisp%d", i);
|
||||
if (!links[id].name)
|
||||
goto devm_err;
|
||||
for (i = 1; i <= hdmi_num; i++) {
|
||||
be_id = fixed_be ? (INTEL_HDMI_BE_ID + i - 1) : id;
|
||||
ret = sof_intel_board_set_intel_hdmi_link(dev, &links[id], be_id,
|
||||
i, idisp_codec);
|
||||
if (ret)
|
||||
return NULL;
|
||||
|
||||
links[id].id = fixed_be ? (INTEL_HDMI_BE_ID + i - 1) : id;
|
||||
links[id].cpus = &cpus[id];
|
||||
links[id].num_cpus = 1;
|
||||
links[id].cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"iDisp%d Pin", i);
|
||||
if (!links[id].cpus->dai_name)
|
||||
goto devm_err;
|
||||
|
||||
if (idisp_codec) {
|
||||
idisp_components[i - 1].name = "ehdaudio0D2";
|
||||
idisp_components[i - 1].dai_name = devm_kasprintf(dev,
|
||||
GFP_KERNEL,
|
||||
"intel-hdmi-hifi%d",
|
||||
i);
|
||||
if (!idisp_components[i - 1].dai_name)
|
||||
goto devm_err;
|
||||
} else {
|
||||
idisp_components[i - 1] = snd_soc_dummy_dlc;
|
||||
}
|
||||
|
||||
links[id].codecs = &idisp_components[i - 1];
|
||||
links[id].num_codecs = 1;
|
||||
links[id].platforms = platform_component;
|
||||
links[id].num_platforms = ARRAY_SIZE(platform_component);
|
||||
links[id].init = sof_hdmi_init;
|
||||
links[id].dpcm_playback = 1;
|
||||
links[id].no_pcm = 1;
|
||||
id++;
|
||||
}
|
||||
id++;
|
||||
}
|
||||
|
||||
/* BT audio offload */
|
||||
|
@ -387,10 +275,10 @@ sof_card_dai_links_create(struct device *dev, enum sof_ssp_codec amp_type,
|
|||
|
||||
static int sof_ssp_amp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
|
||||
struct snd_soc_dai_link *dai_links;
|
||||
struct snd_soc_acpi_mach *mach;
|
||||
struct sof_card_private *ctx;
|
||||
int dmic_be_num = 0, hdmi_num = 0;
|
||||
int dmic_be_num = 0;
|
||||
int ret, ssp_codec;
|
||||
|
||||
ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
|
||||
|
@ -400,8 +288,6 @@ static int sof_ssp_amp_probe(struct platform_device *pdev)
|
|||
if (pdev->id_entry && pdev->id_entry->driver_data)
|
||||
sof_ssp_amp_quirk = (unsigned long)pdev->id_entry->driver_data;
|
||||
|
||||
mach = pdev->dev.platform_data;
|
||||
|
||||
ctx->amp_type = sof_ssp_detect_amp_type(&pdev->dev);
|
||||
|
||||
if (dmi_check_system(chromebook_platforms) || mach->mach_params.dmic_num > 0)
|
||||
|
@ -420,24 +306,27 @@ static int sof_ssp_amp_probe(struct platform_device *pdev)
|
|||
SOF_NO_OF_HDMI_CAPTURE_SSP_SHIFT;
|
||||
|
||||
if (sof_ssp_amp_quirk & SOF_HDMI_PLAYBACK_PRESENT) {
|
||||
hdmi_num = (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_PLAYBACK_MASK) >>
|
||||
ctx->hdmi_num = (sof_ssp_amp_quirk & SOF_NO_OF_HDMI_PLAYBACK_MASK) >>
|
||||
SOF_NO_OF_HDMI_PLAYBACK_SHIFT;
|
||||
/* default number of HDMI DAI's */
|
||||
if (!hdmi_num)
|
||||
hdmi_num = 3;
|
||||
if (!ctx->hdmi_num)
|
||||
ctx->hdmi_num = 3;
|
||||
|
||||
if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
|
||||
ctx->idisp_codec = true;
|
||||
ctx->hdmi.idisp_codec = true;
|
||||
|
||||
sof_ssp_amp_card.num_links += hdmi_num;
|
||||
sof_ssp_amp_card.num_links += ctx->hdmi_num;
|
||||
} else {
|
||||
ctx->hdmi_num = 0;
|
||||
}
|
||||
|
||||
if (sof_ssp_amp_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
|
||||
sof_ssp_amp_card.num_links++;
|
||||
|
||||
dai_links = sof_card_dai_links_create(&pdev->dev, ctx->amp_type,
|
||||
ssp_codec, dmic_be_num, hdmi_num,
|
||||
ctx->idisp_codec);
|
||||
ssp_codec, dmic_be_num,
|
||||
ctx->hdmi_num,
|
||||
ctx->hdmi.idisp_codec);
|
||||
if (!dai_links)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -457,8 +346,6 @@ static int sof_ssp_amp_probe(struct platform_device *pdev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
|
||||
|
||||
sof_ssp_amp_card.dev = &pdev->dev;
|
||||
|
||||
/* set platform name for each dailink */
|
||||
|
@ -467,8 +354,6 @@ static int sof_ssp_amp_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
|
||||
|
||||
snd_soc_card_set_drvdata(&sof_ssp_amp_card, ctx);
|
||||
|
||||
return devm_snd_soc_register_card(&pdev->dev, &sof_ssp_amp_card);
|
||||
|
@ -512,6 +397,15 @@ static const struct platform_device_id board_ids[] = {
|
|||
SOF_NO_OF_HDMI_PLAYBACK(3) |
|
||||
SOF_HDMI_PLAYBACK_PRESENT),
|
||||
},
|
||||
{
|
||||
.name = "mtl_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);
|
||||
|
@ -530,7 +424,7 @@ MODULE_DESCRIPTION("ASoC Intel(R) SOF Amplifier Machine driver");
|
|||
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);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_BOARD_HELPERS);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_REALTEK_COMMON);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_CIRRUS_COMMON);
|
||||
MODULE_IMPORT_NS(SND_SOC_INTEL_SOF_SSP_COMMON);
|
||||
|
|
|
@ -77,6 +77,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_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 = "INTC10B0",
|
||||
.drv_name = "mtl_lt6911_hdmi_ssp",
|
||||
.sof_tplg_filename = "sof-mtl-hdmi-ssp02.tplg",
|
||||
},
|
||||
{},
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_mtl_machines);
|
||||
|
@ -158,6 +164,24 @@ static const struct snd_soc_acpi_adr_device rt1712_3_single_adr[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt713_0_single_adr[] = {
|
||||
{
|
||||
.adr = 0x000031025D071301ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &single_endpoint,
|
||||
.name_prefix = "rt713"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1713_3_single_adr[] = {
|
||||
{
|
||||
.adr = 0x000331025D171301ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &single_endpoint,
|
||||
.name_prefix = "rt713-dmic"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device mx8373_0_adr[] = {
|
||||
{
|
||||
.adr = 0x000023019F837300ull,
|
||||
|
@ -200,6 +224,24 @@ static const struct snd_soc_acpi_adr_device rt1316_3_group1_adr[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1316_1_group2_adr[] = {
|
||||
{
|
||||
.adr = 0x000131025D131601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_l_endpoint,
|
||||
.name_prefix = "rt1316-1"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1316_2_group2_adr[] = {
|
||||
{
|
||||
.adr = 0x000230025D131601ull,
|
||||
.num_endpoints = 1,
|
||||
.endpoints = &spk_r_endpoint,
|
||||
.name_prefix = "rt1316-2"
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device rt1318_1_group1_adr[] = {
|
||||
{
|
||||
.adr = 0x000130025D131801ull,
|
||||
|
@ -356,6 +398,30 @@ static const struct snd_soc_acpi_link_adr mtl_sdw_rt1318_l12_rt714_l0[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr mtl_rt713_l0_rt1316_l12_rt1713_l3[] = {
|
||||
{
|
||||
.mask = BIT(0),
|
||||
.num_adr = ARRAY_SIZE(rt713_0_single_adr),
|
||||
.adr_d = rt713_0_single_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(1),
|
||||
.num_adr = ARRAY_SIZE(rt1316_1_group2_adr),
|
||||
.adr_d = rt1316_1_group2_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(2),
|
||||
.num_adr = ARRAY_SIZE(rt1316_2_group2_adr),
|
||||
.adr_d = rt1316_2_group2_adr,
|
||||
},
|
||||
{
|
||||
.mask = BIT(3),
|
||||
.num_adr = ARRAY_SIZE(rt1713_3_single_adr),
|
||||
.adr_d = rt1713_3_single_adr,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_adr_device mx8363_2_adr[] = {
|
||||
{
|
||||
.adr = 0x000230019F836300ull,
|
||||
|
@ -435,6 +501,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_mtl_sdw_machines[] = {
|
|||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-mtl-rt715-rt711-rt1308-mono.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = GENMASK(3, 0),
|
||||
.links = mtl_rt713_l0_rt1316_l12_rt1713_l3,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-mtl-rt713-l0-rt1316-l12-rt1713-l3.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = BIT(3) | BIT(0),
|
||||
.links = mtl_712_only,
|
||||
|
|
|
@ -246,6 +246,25 @@ static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link2_rt1316_link01[] =
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link0_rt1316_link12[] = {
|
||||
{
|
||||
.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,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link0_rt1318_link12_rt714_link3[] = {
|
||||
{
|
||||
.mask = BIT(0),
|
||||
|
@ -459,6 +478,12 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = {
|
|||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-rpl-rt711-l0-rt1318-l12-rt714-l3.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = 0x7, /* rt711 on link0 & two rt1316s on link1 and link2 */
|
||||
.links = rpl_sdw_rt711_link0_rt1316_link12,
|
||||
.drv_name = "sof_sdw",
|
||||
.sof_tplg_filename = "sof-rpl-rt711-l0-rt1316-l12.tplg",
|
||||
},
|
||||
{
|
||||
.link_mask = 0x7, /* rt711 on link0 & two rt1318s on link1 and link2 */
|
||||
.links = rpl_sdw_rt711_link0_rt1318_link12,
|
||||
|
|
Loading…
Reference in a new issue