mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 13:30:45 -05:00
ASoC: use sof_sdw as default Intel SOF SDW machine
Merge series from Bard Liao <yung-chuan.liao@linux.intel.com>: Currently, we create a ACPI mach table for every new audio configuration. And all Intel SOF SoundWire configurations point to the same sof_sdw machine driver. Also, we don't need a specific topology for a coufguration, we can use the function topology instead. That give us a change to generate an ACPI mach table based on the SoundWire codec information reported by the ACPI table and use the sof_sdw machine driver as the default machine driver. This will reduce the effort to support a new Intel SOF SoundWire audio configuration.
This commit is contained in:
@@ -114,8 +114,8 @@ struct snd_soc_acpi_endpoint {
|
||||
* @name_prefix: string used for codec controls
|
||||
*/
|
||||
struct snd_soc_acpi_adr_device {
|
||||
const u64 adr;
|
||||
const u8 num_endpoints;
|
||||
u64 adr;
|
||||
u8 num_endpoints;
|
||||
const struct snd_soc_acpi_endpoint *endpoints;
|
||||
const char *name_prefix;
|
||||
};
|
||||
@@ -131,8 +131,8 @@ struct snd_soc_acpi_adr_device {
|
||||
*/
|
||||
|
||||
struct snd_soc_acpi_link_adr {
|
||||
const u32 mask;
|
||||
const u32 num_adr;
|
||||
u32 mask;
|
||||
u32 num_adr;
|
||||
const struct snd_soc_acpi_adr_device *adr_d;
|
||||
};
|
||||
|
||||
|
||||
@@ -68,6 +68,7 @@ struct asoc_sdw_codec_info {
|
||||
const int part_id;
|
||||
const int version_id;
|
||||
const char *codec_name;
|
||||
const char *name_prefix;
|
||||
int amp_num;
|
||||
const u8 acpi_id[ACPI_ID_LEN];
|
||||
const bool ignore_internal_dmic;
|
||||
@@ -168,6 +169,7 @@ int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card, int *num_devs, int *
|
||||
|
||||
struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks,
|
||||
const struct snd_soc_acpi_endpoint *new);
|
||||
int asoc_sdw_get_dai_type(u32 type);
|
||||
|
||||
int asoc_sdw_parse_sdw_endpoints(struct snd_soc_card *card,
|
||||
struct asoc_sdw_dailink *soc_dais,
|
||||
|
||||
@@ -126,11 +126,15 @@ int sof_sdw_get_tplg_files(struct snd_soc_card *card, const struct snd_soc_acpi_
|
||||
if (!ret) {
|
||||
release_firmware(fw);
|
||||
} else {
|
||||
dev_dbg(card->dev, "Failed to open topology file: %s\n", (*tplg_files)[i]);
|
||||
dev_warn(card->dev,
|
||||
"Failed to open topology file: %s, you might need to\n",
|
||||
(*tplg_files)[i]);
|
||||
dev_warn(card->dev,
|
||||
"download it from https://github.com/thesofproject/sof-bin/\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return tplg_num;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(sof_sdw_get_tplg_files);
|
||||
|
||||
@@ -78,6 +78,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x700,
|
||||
.name_prefix = "rt700",
|
||||
.dais = {
|
||||
{
|
||||
.direction = {true, true},
|
||||
@@ -95,6 +96,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x711,
|
||||
.name_prefix = "rt711",
|
||||
.version_id = 3,
|
||||
.dais = {
|
||||
{
|
||||
@@ -115,6 +117,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x711,
|
||||
.name_prefix = "rt711",
|
||||
.version_id = 2,
|
||||
.dais = {
|
||||
{
|
||||
@@ -135,6 +138,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x712,
|
||||
.name_prefix = "rt712",
|
||||
.version_id = 3,
|
||||
.dais = {
|
||||
{
|
||||
@@ -176,6 +180,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x1712,
|
||||
.name_prefix = "rt712-dmic",
|
||||
.version_id = 3,
|
||||
.dais = {
|
||||
{
|
||||
@@ -190,6 +195,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x713,
|
||||
.name_prefix = "rt713",
|
||||
.version_id = 3,
|
||||
.dais = {
|
||||
{
|
||||
@@ -217,6 +223,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x1713,
|
||||
.name_prefix = "rt713-dmic",
|
||||
.version_id = 3,
|
||||
.dais = {
|
||||
{
|
||||
@@ -231,6 +238,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x1308,
|
||||
.name_prefix = "rt1308",
|
||||
.acpi_id = "10EC1308",
|
||||
.dais = {
|
||||
{
|
||||
@@ -253,6 +261,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x1316,
|
||||
.name_prefix = "rt1316",
|
||||
.dais = {
|
||||
{
|
||||
.direction = {true, true},
|
||||
@@ -273,6 +282,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x1318,
|
||||
.name_prefix = "rt1318",
|
||||
.dais = {
|
||||
{
|
||||
.direction = {true, true},
|
||||
@@ -293,6 +303,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x1320,
|
||||
.name_prefix = "rt1320",
|
||||
.dais = {
|
||||
{
|
||||
.direction = {true, false},
|
||||
@@ -313,6 +324,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x714,
|
||||
.name_prefix = "rt714",
|
||||
.version_id = 3,
|
||||
.ignore_internal_dmic = true,
|
||||
.dais = {
|
||||
@@ -328,6 +340,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x715,
|
||||
.name_prefix = "rt715",
|
||||
.version_id = 3,
|
||||
.ignore_internal_dmic = true,
|
||||
.dais = {
|
||||
@@ -343,6 +356,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x714,
|
||||
.name_prefix = "rt714",
|
||||
.version_id = 2,
|
||||
.ignore_internal_dmic = true,
|
||||
.dais = {
|
||||
@@ -358,6 +372,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x715,
|
||||
.name_prefix = "rt715",
|
||||
.version_id = 2,
|
||||
.ignore_internal_dmic = true,
|
||||
.dais = {
|
||||
@@ -373,6 +388,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x721,
|
||||
.name_prefix = "rt721",
|
||||
.version_id = 3,
|
||||
.dais = {
|
||||
{
|
||||
@@ -415,6 +431,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x722,
|
||||
.name_prefix = "rt722",
|
||||
.version_id = 3,
|
||||
.dais = {
|
||||
{
|
||||
@@ -459,6 +476,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x8373,
|
||||
.name_prefix = "Left",
|
||||
.dais = {
|
||||
{
|
||||
.direction = {true, true},
|
||||
@@ -478,6 +496,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x8363,
|
||||
.name_prefix = "Left",
|
||||
.dais = {
|
||||
{
|
||||
.direction = {true, false},
|
||||
@@ -497,6 +516,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x5682,
|
||||
.name_prefix = "rt5682",
|
||||
.dais = {
|
||||
{
|
||||
.direction = {true, true},
|
||||
@@ -514,6 +534,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x3556,
|
||||
.name_prefix = "AMP",
|
||||
.dais = {
|
||||
{
|
||||
.direction = {true, false},
|
||||
@@ -566,6 +587,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x4242,
|
||||
.name_prefix = "cs42l42",
|
||||
.dais = {
|
||||
{
|
||||
.direction = {true, true},
|
||||
@@ -583,6 +605,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x4243,
|
||||
.name_prefix = "cs42l43",
|
||||
.codec_name = "cs42l43-codec",
|
||||
.count_sidecar = asoc_sdw_bridge_cs35l56_count_sidecar,
|
||||
.add_sidecar = asoc_sdw_bridge_cs35l56_add_sidecar,
|
||||
@@ -634,6 +657,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0xaaaa, /* generic codec mockup */
|
||||
.name_prefix = "sdw_mockup_mmulti-function",
|
||||
.version_id = 0,
|
||||
.dais = {
|
||||
{
|
||||
@@ -659,6 +683,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0xaa55, /* headset codec mockup */
|
||||
.name_prefix = "sdw_mockup_headset0",
|
||||
.version_id = 0,
|
||||
.dais = {
|
||||
{
|
||||
@@ -672,6 +697,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x55aa, /* amplifier mockup */
|
||||
.name_prefix = "sdw_mockup_amp1",
|
||||
.version_id = 0,
|
||||
.dais = {
|
||||
{
|
||||
@@ -685,6 +711,7 @@ struct asoc_sdw_codec_info codec_info_list[] = {
|
||||
},
|
||||
{
|
||||
.part_id = 0x5555,
|
||||
.name_prefix = "sdw_mockup_mic0",
|
||||
.version_id = 0,
|
||||
.dais = {
|
||||
{
|
||||
@@ -1212,7 +1239,7 @@ struct asoc_sdw_dailink *asoc_sdw_find_dailink(struct asoc_sdw_dailink *dailinks
|
||||
}
|
||||
EXPORT_SYMBOL_NS(asoc_sdw_find_dailink, "SND_SOC_SDW_UTILS");
|
||||
|
||||
static int asoc_sdw_get_dai_type(u32 type)
|
||||
int asoc_sdw_get_dai_type(u32 type)
|
||||
{
|
||||
switch (type) {
|
||||
case SDCA_FUNCTION_TYPE_SMART_AMP:
|
||||
@@ -1230,6 +1257,7 @@ static int asoc_sdw_get_dai_type(u32 type)
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_NS(asoc_sdw_get_dai_type, "SND_SOC_SDW_UTILS");
|
||||
|
||||
/*
|
||||
* Check if the SDCA endpoint is present by the SDW peripheral
|
||||
|
||||
@@ -73,6 +73,10 @@ static int sof_test_topology_file(struct device *dev,
|
||||
if (!profile->tplg_path || !profile->tplg_name)
|
||||
return 0;
|
||||
|
||||
/* Dummy topology does not exist and should not be used */
|
||||
if (strstr(profile->tplg_name, "dummy"))
|
||||
return 0;
|
||||
|
||||
tplg_filename = kasprintf(GFP_KERNEL, "%s/%s", profile->tplg_path,
|
||||
profile->tplg_name);
|
||||
if (!tplg_filename)
|
||||
@@ -266,6 +270,7 @@ static void sof_print_profile_info(struct snd_sof_dev *sdev,
|
||||
enum sof_ipc_type ipc_type,
|
||||
struct sof_loadable_file_profile *profile)
|
||||
{
|
||||
struct snd_sof_pdata *plat_data = sdev->pdata;
|
||||
struct device *dev = sdev->dev;
|
||||
|
||||
if (ipc_type != profile->ipc_type)
|
||||
@@ -282,7 +287,12 @@ static void sof_print_profile_info(struct snd_sof_dev *sdev,
|
||||
|
||||
if (profile->fw_lib_path)
|
||||
dev_info(dev, " Firmware lib path: %s\n", profile->fw_lib_path);
|
||||
dev_info(dev, " Topology file: %s/%s\n", profile->tplg_path, profile->tplg_name);
|
||||
|
||||
if (plat_data->machine->get_function_tplg_files && !plat_data->disable_function_topology)
|
||||
dev_info(dev, " Topology file: function topologies\n");
|
||||
else
|
||||
dev_info(dev, " Topology file: %s/%s\n",
|
||||
profile->tplg_path, profile->tplg_name);
|
||||
}
|
||||
|
||||
int sof_create_ipc_file_profile(struct snd_sof_dev *sdev,
|
||||
|
||||
@@ -118,4 +118,5 @@ const struct sof_intel_dsp_desc apl_chip_info = {
|
||||
.power_down_dsp = hda_power_down_dsp,
|
||||
.disable_interrupts = hda_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_CAVS_1_5_PLUS,
|
||||
.platform = "apl",
|
||||
};
|
||||
|
||||
@@ -479,6 +479,7 @@ const struct sof_intel_dsp_desc cnl_chip_info = {
|
||||
.power_down_dsp = hda_power_down_dsp,
|
||||
.disable_interrupts = hda_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_CAVS_1_8,
|
||||
.platform = "cnl",
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -515,5 +516,6 @@ const struct sof_intel_dsp_desc jsl_chip_info = {
|
||||
.power_down_dsp = hda_power_down_dsp,
|
||||
.disable_interrupts = hda_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_CAVS_2_0,
|
||||
.platform = "jsl",
|
||||
};
|
||||
EXPORT_SYMBOL_NS(jsl_chip_info, "SND_SOC_SOF_INTEL_CNL");
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <sound/intel-dsp-config.h>
|
||||
#include <sound/intel-nhlt.h>
|
||||
#include <sound/soc-acpi-intel-ssp-common.h>
|
||||
#include <sound/soc_sdw_utils.h>
|
||||
#include <sound/sof.h>
|
||||
#include <sound/sof/xtensa.h>
|
||||
#include <sound/hda-mlink.h>
|
||||
@@ -33,6 +34,7 @@
|
||||
#include "../sof-pci-dev.h"
|
||||
#include "../ops.h"
|
||||
#include "../ipc4-topology.h"
|
||||
#include "../../intel/common/sof-function-topology-lib.h"
|
||||
#include "hda.h"
|
||||
|
||||
#include <trace/events/sof_intel.h>
|
||||
@@ -1131,14 +1133,166 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
|
||||
|
||||
#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
|
||||
|
||||
static bool is_endpoint_present(struct sdw_slave *sdw_device,
|
||||
struct asoc_sdw_codec_info *dai_info, int dai_type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sdw_device->sdca_data.num_functions; i++) {
|
||||
if (dai_type == dai_info->dais[i].dai_type)
|
||||
return true;
|
||||
}
|
||||
dev_dbg(&sdw_device->dev, "Endpoint DAI type %d not found\n", dai_type);
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev,
|
||||
struct sdw_slave *sdw_device,
|
||||
struct snd_soc_acpi_link_adr *link,
|
||||
int *amp_index)
|
||||
{
|
||||
struct snd_soc_acpi_adr_device *adr_dev;
|
||||
const char *name_prefix = "";
|
||||
int index = link->num_adr;
|
||||
bool is_amp = true; /* Set it to false if the codec wiah any NON-AMP DAI type */
|
||||
int ep_index = 0;
|
||||
int i, j;
|
||||
|
||||
link->mask = BIT(sdw_device->bus->link_id);
|
||||
/* index is 0 based, we need allocate index + 1 for the array size */
|
||||
if (!index)
|
||||
adr_dev = devm_kzalloc(dev, sizeof(*adr_dev), GFP_KERNEL);
|
||||
else
|
||||
adr_dev = devm_krealloc(dev, (struct snd_soc_acpi_adr_device *)link->adr_d,
|
||||
(index + 1) * sizeof(*adr_dev), GFP_KERNEL);
|
||||
|
||||
if (!adr_dev)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < asoc_sdw_get_codec_info_list_count(); i++) {
|
||||
struct snd_soc_acpi_endpoint *endpoints;
|
||||
int amp_group_id = 1;
|
||||
|
||||
if (sdw_device->id.part_id != codec_info_list[i].part_id)
|
||||
continue;
|
||||
|
||||
endpoints = devm_kcalloc(dev, codec_info_list[i].dai_num,
|
||||
sizeof(struct snd_soc_acpi_endpoint), GFP_KERNEL);
|
||||
if (!endpoints)
|
||||
return NULL;
|
||||
|
||||
name_prefix = codec_info_list[i].name_prefix;
|
||||
/*
|
||||
* This should not happen, but add a paranoid check to avoid NULL pointer
|
||||
* dereference
|
||||
*/
|
||||
if (!name_prefix) {
|
||||
dev_err(dev, "codec_info_list name_prefix of part id %#x is missing\n",
|
||||
codec_info_list[i].part_id);
|
||||
return NULL;
|
||||
}
|
||||
for (j = 0; j < codec_info_list[i].dai_num; j++) {
|
||||
/* Check if the endpoint is present by the SDCA DisCo table */
|
||||
if (!is_endpoint_present(sdw_device, &codec_info_list[i],
|
||||
codec_info_list[i].dais[j].dai_type))
|
||||
continue;
|
||||
|
||||
endpoints[ep_index].num = ep_index;
|
||||
if (codec_info_list[i].dais[j].dai_type == SOC_SDW_DAI_TYPE_AMP) {
|
||||
/* Assume all amp are aggregated */
|
||||
endpoints[ep_index].aggregated = 1;
|
||||
endpoints[ep_index].group_id = amp_group_id;
|
||||
endpoints[ep_index].group_position = *amp_index;
|
||||
/* Set group id = 2 for feedback capture endpoint */
|
||||
amp_group_id++;
|
||||
} else {
|
||||
endpoints[ep_index].aggregated = 0;
|
||||
endpoints[ep_index].group_id = 0;
|
||||
endpoints[ep_index].group_position = 0;
|
||||
is_amp = false;
|
||||
}
|
||||
ep_index++;
|
||||
}
|
||||
adr_dev[index].endpoints = endpoints;
|
||||
adr_dev[index].num_endpoints = ep_index;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == asoc_sdw_get_codec_info_list_count()) {
|
||||
dev_err(dev, "part id %#x is not supported\n", sdw_device->id.part_id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
adr_dev[index].adr = ((u64)sdw_device->id.class_id & 0xFF) |
|
||||
((u64)sdw_device->id.part_id & 0xFFFF) << 8 |
|
||||
((u64)sdw_device->id.mfg_id & 0xFFFF) << 24 |
|
||||
((u64)(sdw_device->id.unique_id & 0xF) << 40) |
|
||||
((u64)(sdw_device->id.sdw_version & 0xF) << 44) |
|
||||
((u64)(sdw_device->bus->link_id & 0xF) << 48);
|
||||
|
||||
if (!is_amp) {
|
||||
/* For non-amp codecs, get name_prefix from codec_info_list[] */
|
||||
adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, "%s", name_prefix);
|
||||
goto done_name_prefix;
|
||||
}
|
||||
|
||||
/*
|
||||
* The name_prefix comes from codec_info_list which has a name_prefix per codec.
|
||||
* And we need to give a unique name_prefix for each amp and should be backwards
|
||||
* compatible to the existing acpi match tables to not break existing UCMs.
|
||||
* For the common name_prefix, we append the amp index to it. However, for the
|
||||
* "Left" name_prefix, we convert the second amp name_prefix to "Right" and
|
||||
* for the third and further amps, we set the name_prefix to "AMP<amp_index>".
|
||||
*/
|
||||
if (!strcmp(name_prefix, "Left")) {
|
||||
switch (*amp_index) {
|
||||
case 1:
|
||||
adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"%s", "Left");
|
||||
break;
|
||||
case 2:
|
||||
adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL,
|
||||
"%s", "Right");
|
||||
break;
|
||||
default:
|
||||
/* Set the name_fix to AMP<amp_index> if there are more than 2 amps */
|
||||
adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, "%s%d",
|
||||
"AMP", *amp_index);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, "%s%d",
|
||||
name_prefix,
|
||||
*amp_index);
|
||||
}
|
||||
(*amp_index)++;
|
||||
|
||||
done_name_prefix:
|
||||
if (!adr_dev[index].name_prefix) {
|
||||
dev_err(dev, "failed to allocate memory for name_prefix\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dev_dbg(dev, "adr[%d] 0x%llx link id %d name_prefix \"%s\" is found\n",
|
||||
index, adr_dev[index].adr, sdw_device->bus->link_id, adr_dev[index].name_prefix);
|
||||
|
||||
link->num_adr++;
|
||||
|
||||
return adr_dev;
|
||||
}
|
||||
|
||||
static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev)
|
||||
{
|
||||
struct snd_sof_pdata *pdata = sdev->pdata;
|
||||
const struct snd_soc_acpi_link_adr *link;
|
||||
const struct sof_intel_dsp_desc *chip;
|
||||
struct snd_soc_acpi_link_adr *links;
|
||||
struct sdw_peripherals *peripherals;
|
||||
struct snd_soc_acpi_mach *mach;
|
||||
struct sof_intel_hda_dev *hdev;
|
||||
u32 link_mask;
|
||||
int link_index, link_num;
|
||||
int amp_index = 1;
|
||||
u32 link_mask = 0;
|
||||
int i;
|
||||
|
||||
hdev = pdata->hw_pdata;
|
||||
@@ -1215,7 +1369,53 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev
|
||||
peripherals->array[i]->id.part_id,
|
||||
peripherals->array[i]->id.sdw_version);
|
||||
|
||||
return NULL;
|
||||
chip = get_chip_info(sdev->pdata);
|
||||
|
||||
/* SDCA was not well supported in the BIOS before ACE2.0 */
|
||||
if (chip->hw_ip_version < SOF_INTEL_ACE_2_0)
|
||||
return NULL;
|
||||
|
||||
if (!peripherals->num_peripherals)
|
||||
return NULL;
|
||||
|
||||
/* Create default SDW mach */
|
||||
mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL);
|
||||
if (!mach)
|
||||
return NULL;
|
||||
|
||||
/* Get link mask and link number */
|
||||
for (i = 0; i < peripherals->num_peripherals; i++)
|
||||
link_mask |= BIT(peripherals->array[i]->bus->link_id);
|
||||
|
||||
link_num = hweight32(link_mask);
|
||||
links = devm_kcalloc(sdev->dev, link_num, sizeof(*links), GFP_KERNEL);
|
||||
if (!links)
|
||||
return NULL;
|
||||
|
||||
/* Generate snd_soc_acpi_link_adr struct for each peripheral reported by the ACPI table */
|
||||
for (i = 0; i < peripherals->num_peripherals; i++) {
|
||||
/* link_index = the number of used links below the current link */
|
||||
link_index = hweight32(link_mask & (BIT(peripherals->array[i]->bus->link_id) - 1));
|
||||
links[link_index].adr_d = find_acpi_adr_device(sdev->dev, peripherals->array[i],
|
||||
&links[link_index], &_index);
|
||||
if (!links[link_index].adr_d)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mach->drv_name = "sof_sdw";
|
||||
mach->mach_params.links = links;
|
||||
mach->mach_params.link_mask = link_mask;
|
||||
mach->mach_params.platform = dev_name(sdev->dev);
|
||||
mach->get_function_tplg_files = sof_sdw_get_tplg_files;
|
||||
/*
|
||||
* Set mach->sof_tplg_filename as a dummy topology to avoid tplg file checking
|
||||
* and being used.
|
||||
*/
|
||||
mach->sof_tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
|
||||
"sof-%s-dummy.tplg", chip->platform);
|
||||
|
||||
dev_info(sdev->dev, "Use SoundWire default machine driver with function topologies\n");
|
||||
return mach;
|
||||
}
|
||||
#else
|
||||
static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev)
|
||||
@@ -1543,6 +1743,7 @@ MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA");
|
||||
MODULE_IMPORT_NS("SND_INTEL_SOUNDWIRE_ACPI");
|
||||
MODULE_IMPORT_NS("SOUNDWIRE_INTEL_INIT");
|
||||
MODULE_IMPORT_NS("SOUNDWIRE_INTEL");
|
||||
MODULE_IMPORT_NS("SND_SOC_SDW_UTILS");
|
||||
MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK");
|
||||
MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON");
|
||||
MODULE_IMPORT_NS("SND_SOC_ACPI_INTEL_MATCH");
|
||||
|
||||
@@ -193,4 +193,5 @@ const struct sof_intel_dsp_desc icl_chip_info = {
|
||||
.power_down_dsp = hda_power_down_dsp,
|
||||
.disable_interrupts = hda_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_CAVS_2_0,
|
||||
.platform = "icl",
|
||||
};
|
||||
|
||||
@@ -183,6 +183,7 @@ const struct sof_intel_dsp_desc lnl_chip_info = {
|
||||
.power_down_dsp = mtl_power_down_dsp,
|
||||
.disable_interrupts = lnl_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_ACE_2_0,
|
||||
.platform = "lnl",
|
||||
};
|
||||
|
||||
MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_MTL");
|
||||
|
||||
@@ -786,6 +786,7 @@ const struct sof_intel_dsp_desc mtl_chip_info = {
|
||||
.power_down_dsp = mtl_power_down_dsp,
|
||||
.disable_interrupts = mtl_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_ACE_1_0,
|
||||
.platform = "mtl",
|
||||
};
|
||||
|
||||
const struct sof_intel_dsp_desc arl_s_chip_info = {
|
||||
@@ -814,4 +815,5 @@ const struct sof_intel_dsp_desc arl_s_chip_info = {
|
||||
.power_down_dsp = mtl_power_down_dsp,
|
||||
.disable_interrupts = mtl_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_ACE_1_0,
|
||||
.platform = "arl",
|
||||
};
|
||||
|
||||
@@ -125,6 +125,7 @@ const struct sof_intel_dsp_desc ptl_chip_info = {
|
||||
.power_down_dsp = mtl_power_down_dsp,
|
||||
.disable_interrupts = lnl_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_ACE_3_0,
|
||||
.platform = "ptl",
|
||||
};
|
||||
|
||||
const struct sof_intel_dsp_desc wcl_chip_info = {
|
||||
@@ -149,6 +150,7 @@ const struct sof_intel_dsp_desc wcl_chip_info = {
|
||||
.power_down_dsp = mtl_power_down_dsp,
|
||||
.disable_interrupts = lnl_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_ACE_3_0,
|
||||
.platform = "wcl",
|
||||
};
|
||||
|
||||
MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_MTL");
|
||||
|
||||
@@ -186,6 +186,7 @@ struct sof_intel_dsp_desc {
|
||||
u32 sdw_alh_base;
|
||||
u32 d0i3_offset;
|
||||
u32 quirks;
|
||||
const char *platform;
|
||||
enum sof_intel_hw_ip_version hw_ip_version;
|
||||
int (*read_sdw_lcount)(struct snd_sof_dev *sdev);
|
||||
void (*enable_sdw_irq)(struct snd_sof_dev *sdev, bool enable);
|
||||
|
||||
@@ -113,5 +113,6 @@ const struct sof_intel_dsp_desc skl_chip_info = {
|
||||
.power_down_dsp = hda_power_down_dsp,
|
||||
.disable_interrupts = hda_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_CAVS_1_5,
|
||||
.platform = "skl",
|
||||
};
|
||||
EXPORT_SYMBOL_NS(skl_chip_info, "SND_SOC_SOF_INTEL_HDA_COMMON");
|
||||
|
||||
@@ -162,6 +162,7 @@ const struct sof_intel_dsp_desc tgl_chip_info = {
|
||||
.power_down_dsp = hda_power_down_dsp,
|
||||
.disable_interrupts = hda_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_CAVS_2_5,
|
||||
.platform = "tgl",
|
||||
};
|
||||
|
||||
const struct sof_intel_dsp_desc tglh_chip_info = {
|
||||
@@ -191,6 +192,7 @@ const struct sof_intel_dsp_desc tglh_chip_info = {
|
||||
.power_down_dsp = hda_power_down_dsp,
|
||||
.disable_interrupts = hda_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_CAVS_2_5,
|
||||
.platform = "tgl",
|
||||
};
|
||||
|
||||
const struct sof_intel_dsp_desc ehl_chip_info = {
|
||||
@@ -220,6 +222,7 @@ const struct sof_intel_dsp_desc ehl_chip_info = {
|
||||
.power_down_dsp = hda_power_down_dsp,
|
||||
.disable_interrupts = hda_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_CAVS_2_5,
|
||||
.platform = "ehl",
|
||||
};
|
||||
|
||||
const struct sof_intel_dsp_desc adls_chip_info = {
|
||||
@@ -249,4 +252,5 @@ const struct sof_intel_dsp_desc adls_chip_info = {
|
||||
.power_down_dsp = hda_power_down_dsp,
|
||||
.disable_interrupts = hda_dsp_disable_interrupts,
|
||||
.hw_ip_version = SOF_INTEL_CAVS_2_5,
|
||||
.platform = "adl",
|
||||
};
|
||||
|
||||
@@ -2523,9 +2523,14 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file)
|
||||
* callback or the callback returns 0.
|
||||
*/
|
||||
if (!tplg_cnt) {
|
||||
if (strstr(file, "dummy")) {
|
||||
dev_err(scomp->dev,
|
||||
"Function topology is required, please upgrade sof-firmware\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
tplg_files[0] = file;
|
||||
tplg_cnt = 1;
|
||||
dev_dbg(scomp->dev, "loading topology: %s\n", file);
|
||||
dev_info(scomp->dev, "loading topology: %s\n", file);
|
||||
} else {
|
||||
dev_info(scomp->dev, "Using function topologies instead %s\n", file);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user