Skip to content

Commit 34c43ad

Browse files
committed
ASoC: Intel: updates for 6.10 - part5
Merge series from Pierre-Louis Bossart <[email protected]>: This patchset corrects a couple of mistakes corrected, improves snd_soc_card allocation. The new functionality is mostly for SoundWire platforms, with new SKUs for Dell and Acer, and support for the Cirrus Logic bridge/sidecar amplifier topology.
2 parents 9a8cadd + b831b4d commit 34c43ad

File tree

10 files changed

+397
-75
lines changed

10 files changed

+397
-75
lines changed

sound/soc/intel/boards/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -690,6 +690,7 @@ config SND_SOC_INTEL_SOUNDWIRE_SOF_MACH
690690
select SND_SOC_CS42L43_SDW
691691
select MFD_CS42L43
692692
select MFD_CS42L43_SDW
693+
select SND_SOC_CS35L56_SPI
693694
select SND_SOC_CS35L56_SDW
694695
select SND_SOC_DMIC
695696
select SND_SOC_INTEL_HDA_DSP_COMMON

sound/soc/intel/boards/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ snd-soc-ehl-rt5660-objs := ehl_rt5660.o
3737
snd-soc-sof-ssp-amp-objs := sof_ssp_amp.o
3838
snd-soc-sof-sdw-objs += sof_sdw.o \
3939
sof_sdw_maxim.o sof_sdw_rt_amp.o \
40+
bridge_cs35l56.o \
4041
sof_sdw_rt5682.o sof_sdw_rt700.o \
4142
sof_sdw_rt711.o sof_sdw_rt_sdca_jack_common.o \
4243
sof_sdw_rt712_sdca.o sof_sdw_rt722_sdca.o \
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
//
3+
// Intel SOF Machine Driver with Cirrus Logic CS35L56 Smart Amp
4+
5+
#include <linux/module.h>
6+
#include <linux/platform_device.h>
7+
#include <sound/core.h>
8+
#include <sound/pcm.h>
9+
#include <sound/pcm_params.h>
10+
#include <sound/soc.h>
11+
#include <sound/soc-acpi.h>
12+
#include "sof_sdw_common.h"
13+
14+
static const struct snd_soc_dapm_widget bridge_widgets[] = {
15+
SND_SOC_DAPM_SPK("Bridge Speaker", NULL),
16+
};
17+
18+
static const struct snd_soc_dapm_route bridge_map[] = {
19+
{"Bridge Speaker", NULL, "AMPL SPK"},
20+
{"Bridge Speaker", NULL, "AMPR SPK"},
21+
};
22+
23+
static const char * const bridge_cs35l56_name_prefixes[] = {
24+
"AMPL",
25+
"AMPR",
26+
};
27+
28+
static int bridge_cs35l56_asp_init(struct snd_soc_pcm_runtime *rtd)
29+
{
30+
struct snd_soc_card *card = rtd->card;
31+
int i, ret;
32+
unsigned int rx_mask = 3; // ASP RX1, RX2
33+
unsigned int tx_mask = 3; // ASP TX1, TX2
34+
struct snd_soc_dai *codec_dai;
35+
struct snd_soc_dai *cpu_dai;
36+
37+
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
38+
"%s spk:cs35l56-bridge",
39+
card->components);
40+
if (!card->components)
41+
return -ENOMEM;
42+
43+
ret = snd_soc_dapm_new_controls(&card->dapm, bridge_widgets,
44+
ARRAY_SIZE(bridge_widgets));
45+
if (ret) {
46+
dev_err(card->dev, "widgets addition failed: %d\n", ret);
47+
return ret;
48+
}
49+
50+
ret = snd_soc_dapm_add_routes(&card->dapm, bridge_map, ARRAY_SIZE(bridge_map));
51+
if (ret) {
52+
dev_err(card->dev, "map addition failed: %d\n", ret);
53+
return ret;
54+
}
55+
56+
/* 4 x 16-bit sample slots and FSYNC=48000, BCLK=3.072 MHz */
57+
for_each_rtd_codec_dais(rtd, i, codec_dai) {
58+
ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_mask, rx_mask, 4, 16);
59+
if (ret < 0)
60+
return ret;
61+
62+
ret = snd_soc_dai_set_sysclk(codec_dai, 0, 3072000, SND_SOC_CLOCK_IN);
63+
if (ret < 0)
64+
return ret;
65+
}
66+
67+
for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
68+
ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_mask, rx_mask, 4, 16);
69+
if (ret < 0)
70+
return ret;
71+
}
72+
73+
return 0;
74+
}
75+
76+
static const struct snd_soc_pcm_stream bridge_params = {
77+
.formats = SNDRV_PCM_FMTBIT_S16_LE,
78+
.rate_min = 48000,
79+
.rate_max = 48000,
80+
.channels_min = 2,
81+
.channels_max = 2,
82+
};
83+
84+
SND_SOC_DAILINK_DEFS(bridge_dai,
85+
DAILINK_COMP_ARRAY(COMP_CODEC("cs42l43-codec", "cs42l43-asp")),
86+
DAILINK_COMP_ARRAY(COMP_CODEC("spi-cs35l56-left", "cs35l56-asp1"),
87+
COMP_CODEC("spi-cs35l56-right", "cs35l56-asp1")),
88+
DAILINK_COMP_ARRAY(COMP_PLATFORM("cs42l43-codec")));
89+
90+
static const struct snd_soc_dai_link bridge_dai_template = {
91+
.name = "cs42l43-cs35l56",
92+
.init = bridge_cs35l56_asp_init,
93+
.c2c_params = &bridge_params,
94+
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBC_CFC,
95+
SND_SOC_DAILINK_REG(bridge_dai),
96+
};
97+
98+
int bridge_cs35l56_count_sidecar(struct snd_soc_card *card,
99+
int *num_dais, int *num_devs)
100+
{
101+
if (sof_sdw_quirk & SOF_SIDECAR_AMPS) {
102+
(*num_dais)++;
103+
(*num_devs) += ARRAY_SIZE(bridge_cs35l56_name_prefixes);
104+
}
105+
106+
return 0;
107+
}
108+
109+
int bridge_cs35l56_add_sidecar(struct snd_soc_card *card,
110+
struct snd_soc_dai_link **dai_links,
111+
struct snd_soc_codec_conf **codec_conf)
112+
{
113+
if (sof_sdw_quirk & SOF_SIDECAR_AMPS) {
114+
**dai_links = bridge_dai_template;
115+
116+
for (int i = 0; i < ARRAY_SIZE(bridge_cs35l56_name_prefixes); i++) {
117+
(*codec_conf)->dlc.name = (*dai_links)->codecs[i].name;
118+
(*codec_conf)->name_prefix = bridge_cs35l56_name_prefixes[i];
119+
(*codec_conf)++;
120+
}
121+
122+
(*dai_links)++;
123+
}
124+
125+
return 0;
126+
}
127+
128+
int bridge_cs35l56_spk_init(struct snd_soc_card *card,
129+
struct snd_soc_dai_link *dai_links,
130+
struct sof_sdw_codec_info *info,
131+
bool playback)
132+
{
133+
if (sof_sdw_quirk & SOF_SIDECAR_AMPS)
134+
info->amp_num += ARRAY_SIZE(bridge_cs35l56_name_prefixes);
135+
136+
return 0;
137+
}

sound/soc/intel/boards/skl_hda_dsp_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ struct skl_hda_hdmi_pcm {
2828
};
2929

3030
struct skl_hda_private {
31+
struct snd_soc_card card;
3132
struct list_head hdmi_pcm_list;
3233
int pcm_count;
3334
int dai_index;

sound/soc/intel/boards/skl_hda_dsp_generic.c

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,6 @@ skl_hda_add_dai_link(struct snd_soc_card *card, struct snd_soc_dai_link *link)
9292
return ret;
9393
}
9494

95-
static struct snd_soc_card hda_soc_card = {
96-
.name = "hda-dsp",
97-
.owner = THIS_MODULE,
98-
.dai_link = skl_hda_be_dai_links,
99-
.dapm_widgets = skl_hda_widgets,
100-
.dapm_routes = skl_hda_map,
101-
.add_dai_link = skl_hda_add_dai_link,
102-
.fully_routed = true,
103-
.late_probe = skl_hda_card_late_probe,
104-
};
105-
106-
static char hda_soc_components[30];
107-
10895
#define IDISP_DAI_COUNT 3
10996
#define HDAC_DAI_COUNT 2
11097
#define DMIC_DAI_COUNT 2
@@ -115,9 +102,9 @@ static char hda_soc_components[30];
115102

116103
#define HDA_CODEC_AUTOSUSPEND_DELAY_MS 1000
117104

118-
static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params)
105+
static int skl_hda_fill_card_info(struct snd_soc_card *card,
106+
struct snd_soc_acpi_mach_params *mach_params)
119107
{
120-
struct snd_soc_card *card = &hda_soc_card;
121108
struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
122109
struct snd_soc_dai_link *dai_link;
123110
u32 codec_count, codec_mask;
@@ -199,6 +186,7 @@ static int skl_hda_audio_probe(struct platform_device *pdev)
199186
{
200187
struct snd_soc_acpi_mach *mach;
201188
struct skl_hda_private *ctx;
189+
struct snd_soc_card *card;
202190
int ret;
203191

204192
dev_dbg(&pdev->dev, "entry\n");
@@ -213,32 +201,44 @@ static int skl_hda_audio_probe(struct platform_device *pdev)
213201
if (!mach)
214202
return -EINVAL;
215203

216-
snd_soc_card_set_drvdata(&hda_soc_card, ctx);
204+
card = &ctx->card;
205+
card->name = "hda-dsp",
206+
card->owner = THIS_MODULE,
207+
card->dai_link = skl_hda_be_dai_links,
208+
card->dapm_widgets = skl_hda_widgets,
209+
card->dapm_routes = skl_hda_map,
210+
card->add_dai_link = skl_hda_add_dai_link,
211+
card->fully_routed = true,
212+
card->late_probe = skl_hda_card_late_probe,
213+
214+
snd_soc_card_set_drvdata(card, ctx);
217215

218-
ret = skl_hda_fill_card_info(&mach->mach_params);
216+
ret = skl_hda_fill_card_info(card, &mach->mach_params);
219217
if (ret < 0) {
220218
dev_err(&pdev->dev, "Unsupported HDAudio/iDisp configuration found\n");
221219
return ret;
222220
}
223221

224-
ctx->pcm_count = hda_soc_card.num_links;
222+
ctx->pcm_count = card->num_links;
225223
ctx->dai_index = 1; /* hdmi codec dai name starts from index 1 */
226224
ctx->platform_name = mach->mach_params.platform;
227225
ctx->common_hdmi_codec_drv = mach->mach_params.common_hdmi_codec_drv;
228226

229-
hda_soc_card.dev = &pdev->dev;
227+
card->dev = &pdev->dev;
230228
if (!snd_soc_acpi_sof_parent(&pdev->dev))
231-
hda_soc_card.disable_route_checks = true;
229+
card->disable_route_checks = true;
232230

233231
if (mach->mach_params.dmic_num > 0) {
234-
snprintf(hda_soc_components, sizeof(hda_soc_components),
235-
"cfg-dmics:%d", mach->mach_params.dmic_num);
236-
hda_soc_card.components = hda_soc_components;
232+
card->components = devm_kasprintf(card->dev, GFP_KERNEL,
233+
"cfg-dmics:%d",
234+
mach->mach_params.dmic_num);
235+
if (!card->components)
236+
return -ENOMEM;
237237
}
238238

239-
ret = devm_snd_soc_register_card(&pdev->dev, &hda_soc_card);
239+
ret = devm_snd_soc_register_card(&pdev->dev, card);
240240
if (!ret)
241-
skl_set_hda_codec_autosuspend_delay(&hda_soc_card);
241+
skl_set_hda_codec_autosuspend_delay(card);
242242

243243
return ret;
244244
}

0 commit comments

Comments
 (0)