summaryrefslogtreecommitdiff
path: root/sound/soc/intel/boards/sof_sdw.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/boards/sof_sdw.c')
-rw-r--r--sound/soc/intel/boards/sof_sdw.c106
1 files changed, 63 insertions, 43 deletions
diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c
index d65c5da49000..b1595fdb500d 100644
--- a/sound/soc/intel/boards/sof_sdw.c
+++ b/sound/soc/intel/boards/sof_sdw.c
@@ -39,6 +39,8 @@ static void log_quirks(struct device *dev)
dev_err(dev, "quirk SOF_SDW_NO_AGGREGATION enabled but no longer supported\n");
if (sof_sdw_quirk & SOF_CODEC_SPKR)
dev_dbg(dev, "quirk SOF_CODEC_SPKR enabled\n");
+ if (sof_sdw_quirk & SOF_SIDECAR_AMPS)
+ dev_dbg(dev, "quirk SOF_SIDECAR_AMPS enabled\n");
}
static int sof_sdw_quirk_cb(const struct dmi_system_id *id)
@@ -421,8 +423,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = {
DMI_EXACT_MATCH(DMI_PRODUCT_SKU, "0C0F")
},
.driver_data = (void *)(SOF_SDW_TGL_HDMI |
- RT711_JD2 |
- SOF_SDW_FOUR_SPK),
+ RT711_JD2),
},
{
.callback = sof_sdw_quirk_cb,
@@ -996,6 +997,8 @@ static struct sof_sdw_codec_info codec_info_list[] = {
{
.part_id = 0x4243,
.codec_name = "cs42l43-codec",
+ .count_sidecar = bridge_cs35l56_count_sidecar,
+ .add_sidecar = bridge_cs35l56_add_sidecar,
.dais = {
{
.direction = {true, false},
@@ -1024,7 +1027,7 @@ static struct sof_sdw_codec_info codec_info_list[] = {
.dailink = {SDW_AMP_OUT_DAI_ID, SDW_UNUSED_DAI_ID},
.init = sof_sdw_cs42l43_spk_init,
.rtd_init = cs42l43_spk_rtd_init,
- .quirk = SOF_CODEC_SPKR,
+ .quirk = SOF_CODEC_SPKR | SOF_SIDECAR_AMPS,
},
},
.dai_num = 4,
@@ -1280,6 +1283,8 @@ struct sof_sdw_endpoint {
u32 link_mask;
const char *codec_name;
+ const char *name_prefix;
+ bool include_sidecar;
struct sof_sdw_codec_info *codec_info;
const struct sof_sdw_dai_info *dai_info;
@@ -1335,17 +1340,18 @@ static struct sof_sdw_dailink *find_dailink(struct sof_sdw_dailink *dailinks,
static int parse_sdw_endpoints(struct snd_soc_card *card,
struct sof_sdw_dailink *sof_dais,
- struct sof_sdw_endpoint *sof_ends)
+ struct sof_sdw_endpoint *sof_ends,
+ int *num_devs)
{
struct device *dev = card->dev;
struct mc_private *ctx = snd_soc_card_get_drvdata(card);
struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
struct snd_soc_acpi_mach_params *mach_params = &mach->mach_params;
- struct snd_soc_codec_conf *codec_conf = card->codec_conf;
const struct snd_soc_acpi_link_adr *adr_link;
struct sof_sdw_endpoint *sof_end = sof_ends;
int num_dais = 0;
int i, j;
+ int ret;
for (adr_link = mach_params->links; adr_link->num_adr; adr_link++) {
int num_link_dailinks = 0;
@@ -1377,13 +1383,19 @@ static int parse_sdw_endpoints(struct snd_soc_card *card,
if (!codec_name)
return -ENOMEM;
- codec_conf->dlc.name = codec_name;
- codec_conf->name_prefix = adr_dev->name_prefix;
- codec_conf++;
-
dev_dbg(dev, "Adding prefix %s for %s\n",
adr_dev->name_prefix, codec_name);
+ sof_end->name_prefix = adr_dev->name_prefix;
+
+ if (codec_info->count_sidecar && codec_info->add_sidecar) {
+ ret = codec_info->count_sidecar(card, &num_dais, num_devs);
+ if (ret)
+ return ret;
+
+ sof_end->include_sidecar = true;
+ }
+
for (j = 0; j < adr_dev->num_endpoints; j++) {
const struct snd_soc_acpi_endpoint *adr_end;
const struct sof_sdw_dai_info *dai_info;
@@ -1444,20 +1456,33 @@ static int parse_sdw_endpoints(struct snd_soc_card *card,
ctx->append_dai_type |= (num_link_dailinks > 1);
}
- WARN_ON(codec_conf != card->codec_conf + card->num_configs);
-
return num_dais;
}
static int create_sdw_dailink(struct snd_soc_card *card,
struct sof_sdw_dailink *sof_dai,
struct snd_soc_dai_link **dai_links,
- int *be_id)
+ int *be_id, struct snd_soc_codec_conf **codec_conf)
{
struct device *dev = card->dev;
struct mc_private *ctx = snd_soc_card_get_drvdata(card);
struct sof_sdw_endpoint *sof_end;
int stream;
+ int ret;
+
+ list_for_each_entry(sof_end, &sof_dai->endpoints, list) {
+ if (sof_end->name_prefix) {
+ (*codec_conf)->dlc.name = sof_end->codec_name;
+ (*codec_conf)->name_prefix = sof_end->name_prefix;
+ (*codec_conf)++;
+ }
+
+ if (sof_end->include_sidecar) {
+ ret = sof_end->codec_info->add_sidecar(card, dai_links, codec_conf);
+ if (ret)
+ return ret;
+ }
+ }
for_each_pcm_streams(stream) {
static const char * const sdw_stream_name[] = {
@@ -1570,7 +1595,8 @@ static int create_sdw_dailink(struct snd_soc_card *card,
static int create_sdw_dailinks(struct snd_soc_card *card,
struct snd_soc_dai_link **dai_links, int *be_id,
- struct sof_sdw_dailink *sof_dais)
+ struct sof_sdw_dailink *sof_dais,
+ struct snd_soc_codec_conf **codec_conf)
{
struct mc_private *ctx = snd_soc_card_get_drvdata(card);
int ret, i;
@@ -1582,7 +1608,8 @@ static int create_sdw_dailinks(struct snd_soc_card *card,
while (sof_dais->initialised) {
int current_be_id;
- ret = create_sdw_dailink(card, sof_dais, dai_links, &current_be_id);
+ ret = create_sdw_dailink(card, sof_dais, dai_links,
+ &current_be_id, codec_conf);
if (ret)
return ret;
@@ -1752,17 +1779,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
goto err_dai;
}
- /* will be populated when acpi endpoints are parsed */
- codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
- if (!codec_conf) {
- ret = -ENOMEM;
- goto err_end;
- }
-
- card->codec_conf = codec_conf;
- card->num_configs = num_devs;
-
- ret = parse_sdw_endpoints(card, sof_dais, sof_ends);
+ ret = parse_sdw_endpoints(card, sof_dais, sof_ends, &num_devs);
if (ret < 0)
goto err_end;
@@ -1799,6 +1816,12 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
sdw_be_num, ssp_num, dmic_num,
ctx->hdmi.idisp_codec ? hdmi_num : 0, bt_num);
+ codec_conf = devm_kcalloc(dev, num_devs, sizeof(*codec_conf), GFP_KERNEL);
+ if (!codec_conf) {
+ ret = -ENOMEM;
+ goto err_end;
+ }
+
/* allocate BE dailinks */
num_links = sdw_be_num + ssp_num + dmic_num + hdmi_num + bt_num;
dai_links = devm_kcalloc(dev, num_links, sizeof(*dai_links), GFP_KERNEL);
@@ -1807,12 +1830,15 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
goto err_end;
}
+ card->codec_conf = codec_conf;
+ card->num_configs = num_devs;
card->dai_link = dai_links;
card->num_links = num_links;
/* SDW */
if (sdw_be_num) {
- ret = create_sdw_dailinks(card, &dai_links, &be_id, sof_dais);
+ ret = create_sdw_dailinks(card, &dai_links, &be_id,
+ sof_dais, &codec_conf);
if (ret)
goto err_end;
}
@@ -1848,6 +1874,7 @@ static int sof_card_dai_links_create(struct snd_soc_card *card)
goto err_end;
}
+ WARN_ON(codec_conf != card->codec_conf + card->num_configs);
WARN_ON(dai_links != card->dai_link + card->num_links);
err_end:
@@ -1879,15 +1906,6 @@ static int sof_sdw_card_late_probe(struct snd_soc_card *card)
return ret;
}
-/* SoC card */
-static const char sdw_card_long_name[] = "Intel Soundwire SOF";
-
-static struct snd_soc_card card_sof_sdw = {
- .name = "soundwire",
- .owner = THIS_MODULE,
- .late_probe = sof_sdw_card_late_probe,
-};
-
/* helper to get the link that the codec DAI is used */
static struct snd_soc_dai_link *mc_find_codec_dai_used(struct snd_soc_card *card,
const char *dai_name)
@@ -1939,20 +1957,24 @@ static void mc_dailink_exit_loop(struct snd_soc_card *card)
static int mc_probe(struct platform_device *pdev)
{
- struct snd_soc_card *card = &card_sof_sdw;
struct snd_soc_acpi_mach *mach = dev_get_platdata(&pdev->dev);
+ struct snd_soc_card *card;
struct mc_private *ctx;
int amp_num = 0, i;
int ret;
- card->dev = &pdev->dev;
-
- dev_dbg(card->dev, "Entry\n");
+ dev_dbg(&pdev->dev, "Entry\n");
- ctx = devm_kzalloc(card->dev, sizeof(*ctx), GFP_KERNEL);
+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
if (!ctx)
return -ENOMEM;
+ card = &ctx->card;
+ card->dev = &pdev->dev;
+ card->name = "soundwire",
+ card->owner = THIS_MODULE,
+ card->late_probe = sof_sdw_card_late_probe,
+
snd_soc_card_set_drvdata(card, ctx);
dmi_check_system(sof_sdw_quirk_table);
@@ -1988,7 +2010,7 @@ static int mc_probe(struct platform_device *pdev)
amp_num += codec_info_list[i].amp_num;
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
- "cfg-amp:%d", amp_num);
+ " cfg-amp:%d", amp_num);
if (!card->components)
return -ENOMEM;
@@ -2001,8 +2023,6 @@ static int mc_probe(struct platform_device *pdev)
return -ENOMEM;
}
- card->long_name = sdw_card_long_name;
-
/* Register the card */
ret = devm_snd_soc_register_card(card->dev, card);
if (ret) {