ASoC: Intel: boards: updates for 6.12

Merge series from Bard Liao <yung-chuan.liao@linux.intel.com>:

Some simplifications from Brent Lu for Chromebooks, a new SoundWire codec
support from Bard Liao, new cs42l43 match entries support from
Charles Keepax, Add quirks from some new Dell laptops from Maciej
Strozek, some ACPI match entries from Balamurugan C, and few bug
fixes from Pierre-Louis Bossart.

v2:
 - Add "ASoC: SOF: Intel: hda: support BT link mask in mach_params"
   commit to fix the build issue in v1.

Balamurugan C (2):
  ASoC: Intel: soc-acpi: Add entry for sof_es8336 in ARL match table.
  ASoC: Intel: soc-acpi: Add entry for HDMI_In capture support in ARL
    match table

Bard Liao (4):
  ASoC: Intel: sof_sdw: add rt1320 amp support
  ASoC: SOF: Intel: hda: refactoring topology name fixup for HDA mach
  ASoC: Intel: sof_sdw: move ignore_internal_dmic check earlier
  ASoC: Intel: sof_sdw: overwrite mach_params->dmic_num

Brent Lu (5):
  ASoC: SOF: Intel: hda: refactoring topology name fixup for SDW mach
  ASoC: SOF: Intel: hda: support BT link mask in mach_params
  ASoC: Intel: skl_hda_dsp_generic: support BT audio offload
  ASoC: Intel: skl_hda_dsp_generic: remove hdac-hdmi support
  ASoC: Intel: skl_hda_dsp_generic: use sof_hdmi_private to init HDMI

Charles Keepax (3):
  ASoC: Intel: soc-acpi: arl: Add match entries for new cs42l43 laptops
  ASoC: Intel: soc-acpi: adl: Add match entries for new cs42l43 laptops
  ASoC: Intel: soc-acpi: lnl: Add match entries for new cs42l43 laptops

Maciej Strozek (1):
  ASoC: Intel: sof_sdw: Add quirks from some new Dell laptops

Pierre-Louis Bossart (2):
  ASoC: Intel: sof_sdw: make sof_sdw_quirk static
  ASoC: Intel: boards: always check the result of
    acpi_dev_get_first_match_dev()

 include/sound/soc-acpi.h                      |   2 +
 sound/soc/intel/boards/Kconfig                |   2 +-
 sound/soc/intel/boards/bytcht_cx2072x.c       |   4 +
 sound/soc/intel/boards/bytcht_da7213.c        |   4 +
 sound/soc/intel/boards/bytcht_es8316.c        |   2 +-
 sound/soc/intel/boards/bytcr_rt5640.c         |   2 +-
 sound/soc/intel/boards/bytcr_rt5651.c         |   2 +-
 sound/soc/intel/boards/cht_bsw_rt5645.c       |   4 +
 sound/soc/intel/boards/cht_bsw_rt5672.c       |   4 +
 sound/soc/intel/boards/skl_hda_dsp_common.c   |  56 ++--
 sound/soc/intel/boards/skl_hda_dsp_common.h   |  39 +--
 sound/soc/intel/boards/skl_hda_dsp_generic.c  |  58 ++--
 sound/soc/intel/boards/sof_es8336.c           |  12 +-
 sound/soc/intel/boards/sof_sdw.c              |  85 +++++-
 sound/soc/intel/boards/sof_sdw_common.h       |   2 -
 sound/soc/intel/boards/sof_wm8804.c           |   4 +
 .../intel/common/soc-acpi-intel-adl-match.c   | 105 +++++++
 .../intel/common/soc-acpi-intel-arl-match.c   | 244 +++++++++++++++
 .../intel/common/soc-acpi-intel-hda-match.c   |  12 +-
 .../intel/common/soc-acpi-intel-lnl-match.c   | 104 +++++++
 sound/soc/sdw_utils/soc_sdw_rt_amp.c          |  11 +-
 sound/soc/sdw_utils/soc_sdw_utils.c           |  19 ++
 sound/soc/sof/intel/hda.c                     | 281 ++++++++----------
 23 files changed, 780 insertions(+), 278 deletions(-)

--
2.43.0
This commit is contained in:
Mark Brown 2024-08-28 17:33:56 +01:00
commit 4f451bc91e
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
23 changed files with 780 additions and 278 deletions

View File

@ -73,6 +73,7 @@ static inline struct snd_soc_acpi_mach *snd_soc_acpi_codec_list(void *arg)
* @subsystem_rev: optional PCI SSID revision value
* @subsystem_id_set: true if a value has been written to
* subsystem_vendor and subsystem_device.
* @bt_link_mask: BT offload link enabled on the board
*/
struct snd_soc_acpi_mach_params {
u32 acpi_ipc_irq_index;
@ -89,6 +90,7 @@ struct snd_soc_acpi_mach_params {
unsigned short subsystem_device;
unsigned short subsystem_rev;
bool subsystem_id_set;
u32 bt_link_mask;
};
/**

View File

@ -305,7 +305,6 @@ if SND_SOC_SOF_HDA_AUDIO_CODEC
config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH
tristate "Skylake+ with HDA Codecs"
depends on SND_HDA_CODEC_HDMI
select SND_SOC_HDAC_HDMI
select SND_SOC_INTEL_HDA_DSP_COMMON
select SND_SOC_DMIC
# SND_SOC_HDAC_HDA is already selected
@ -524,6 +523,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
select SND_SOC_RT1308
select SND_SOC_RT1316_SDW
select SND_SOC_RT1318_SDW
select SND_SOC_RT1320_SDW
select SND_SOC_RT5682_SDW
select SND_SOC_CS42L42_SDW
select SND_SOC_CS42L43

View File

@ -255,7 +255,11 @@ static int snd_byt_cht_cx2072x_probe(struct platform_device *pdev)
snprintf(codec_name, sizeof(codec_name), "i2c-%s",
acpi_dev_name(adev));
byt_cht_cx2072x_dais[dai_index].codecs->name = codec_name;
} else {
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
return -ENOENT;
}
acpi_dev_put(adev);
/* override platform name, if required */

View File

@ -258,7 +258,11 @@ static int bytcht_da7213_probe(struct platform_device *pdev)
snprintf(codec_name, sizeof(codec_name),
"i2c-%s", acpi_dev_name(adev));
dailink[dai_index].codecs->name = codec_name;
} else {
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
return -ENOENT;
}
acpi_dev_put(adev);
/* override platform name, if required */

View File

@ -562,7 +562,7 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev)
byt_cht_es8316_dais[dai_index].codecs->name = codec_name;
} else {
dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
return -ENXIO;
return -ENOENT;
}
codec_dev = acpi_get_first_physical_node(adev);

View File

@ -1693,7 +1693,7 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name;
} else {
dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
return -ENXIO;
return -ENOENT;
}
codec_dev = acpi_get_first_physical_node(adev);

View File

@ -926,7 +926,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name;
} else {
dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
return -ENXIO;
return -ENOENT;
}
codec_dev = acpi_get_first_physical_node(adev);

View File

@ -582,7 +582,11 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
snprintf(cht_rt5645_codec_name, sizeof(cht_rt5645_codec_name),
"i2c-%s", acpi_dev_name(adev));
cht_dailink[dai_index].codecs->name = cht_rt5645_codec_name;
} else {
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
return -ENOENT;
}
/* acpi_get_first_physical_node() returns a borrowed ref, no need to deref */
codec_dev = acpi_get_first_physical_node(adev);
acpi_dev_put(adev);

View File

@ -479,7 +479,11 @@ static int snd_cht_mc_probe(struct platform_device *pdev)
snprintf(drv->codec_name, sizeof(drv->codec_name),
"i2c-%s", acpi_dev_name(adev));
cht_dailink[dai_index].codecs->name = drv->codec_name;
} else {
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
return -ENOENT;
}
acpi_dev_put(adev);
/* Use SSP0 on Bay Trail CR devices */

View File

@ -11,7 +11,6 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include "../../codecs/hdac_hdmi.h"
#include "skl_hda_dsp_common.h"
#include <sound/hda_codec.h>
@ -22,21 +21,16 @@
int skl_hda_hdmi_add_pcm(struct snd_soc_card *card, int device)
{
struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
struct skl_hda_hdmi_pcm *pcm;
struct snd_soc_dai *dai;
char dai_name[NAME_SIZE];
pcm = devm_kzalloc(card->dev, sizeof(*pcm), GFP_KERNEL);
if (!pcm)
return -ENOMEM;
snprintf(dai_name, sizeof(dai_name), "intel-hdmi-hifi%d",
ctx->dai_index);
pcm->codec_dai = snd_soc_card_get_codec_dai(card, dai_name);
if (!pcm->codec_dai)
dai = snd_soc_card_get_codec_dai(card, dai_name);
if (!dai)
return -EINVAL;
pcm->device = device;
list_add_tail(&pcm->head, &ctx->hdmi_pcm_list);
ctx->hdmi.hdmi_comp = dai->component;
return 0;
}
@ -75,6 +69,11 @@ SND_SOC_DAILINK_DEF(dmic_codec,
SND_SOC_DAILINK_DEF(dmic16k,
DAILINK_COMP_ARRAY(COMP_CPU("DMIC16k Pin")));
SND_SOC_DAILINK_DEF(bt_offload_pin,
DAILINK_COMP_ARRAY(COMP_CPU(""))); /* initialized in driver probe function */
SND_SOC_DAILINK_DEF(dummy,
DAILINK_COMP_ARRAY(COMP_DUMMY()));
SND_SOC_DAILINK_DEF(platform,
DAILINK_COMP_ARRAY(COMP_PLATFORM("0000:00:1f.3")));
@ -132,37 +131,26 @@ struct snd_soc_dai_link skl_hda_be_dai_links[HDA_DSP_MAX_BE_DAI_LINKS] = {
.no_pcm = 1,
SND_SOC_DAILINK_REG(dmic16k, dmic_codec, platform),
},
{
.name = NULL, /* initialized in driver probe function */
.id = 8,
.dpcm_playback = 1,
.dpcm_capture = 1,
.no_pcm = 1,
SND_SOC_DAILINK_REG(bt_offload_pin, dummy, platform),
},
};
int skl_hda_hdmi_jack_init(struct snd_soc_card *card)
{
struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component = NULL;
struct skl_hda_hdmi_pcm *pcm;
char jack_name[NAME_SIZE];
int err;
if (ctx->common_hdmi_codec_drv)
return skl_hda_hdmi_build_controls(card);
/* HDMI disabled, do not create controls */
if (!ctx->hdmi.idisp_codec)
return 0;
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;
}
if (!component)
if (!ctx->hdmi.hdmi_comp)
return -EINVAL;
return hdac_hdmi_jack_port_init(component, &card->dapm);
return hda_dsp_hdmi_build_controls(card, ctx->hdmi.hdmi_comp);
}

View File

@ -17,51 +17,22 @@
#include <sound/hda_codec.h>
#include "../../codecs/hdac_hda.h"
#include "hda_dsp_common.h"
#include "sof_hdmi_common.h"
#define HDA_DSP_MAX_BE_DAI_LINKS 7
struct skl_hda_hdmi_pcm {
struct list_head head;
struct snd_soc_dai *codec_dai;
struct snd_soc_jack hdmi_jack;
int device;
};
#define HDA_DSP_MAX_BE_DAI_LINKS 8
struct skl_hda_private {
struct snd_soc_card card;
struct list_head hdmi_pcm_list;
struct sof_hdmi_private hdmi;
int pcm_count;
int dai_index;
const char *platform_name;
bool common_hdmi_codec_drv;
bool idisp_codec;
bool bt_offload_present;
int ssp_bt;
};
extern struct snd_soc_dai_link skl_hda_be_dai_links[HDA_DSP_MAX_BE_DAI_LINKS];
int skl_hda_hdmi_jack_init(struct snd_soc_card *card);
int skl_hda_hdmi_add_pcm(struct snd_soc_card *card, int device);
/*
* Search card topology and register HDMI PCM related controls
* to codec driver.
*/
static inline int skl_hda_hdmi_build_controls(struct snd_soc_card *card)
{
struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_component *component;
struct skl_hda_hdmi_pcm *pcm;
/* HDMI disabled, do not create controls */
if (list_empty(&ctx->hdmi_pcm_list))
return 0;
pcm = list_first_entry(&ctx->hdmi_pcm_list, struct skl_hda_hdmi_pcm,
head);
component = pcm->codec_dai->component;
if (!component)
return -EINVAL;
return hda_dsp_hdmi_build_controls(card, component);
}
#endif /* __SOUND_SOC_HDA_DSP_COMMON_H */

View File

@ -13,7 +13,6 @@
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "../../codecs/hdac_hdmi.h"
#include "skl_hda_dsp_common.h"
static const struct snd_soc_dapm_widget skl_hda_widgets[] = {
@ -76,7 +75,7 @@ skl_hda_add_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link *link)
link->platforms->name = ctx->platform_name;
link->nonatomic = 1;
if (!ctx->idisp_codec)
if (!ctx->hdmi.idisp_codec)
return 0;
if (strstr(link->name, "HDMI")) {
@ -95,32 +94,32 @@ skl_hda_add_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link *link)
#define IDISP_DAI_COUNT 3
#define HDAC_DAI_COUNT 2
#define DMIC_DAI_COUNT 2
#define BT_DAI_COUNT 1
/* there are two routes per iDisp output */
#define IDISP_ROUTE_COUNT (IDISP_DAI_COUNT * 2)
#define IDISP_CODEC_MASK 0x4
#define HDA_CODEC_AUTOSUSPEND_DELAY_MS 1000
static int skl_hda_fill_card_info(struct snd_soc_card *card,
static int skl_hda_fill_card_info(struct device *dev, struct snd_soc_card *card,
struct snd_soc_acpi_mach_params *mach_params)
{
struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_dai_link *dai_link;
struct snd_soc_dai_link *bt_link;
u32 codec_count, codec_mask;
int i, num_links, num_route;
codec_mask = mach_params->codec_mask;
codec_count = hweight_long(codec_mask);
ctx->idisp_codec = !!(codec_mask & IDISP_CODEC_MASK);
if (!codec_count || codec_count > 2 ||
(codec_count == 2 && !ctx->idisp_codec))
(codec_count == 2 && !ctx->hdmi.idisp_codec))
return -EINVAL;
if (codec_mask == IDISP_CODEC_MASK) {
/* topology with iDisp as the only HDA codec */
num_links = IDISP_DAI_COUNT + DMIC_DAI_COUNT;
num_links = IDISP_DAI_COUNT + DMIC_DAI_COUNT + BT_DAI_COUNT;
num_route = IDISP_ROUTE_COUNT;
/*
@ -129,7 +128,7 @@ static int skl_hda_fill_card_info(struct snd_soc_card *card,
* num_links of dai links need to be registered
* to ASoC.
*/
for (i = 0; i < DMIC_DAI_COUNT; i++) {
for (i = 0; i < (DMIC_DAI_COUNT + BT_DAI_COUNT); i++) {
skl_hda_be_dai_links[IDISP_DAI_COUNT + i] =
skl_hda_be_dai_links[IDISP_DAI_COUNT +
HDAC_DAI_COUNT + i];
@ -140,7 +139,7 @@ static int skl_hda_fill_card_info(struct snd_soc_card *card,
num_route = ARRAY_SIZE(skl_hda_map);
card->dapm_widgets = skl_hda_widgets;
card->num_dapm_widgets = ARRAY_SIZE(skl_hda_widgets);
if (!ctx->idisp_codec) {
if (!ctx->hdmi.idisp_codec) {
card->dapm_routes = &skl_hda_map[IDISP_ROUTE_COUNT];
num_route -= IDISP_ROUTE_COUNT;
for (i = 0; i < IDISP_DAI_COUNT; i++) {
@ -150,6 +149,28 @@ static int skl_hda_fill_card_info(struct snd_soc_card *card,
}
}
if (!ctx->bt_offload_present) {
/* remove last link since bt audio offload is not supported */
num_links -= BT_DAI_COUNT;
} else {
if (codec_mask == IDISP_CODEC_MASK)
bt_link = &skl_hda_be_dai_links[IDISP_DAI_COUNT + DMIC_DAI_COUNT];
else
bt_link = &skl_hda_be_dai_links[IDISP_DAI_COUNT + HDAC_DAI_COUNT + DMIC_DAI_COUNT];
/* complete the link name and dai name with SSP port number */
bt_link->name = devm_kasprintf(dev, GFP_KERNEL, "SSP%d-BT",
ctx->ssp_bt);
if (!bt_link->name)
return -ENOMEM;
bt_link->cpus->dai_name = devm_kasprintf(dev, GFP_KERNEL,
"SSP%d Pin",
ctx->ssp_bt);
if (!bt_link->cpus->dai_name)
return -ENOMEM;
}
card->num_links = num_links;
card->num_dapm_routes = num_route;
@ -184,7 +205,7 @@ static void skl_set_hda_codec_autosuspend_delay(struct snd_soc_card *card)
static int skl_hda_audio_probe(struct platform_device *pdev)
{
struct snd_soc_acpi_mach *mach;
struct snd_soc_acpi_mach *mach = pdev->dev.platform_data;
struct skl_hda_private *ctx;
struct snd_soc_card *card;
int ret;
@ -195,12 +216,6 @@ static int skl_hda_audio_probe(struct platform_device *pdev)
if (!ctx)
return -ENOMEM;
INIT_LIST_HEAD(&ctx->hdmi_pcm_list);
mach = pdev->dev.platform_data;
if (!mach)
return -EINVAL;
card = &ctx->card;
card->name = "hda-dsp",
card->owner = THIS_MODULE,
@ -213,7 +228,15 @@ static int skl_hda_audio_probe(struct platform_device *pdev)
snd_soc_card_set_drvdata(card, ctx);
ret = skl_hda_fill_card_info(card, &mach->mach_params);
if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
ctx->hdmi.idisp_codec = true;
if (hweight_long(mach->mach_params.bt_link_mask) == 1) {
ctx->bt_offload_present = true;
ctx->ssp_bt = fls(mach->mach_params.bt_link_mask) - 1;
}
ret = skl_hda_fill_card_info(&pdev->dev, card, &mach->mach_params);
if (ret < 0) {
dev_err(&pdev->dev, "Unsupported HDAudio/iDisp configuration found\n");
return ret;
@ -222,7 +245,6 @@ static int skl_hda_audio_probe(struct platform_device *pdev)
ctx->pcm_count = card->num_links;
ctx->dai_index = 1; /* hdmi codec dai name starts from index 1 */
ctx->platform_name = mach->mach_params.platform;
ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
card->dev = &pdev->dev;
if (!snd_soc_acpi_sof_parent(&pdev->dev))

View File

@ -681,7 +681,7 @@ static int sof_es8336_probe(struct platform_device *pdev)
dai_links[0].codecs->dai_name = "ES8326 HiFi";
} else {
dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
return -ENXIO;
return -ENOENT;
}
codec_dev = acpi_get_first_physical_node(adev);
@ -818,6 +818,16 @@ static const struct platform_device_id board_ids[] = {
SOF_ES8336_SPEAKERS_EN_GPIO1_QUIRK |
SOF_ES8336_JD_INVERTED),
},
{
.name = "arl_es83x6_c1_h02",
.driver_data = (kernel_ulong_t)(SOF_ES8336_SSP_CODEC(1) |
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_ES8336_SPEAKERS_EN_GPIO1_QUIRK |
SOF_ES8336_JD_INVERTED),
},
{ }
};
MODULE_DEVICE_TABLE(platform, board_ids);

View File

@ -17,7 +17,7 @@
#include "sof_sdw_common.h"
#include "../../codecs/rt711.h"
unsigned long sof_sdw_quirk = RT711_JD1;
static unsigned long sof_sdw_quirk = RT711_JD1;
static int quirk_override = -1;
module_param_named(quirk, quirk_override, int, 0444);
MODULE_PARM_DESC(quirk, "Board-specific quirk override");
@ -480,6 +480,14 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
RT711_JD2),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF9")
},
.driver_data = (void *)(SOC_SDW_CODEC_SPKR),
},
/* MeteorLake devices */
{
.callback = sof_sdw_quirk_cb,
@ -540,6 +548,56 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
},
.driver_data = (void *)(SOC_SDW_SIDECAR_AMPS),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CDB")
},
.driver_data = (void *)(SOC_SDW_CODEC_SPKR),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CDC")
},
.driver_data = (void *)(SOC_SDW_CODEC_SPKR),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CDD")
},
.driver_data = (void *)(SOC_SDW_CODEC_SPKR),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF8")
},
.driver_data = (void *)(SOC_SDW_CODEC_SPKR),
},
/* ArrowLake devices */
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CE8")
},
.driver_data = (void *)(SOC_SDW_CODEC_SPKR),
},
{
.callback = sof_sdw_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc"),
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0CF7")
},
.driver_data = (void *)(SOC_SDW_CODEC_SPKR),
},
{}
};
@ -1102,8 +1160,17 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
hdmi_num = SOF_PRE_TGL_HDMI_COUNT;
/* enable dmic01 & dmic16k */
if (sof_sdw_quirk & SOC_SDW_PCH_DMIC || mach_params->dmic_num)
dmic_num = 2;
if (sof_sdw_quirk & SOC_SDW_PCH_DMIC || mach_params->dmic_num) {
if (ctx->ignore_internal_dmic)
dev_warn(dev, "Ignoring PCH DMIC\n");
else
dmic_num = 2;
}
/*
* mach_params->dmic_num will be used to set the cfg-mics value of card->components
* string. Overwrite it to the actual number of PCH DMICs used in the device.
*/
mach_params->dmic_num = dmic_num;
if (sof_sdw_quirk & SOF_SSP_BT_OFFLOAD_PRESENT)
bt_num = 1;
@ -1148,14 +1215,10 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
}
/* dmic */
if (dmic_num > 0) {
if (ctx->ignore_internal_dmic) {
dev_warn(dev, "Ignoring PCH DMIC\n");
} else {
ret = create_dmic_dailinks(card, &dai_links, &be_id);
if (ret)
goto err_end;
}
if (dmic_num) {
ret = create_dmic_dailinks(card, &dai_links, &be_id);
if (ret)
goto err_end;
}
/* HDMI */

View File

@ -58,8 +58,6 @@ struct intel_mc_ctx {
unsigned int sdw_pin_index[SDW_INTEL_MAX_LINKS];
};
extern unsigned long sof_sdw_quirk;
/* generic HDMI support */
int sof_sdw_hdmi_init(struct snd_soc_pcm_runtime *rtd);

View File

@ -270,7 +270,11 @@ static int sof_wm8804_probe(struct platform_device *pdev)
snprintf(codec_name, sizeof(codec_name),
"%s%s", "i2c-", acpi_dev_name(adev));
dailink[dai_index].codecs->name = codec_name;
} else {
dev_err(&pdev->dev, "Error cannot find '%s' dev\n", mach->id);
return -ENOENT;
}
acpi_dev_put(adev);
snd_soc_card_set_drvdata(card, ctx);

View File

@ -35,6 +35,86 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
.group_id = 1,
};
static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
.num = 0,
.aggregated = 1,
.group_position = 2,
.group_id = 1,
};
static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
.num = 0,
.aggregated = 1,
.group_position = 3,
.group_id = 1,
};
static const struct snd_soc_acpi_adr_device cs35l56_2_r_adr[] = {
{
.adr = 0x00023201FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_r_endpoint,
.name_prefix = "AMP3"
},
{
.adr = 0x00023301FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_3_endpoint,
.name_prefix = "AMP4"
}
};
static const struct snd_soc_acpi_adr_device cs35l56_3_l_adr[] = {
{
.adr = 0x00033001fa355601ull,
.num_endpoints = 1,
.endpoints = &spk_l_endpoint,
.name_prefix = "AMP1"
},
{
.adr = 0x00033101fa355601ull,
.num_endpoints = 1,
.endpoints = &spk_2_endpoint,
.name_prefix = "AMP2"
}
};
static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
{ /* Jack Playback Endpoint */
.num = 0,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
{ /* DMIC Capture Endpoint */
.num = 1,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
{ /* Jack Capture Endpoint */
.num = 2,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
{ /* Speaker Playback Endpoint */
.num = 3,
.aggregated = 0,
.group_position = 0,
.group_id = 0,
},
};
static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = {
{
.adr = 0x00003001FA424301ull,
.num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
.endpoints = cs42l43_endpoints,
.name_prefix = "cs42l43"
}
};
static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
{
.adr = 0x000020025D071100ull,
@ -416,6 +496,25 @@ static const struct snd_soc_acpi_adr_device rt5682_0_adr[] = {
}
};
static const struct snd_soc_acpi_link_adr adl_cs42l43_l0_cs35l56_l23[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(cs42l43_0_adr),
.adr_d = cs42l43_0_adr,
},
{
.mask = BIT(2),
.num_adr = ARRAY_SIZE(cs35l56_2_r_adr),
.adr_d = cs35l56_2_r_adr,
},
{
.mask = BIT(3),
.num_adr = ARRAY_SIZE(cs35l56_3_l_adr),
.adr_d = cs35l56_3_l_adr,
},
{}
};
static const struct snd_soc_acpi_link_adr adl_rvp[] = {
{
.mask = BIT(0),
@ -560,6 +659,12 @@ EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_adl_machines);
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_sdw_machines[] = {
{
.link_mask = BIT(0) | BIT(2) | BIT(3),
.links = adl_cs42l43_l0_cs35l56_l23,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-adl-cs42l43-l0-cs35l56-l23.tplg",
},
{
.link_mask = 0xF, /* 4 active links required */
.links = adl_default,

View File

@ -15,6 +15,112 @@ static const struct snd_soc_acpi_endpoint single_endpoint = {
.group_id = 0,
};
static const struct snd_soc_acpi_endpoint spk_l_endpoint = {
.num = 0,
.aggregated = 1,
.group_position = 0,
.group_id = 1,
};
static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
.num = 0,
.aggregated = 1,
.group_position = 1,
.group_id = 1,
};
static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
.num = 0,
.aggregated = 1,
.group_position = 2,
.group_id = 1,
};
static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
.num = 0,
.aggregated = 1,
.group_position = 3,
.group_id = 1,
};
static const struct snd_soc_acpi_adr_device cs35l56_2_lr_adr[] = {
{
.adr = 0x00023001FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_l_endpoint,
.name_prefix = "AMP1"
},
{
.adr = 0x00023101FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_r_endpoint,
.name_prefix = "AMP2"
}
};
static const struct snd_soc_acpi_adr_device cs35l56_3_lr_adr[] = {
{
.adr = 0x00033001FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_l_endpoint,
.name_prefix = "AMP1"
},
{
.adr = 0x00033401FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_r_endpoint,
.name_prefix = "AMP2"
}
};
static const struct snd_soc_acpi_adr_device cs35l56_2_r_adr[] = {
{
.adr = 0x00023201FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_r_endpoint,
.name_prefix = "AMP3"
},
{
.adr = 0x00023301FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_3_endpoint,
.name_prefix = "AMP4"
}
};
static const struct snd_soc_acpi_adr_device cs35l56_3_l_adr[] = {
{
.adr = 0x00033001fa355601ull,
.num_endpoints = 1,
.endpoints = &spk_l_endpoint,
.name_prefix = "AMP1"
},
{
.adr = 0x00033101fa355601ull,
.num_endpoints = 1,
.endpoints = &spk_2_endpoint,
.name_prefix = "AMP2"
}
};
static const struct snd_soc_acpi_adr_device cs35l56_2_r1_adr[] = {
{
.adr = 0x00023101FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_r_endpoint,
.name_prefix = "AMP2"
},
};
static const struct snd_soc_acpi_adr_device cs35l56_3_l1_adr[] = {
{
.adr = 0x00033301fa355601ull,
.num_endpoints = 1,
.endpoints = &spk_l_endpoint,
.name_prefix = "AMP1"
},
};
static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
{ /* Jack Playback Endpoint */
.num = 0,
@ -51,6 +157,15 @@ static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = {
}
};
static const struct snd_soc_acpi_adr_device cs42l43_2_adr[] = {
{
.adr = 0x00023001FA424301ull,
.num_endpoints = ARRAY_SIZE(cs42l43_endpoints),
.endpoints = cs42l43_endpoints,
.name_prefix = "cs42l43"
}
};
static const struct snd_soc_acpi_adr_device rt711_0_adr[] = {
{
.adr = 0x000020025D071100ull,
@ -77,6 +192,80 @@ static const struct snd_soc_acpi_link_adr arl_cs42l43_l0[] = {
},
};
static const struct snd_soc_acpi_link_adr arl_cs42l43_l2[] = {
{
.mask = BIT(2),
.num_adr = ARRAY_SIZE(cs42l43_2_adr),
.adr_d = cs42l43_2_adr,
},
};
static const struct snd_soc_acpi_link_adr arl_cs42l43_l2_cs35l56_l3[] = {
{
.mask = BIT(2),
.num_adr = ARRAY_SIZE(cs42l43_2_adr),
.adr_d = cs42l43_2_adr,
},
{
.mask = BIT(3),
.num_adr = ARRAY_SIZE(cs35l56_3_lr_adr),
.adr_d = cs35l56_3_lr_adr,
},
{}
};
static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_l2[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(cs42l43_0_adr),
.adr_d = cs42l43_0_adr,
},
{
.mask = BIT(2),
.num_adr = ARRAY_SIZE(cs35l56_2_lr_adr),
.adr_d = cs35l56_2_lr_adr,
},
{}
};
static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_l23[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(cs42l43_0_adr),
.adr_d = cs42l43_0_adr,
},
{
.mask = BIT(2),
.num_adr = ARRAY_SIZE(cs35l56_2_r_adr),
.adr_d = cs35l56_2_r_adr,
},
{
.mask = BIT(3),
.num_adr = ARRAY_SIZE(cs35l56_3_l_adr),
.adr_d = cs35l56_3_l_adr,
},
{}
};
static const struct snd_soc_acpi_link_adr arl_cs42l43_l0_cs35l56_2_l23[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(cs42l43_0_adr),
.adr_d = cs42l43_0_adr,
},
{
.mask = BIT(2),
.num_adr = ARRAY_SIZE(cs35l56_2_r1_adr),
.adr_d = cs35l56_2_r1_adr,
},
{
.mask = BIT(3),
.num_adr = ARRAY_SIZE(cs35l56_3_l1_adr),
.adr_d = cs35l56_3_l1_adr,
},
{}
};
static const struct snd_soc_acpi_link_adr arl_rvp[] = {
{
.mask = BIT(0),
@ -95,19 +284,74 @@ static const struct snd_soc_acpi_link_adr arl_sdca_rvp[] = {
{}
};
static const struct snd_soc_acpi_codecs arl_essx_83x6 = {
.num_codecs = 3,
.codecs = { "ESSX8316", "ESSX8326", "ESSX8336"},
};
static const struct snd_soc_acpi_codecs arl_lt6911_hdmi = {
.num_codecs = 1,
.codecs = {"INTC10B0"}
};
struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_machines[] = {
{
.comp_ids = &arl_essx_83x6,
.drv_name = "arl_es83x6_c1_h02",
.machine_quirk = snd_soc_acpi_codec_list,
.quirk_data = &arl_lt6911_hdmi,
.sof_tplg_filename = "sof-arl-es83x6-ssp1-hdmi-ssp02.tplg",
},
{
.comp_ids = &arl_essx_83x6,
.drv_name = "sof-essx8336",
.sof_tplg_filename = "sof-arl-es8336", /* the tplg suffix is added at run time */
.tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER |
SND_SOC_ACPI_TPLG_INTEL_SSP_MSB |
SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
{},
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_arl_machines);
/* this table is used when there is no I2S codec present */
struct snd_soc_acpi_mach snd_soc_acpi_intel_arl_sdw_machines[] = {
{
.link_mask = BIT(0) | BIT(2) | BIT(3),
.links = arl_cs42l43_l0_cs35l56_l23,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg",
},
{
.link_mask = BIT(0) | BIT(2) | BIT(3),
.links = arl_cs42l43_l0_cs35l56_2_l23,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l23.tplg",
},
{
.link_mask = BIT(0) | BIT(2),
.links = arl_cs42l43_l0_cs35l56_l2,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-arl-cs42l43-l0-cs35l56-l2.tplg",
},
{
.link_mask = BIT(0),
.links = arl_cs42l43_l0,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-arl-cs42l43-l0.tplg",
},
{
.link_mask = BIT(2),
.links = arl_cs42l43_l2,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-arl-cs42l43-l2.tplg",
},
{
.link_mask = BIT(2) | BIT(3),
.links = arl_cs42l43_l2_cs35l56_l3,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-arl-cs42l43-l2-cs35l56-l3.tplg",
},
{
.link_mask = 0x1, /* link0 required */
.links = arl_rvp,

View File

@ -13,16 +13,8 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_hda_machines[] = {
{
/* .id is not used in this file */
.drv_name = "skl_hda_dsp_generic",
/* .fw_filename is dynamically set in skylake driver */
.sof_tplg_filename = "sof-hda-generic.tplg",
/*
* .machine_quirk and .quirk_data are not used here but
* can be used if we need a more complicated machine driver
* combining HDA+other device (e.g. DMIC).
*/
.sof_tplg_filename = "sof-hda-generic", /* the tplg suffix is added at run time */
.tplg_quirk_mask = SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER,
},
{},
};

View File

@ -36,6 +36,20 @@ static const struct snd_soc_acpi_endpoint spk_r_endpoint = {
.group_id = 1,
};
static const struct snd_soc_acpi_endpoint spk_2_endpoint = {
.num = 0,
.aggregated = 1,
.group_position = 2,
.group_id = 1,
};
static const struct snd_soc_acpi_endpoint spk_3_endpoint = {
.num = 0,
.aggregated = 1,
.group_position = 3,
.group_id = 1,
};
static const struct snd_soc_acpi_endpoint rt712_endpoints[] = {
{
.num = 0,
@ -103,6 +117,51 @@ static const struct snd_soc_acpi_endpoint cs42l43_endpoints[] = {
},
};
static const struct snd_soc_acpi_adr_device cs35l56_2_l_adr[] = {
{
.adr = 0x00023001FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_l_endpoint,
.name_prefix = "AMP1"
},
{
.adr = 0x00023101FA355601ull,
.num_endpoints = 1,
.endpoints = &spk_2_endpoint,
.name_prefix = "AMP2"
}
};
static const struct snd_soc_acpi_adr_device cs35l56_3_r_adr[] = {
{
.adr = 0x00033201fa355601ull,
.num_endpoints = 1,
.endpoints = &spk_r_endpoint,
.name_prefix = "AMP3"
},
{
.adr = 0x00033301fa355601ull,
.num_endpoints = 1,
.endpoints = &spk_3_endpoint,
.name_prefix = "AMP4"
}
};
static const struct snd_soc_acpi_adr_device cs35l56_3_lr_adr[] = {
{
.adr = 0x00033001fa355601ull,
.num_endpoints = 1,
.endpoints = &spk_l_endpoint,
.name_prefix = "AMP1"
},
{
.adr = 0x00033101fa355601ull,
.num_endpoints = 1,
.endpoints = &spk_r_endpoint,
.name_prefix = "AMP2"
}
};
static const struct snd_soc_acpi_adr_device cs42l43_0_adr[] = {
{
.adr = 0x00003001FA424301ull,
@ -210,6 +269,39 @@ static const struct snd_soc_acpi_link_adr lnl_cs42l43_l0[] = {
},
};
static const struct snd_soc_acpi_link_adr lnl_cs42l43_l0_cs35l56_l3[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(cs42l43_0_adr),
.adr_d = cs42l43_0_adr,
},
{
.mask = BIT(3),
.num_adr = ARRAY_SIZE(cs35l56_3_lr_adr),
.adr_d = cs35l56_3_lr_adr,
},
{}
};
static const struct snd_soc_acpi_link_adr lnl_cs42l43_l0_cs35l56_l23[] = {
{
.mask = BIT(0),
.num_adr = ARRAY_SIZE(cs42l43_0_adr),
.adr_d = cs42l43_0_adr,
},
{
.mask = BIT(2),
.num_adr = ARRAY_SIZE(cs35l56_2_l_adr),
.adr_d = cs35l56_2_l_adr,
},
{
.mask = BIT(3),
.num_adr = ARRAY_SIZE(cs35l56_3_r_adr),
.adr_d = cs35l56_3_r_adr,
},
{}
};
static const struct snd_soc_acpi_link_adr lnl_rvp[] = {
{
.mask = BIT(0),
@ -312,6 +404,18 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_lnl_sdw_machines[] = {
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-lnl-rt711-l0-rt1316-l23-rt714-l1.tplg",
},
{
.link_mask = BIT(0) | BIT(2) | BIT(3),
.links = lnl_cs42l43_l0_cs35l56_l23,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-lnl-cs42l43-l0-cs35l56-l23.tplg",
},
{
.link_mask = BIT(0) | BIT(3),
.links = lnl_cs42l43_l0_cs35l56_l3,
.drv_name = "sof_sdw",
.sof_tplg_filename = "sof-lnl-cs42l43-l0-cs35l56-l3.tplg",
},
{
.link_mask = BIT(0),
.links = lnl_cs42l43_l0,

View File

@ -160,6 +160,13 @@ static const struct snd_soc_dapm_route rt1318_map[] = {
{ "Speaker", NULL, "rt1318-2 SPOR" },
};
static const struct snd_soc_dapm_route rt1320_map[] = {
{ "Speaker", NULL, "rt1320-1 SPOL" },
{ "Speaker", NULL, "rt1320-1 SPOR" },
{ "Speaker", NULL, "rt1320-2 SPOL" },
{ "Speaker", NULL, "rt1320-2 SPOR" },
};
static const struct snd_soc_dapm_route *get_codec_name_and_route(struct snd_soc_dai *dai,
char *codec_name)
{
@ -171,8 +178,10 @@ static const struct snd_soc_dapm_route *get_codec_name_and_route(struct snd_soc_
return rt1308_map;
else if (strcmp(codec_name, "rt1316") == 0)
return rt1316_map;
else
else if (strcmp(codec_name, "rt1318") == 0)
return rt1318_map;
else
return rt1320_map;
}
int asoc_sdw_rt_amp_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)

View File

@ -254,6 +254,25 @@ struct asoc_sdw_codec_info codec_info_list[] = {
},
.dai_num = 1,
},
{
.part_id = 0x1320,
.dais = {
{
.direction = {true, false},
.dai_name = "rt1320-aif1",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_AMP_OUT_DAI_ID, SOC_SDW_UNUSED_DAI_ID},
.init = asoc_sdw_rt_amp_init,
.exit = asoc_sdw_rt_amp_exit,
.rtd_init = asoc_sdw_rt_amp_spk_rtd_init,
.controls = generic_spk_controls,
.num_controls = ARRAY_SIZE(generic_spk_controls),
.widgets = generic_spk_widgets,
.num_widgets = ARRAY_SIZE(generic_spk_widgets),
},
},
.dai_num = 1,
},
{
.part_id = 0x714,
.version_id = 3,

View File

@ -444,6 +444,10 @@ static int mclk_id_override = -1;
module_param_named(mclk_id, mclk_id_override, int, 0444);
MODULE_PARM_DESC(mclk_id, "SOF SSP mclk_id");
static int bt_link_mask_override;
module_param_named(bt_link_mask, bt_link_mask_override, int, 0444);
MODULE_PARM_DESC(bt_link_mask, "SOF BT offload link mask");
static int hda_init(struct snd_sof_dev *sdev)
{
struct hda_bus *hbus;
@ -511,6 +515,8 @@ static int check_dmic_num(struct snd_sof_dev *sdev)
if (nhlt)
dmic_num = intel_nhlt_get_dmic_geo(sdev->dev, nhlt);
dev_info(sdev->dev, "DMICs detected in NHLT tables: %d\n", dmic_num);
/* allow for module parameter override */
if (dmic_num_override != -1) {
dev_dbg(sdev->dev,
@ -527,7 +533,7 @@ static int check_dmic_num(struct snd_sof_dev *sdev)
return dmic_num;
}
static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev)
static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev, u8 device_type)
{
struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata;
struct nhlt_acpi_table *nhlt;
@ -538,9 +544,11 @@ static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev)
return ssp_mask;
if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_SSP)) {
ssp_mask = intel_nhlt_ssp_endpoint_mask(nhlt, NHLT_DEVICE_I2S);
ssp_mask = intel_nhlt_ssp_endpoint_mask(nhlt, device_type);
if (ssp_mask)
dev_info(sdev->dev, "NHLT_DEVICE_I2S detected, ssp_mask %#x\n", ssp_mask);
dev_info(sdev->dev, "NHLT device %s(%d) detected, ssp_mask %#x\n",
device_type == NHLT_DEVICE_BT ? "BT" : "I2S",
device_type, ssp_mask);
}
return ssp_mask;
@ -558,82 +566,6 @@ static int check_nhlt_ssp_mclk_mask(struct snd_sof_dev *sdev, int ssp_num)
return intel_nhlt_ssp_mclk_mask(nhlt, ssp_num);
}
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
const char *sof_tplg_filename,
const char *idisp_str,
const char *dmic_str)
{
const char *tplg_filename = NULL;
char *filename, *tmp;
const char *split_ext;
filename = kstrdup(sof_tplg_filename, GFP_KERNEL);
if (!filename)
return NULL;
/* this assumes a .tplg extension */
tmp = filename;
split_ext = strsep(&tmp, ".");
if (split_ext)
tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
"%s%s%s.tplg",
split_ext, idisp_str, dmic_str);
kfree(filename);
return tplg_filename;
}
static int dmic_detect_topology_fixup(struct snd_sof_dev *sdev,
const char **tplg_filename,
const char *idisp_str,
int *dmic_found,
bool tplg_fixup)
{
const char *dmic_str;
int dmic_num;
/* first check for DMICs (using NHLT or module parameter) */
dmic_num = check_dmic_num(sdev);
switch (dmic_num) {
case 1:
dmic_str = "-1ch";
break;
case 2:
dmic_str = "-2ch";
break;
case 3:
dmic_str = "-3ch";
break;
case 4:
dmic_str = "-4ch";
break;
default:
dmic_num = 0;
dmic_str = "";
break;
}
if (tplg_fixup) {
const char *default_tplg_filename = *tplg_filename;
const char *fixed_tplg_filename;
fixed_tplg_filename = fixup_tplg_name(sdev, default_tplg_filename,
idisp_str, dmic_str);
if (!fixed_tplg_filename)
return -ENOMEM;
*tplg_filename = fixed_tplg_filename;
}
dev_info(sdev->dev, "DMICs detected in NHLT tables: %d\n", dmic_num);
*dmic_found = dmic_num;
return 0;
}
#endif
static int hda_init_caps(struct snd_sof_dev *sdev)
{
u32 interface_mask = hda_get_interface_mask(sdev);
@ -1045,10 +977,7 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
struct snd_soc_acpi_mach *hda_mach;
struct snd_sof_pdata *pdata = sdev->pdata;
const char *tplg_filename;
const char *idisp_str;
int dmic_num = 0;
int codec_num = 0;
int ret;
int i;
/* codec detection */
@ -1071,33 +1000,30 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
* - one external HDAudio codec
*/
if (!*mach && codec_num <= 2) {
bool tplg_fixup;
bool tplg_fixup = false;
hda_mach = snd_soc_acpi_intel_hda_machines;
dev_info(bus->dev, "using HDA machine driver %s now\n",
hda_mach->drv_name);
if (codec_num == 1 && HDA_IDISP_CODEC(bus->codec_mask))
idisp_str = "-idisp";
else
idisp_str = "";
/* topology: use the info from hda_machines */
if (pdata->tplg_filename) {
tplg_fixup = false;
tplg_filename = pdata->tplg_filename;
} else {
/*
* topology: use the info from hda_machines since tplg file name
* is not overwritten
*/
if (!pdata->tplg_filename)
tplg_fixup = true;
tplg_filename = hda_mach->sof_tplg_filename;
}
ret = dmic_detect_topology_fixup(sdev, &tplg_filename, idisp_str, &dmic_num,
tplg_fixup);
if (ret < 0)
return;
hda_mach->mach_params.dmic_num = dmic_num;
pdata->tplg_filename = tplg_filename;
if (tplg_fixup &&
codec_num == 1 && HDA_IDISP_CODEC(bus->codec_mask)) {
tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
"%s-idisp",
hda_mach->sof_tplg_filename);
if (!tplg_filename)
return;
hda_mach->sof_tplg_filename = tplg_filename;
}
if (codec_num == 2 ||
(codec_num == 1 && !HDA_IDISP_CODEC(bus->codec_mask))) {
@ -1205,45 +1131,10 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev
break;
}
if (mach && mach->link_mask) {
int dmic_num = 0;
bool tplg_fixup;
const char *tplg_filename;
mach->mach_params.links = mach->links;
mach->mach_params.link_mask = mach->link_mask;
mach->mach_params.platform = dev_name(sdev->dev);
if (pdata->tplg_filename) {
tplg_fixup = false;
} else {
tplg_fixup = true;
tplg_filename = mach->sof_tplg_filename;
}
/*
* DMICs use up to 4 pins and are typically pin-muxed with SoundWire
* link 2 and 3, or link 1 and 2, thus we only try to enable dmics
* if all conditions are true:
* a) 2 or fewer links are used by SoundWire
* b) the NHLT table reports the presence of microphones
*/
if (hweight_long(mach->link_mask) <= 2) {
int ret;
ret = dmic_detect_topology_fixup(sdev, &tplg_filename, "",
&dmic_num, tplg_fixup);
if (ret < 0)
return NULL;
}
if (tplg_fixup)
pdata->tplg_filename = tplg_filename;
mach->mach_params.dmic_num = dmic_num;
dev_dbg(sdev->dev,
"SoundWire machine driver %s topology %s\n",
mach->drv_name,
pdata->tplg_filename);
return mach;
}
@ -1300,6 +1191,19 @@ static int check_tplg_quirk_mask(struct snd_soc_acpi_mach *mach)
return 0;
}
static char *remove_file_ext(const char *tplg_filename)
{
char *filename, *tmp;
filename = kstrdup(tplg_filename, GFP_KERNEL);
if (!filename)
return NULL;
/* remove file extension if exist */
tmp = filename;
return strsep(&tmp, ".");
}
struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
{
u32 interface_mask = hda_get_interface_mask(sdev);
@ -1311,21 +1215,75 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
const char *tplg_filename;
const char *tplg_suffix;
bool amp_name_valid;
bool i2s_mach_found = false;
bool sdw_mach_found = false;
/* Try I2S or DMIC if it is supported */
if (interface_mask & (BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC)))
if (interface_mask & (BIT(SOF_DAI_INTEL_SSP) | BIT(SOF_DAI_INTEL_DMIC))) {
mach = snd_soc_acpi_find_machine(desc->machines);
if (mach)
i2s_mach_found = true;
}
/*
* If I2S fails and no external HDaudio codec is detected,
* try SoundWire if it is supported
*/
if (!mach && !HDA_EXT_CODEC(bus->codec_mask) &&
(interface_mask & BIT(SOF_DAI_INTEL_ALH))) {
mach = hda_sdw_machine_select(sdev);
if (mach)
sdw_mach_found = true;
}
/*
* Choose HDA generic machine driver if mach is NULL.
* Otherwise, set certain mach params.
*/
hda_generic_machine_select(sdev, &mach);
if (!mach) {
dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
return NULL;
}
/* report BT offload link mask to machine driver */
mach->mach_params.bt_link_mask = check_nhlt_ssp_mask(sdev, NHLT_DEVICE_BT);
dev_info(sdev->dev, "BT link detected in NHLT tables: %#x\n",
mach->mach_params.bt_link_mask);
/* allow for module parameter override */
if (bt_link_mask_override) {
dev_dbg(sdev->dev, "overriding BT link detected in NHLT tables %#x by kernel param %#x\n",
mach->mach_params.bt_link_mask, bt_link_mask_override);
mach->mach_params.bt_link_mask = bt_link_mask_override;
}
if (hweight_long(mach->mach_params.bt_link_mask) > 1) {
dev_warn(sdev->dev, "invalid BT link mask %#x found, reset the mask\n",
mach->mach_params.bt_link_mask);
mach->mach_params.bt_link_mask = 0;
}
/*
* Fixup tplg file name by appending dmic num, ssp num, codec/amplifier
* name string if quirk flag is set.
*/
if (mach) {
bool add_extension = false;
bool tplg_fixup = false;
bool dmic_fixup = false;
/*
* If tplg file name is overridden, use it instead of
* the one set in mach table
*/
if (!sof_pdata->tplg_filename) {
sof_pdata->tplg_filename = mach->sof_tplg_filename;
/* remove file extension if it exists */
tplg_filename = remove_file_ext(mach->sof_tplg_filename);
if (!tplg_filename)
return NULL;
sof_pdata->tplg_filename = tplg_filename;
tplg_fixup = true;
}
@ -1343,20 +1301,36 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
/* report to machine driver if any DMICs are found */
mach->mach_params.dmic_num = check_dmic_num(sdev);
if (sdw_mach_found) {
/*
* DMICs use up to 4 pins and are typically pin-muxed with SoundWire
* link 2 and 3, or link 1 and 2, thus we only try to enable dmics
* if all conditions are true:
* a) 2 or fewer links are used by SoundWire
* b) the NHLT table reports the presence of microphones
*/
if (hweight_long(mach->link_mask) <= 2)
dmic_fixup = true;
else
mach->mach_params.dmic_num = 0;
} else {
if (mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER)
dmic_fixup = true;
}
if (tplg_fixup &&
mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER &&
dmic_fixup &&
mach->mach_params.dmic_num) {
tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
"%s%s%d%s",
sof_pdata->tplg_filename,
"-dmic",
i2s_mach_found ? "-dmic" : "-",
mach->mach_params.dmic_num,
"ch");
if (!tplg_filename)
return NULL;
sof_pdata->tplg_filename = tplg_filename;
add_extension = true;
}
if (mach->link_mask) {
@ -1365,7 +1339,7 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
}
/* report SSP link mask to machine driver */
mach->mach_params.i2s_link_mask = check_nhlt_ssp_mask(sdev);
mach->mach_params.i2s_link_mask = check_nhlt_ssp_mask(sdev, NHLT_DEVICE_I2S);
if (tplg_fixup &&
mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER &&
@ -1396,7 +1370,6 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
return NULL;
sof_pdata->tplg_filename = tplg_filename;
add_extension = true;
mclk_mask = check_nhlt_ssp_mclk_mask(sdev, ssp_num);
@ -1435,7 +1408,6 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
return NULL;
sof_pdata->tplg_filename = tplg_filename;
add_extension = true;
}
@ -1457,10 +1429,9 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
return NULL;
sof_pdata->tplg_filename = tplg_filename;
add_extension = true;
}
if (tplg_fixup && add_extension) {
if (tplg_fixup) {
tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
"%s%s",
sof_pdata->tplg_filename,
@ -1479,22 +1450,6 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
}
}
/*
* If I2S fails and no external HDaudio codec is detected,
* try SoundWire if it is supported
*/
if (!mach && !HDA_EXT_CODEC(bus->codec_mask) &&
(interface_mask & BIT(SOF_DAI_INTEL_ALH)))
mach = hda_sdw_machine_select(sdev);
/*
* Choose HDA generic machine driver if mach is NULL.
* Otherwise, set certain mach params.
*/
hda_generic_machine_select(sdev, &mach);
if (!mach)
dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n");
return mach;
}