Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion include/sound/soc.h
Original file line number Diff line number Diff line change
Expand Up @@ -699,7 +699,8 @@ struct snd_soc_dai_link_component {
struct snd_soc_dai_link_ch_map {
unsigned int cpu;
unsigned int codec;
unsigned int ch_mask;
unsigned int cpu_ch_mask;
unsigned int codec_ch_mask;
};

struct snd_soc_dai_link {
Expand Down
2 changes: 0 additions & 2 deletions include/sound/soc_sdw_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,6 @@ int asoc_sdw_cs_amp_init(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_links,
struct asoc_sdw_codec_info *info,
bool playback);
int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai);
int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix);

/* MAXIM codec support */
Expand Down
46 changes: 0 additions & 46 deletions sound/soc/sdw_utils/soc_sdw_cs_amp.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
#include <sound/soc-dai.h>
#include <sound/soc_sdw_utils.h>

#define CS_AMP_CHANNELS_PER_AMP 4
#define CS35L56_SPK_VOLUME_0DB 400 /* 0dB Max */

int asoc_sdw_cs35l56_volume_limit(struct snd_soc_card *card, const char *name_prefix)
Expand Down Expand Up @@ -64,51 +63,6 @@ int asoc_sdw_cs_spk_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai
}
EXPORT_SYMBOL_NS(asoc_sdw_cs_spk_rtd_init, "SND_SOC_SDW_UTILS");

int asoc_sdw_cs_spk_feedback_rtd_init(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai)
{
const struct snd_soc_dai_link *dai_link = rtd->dai_link;
const struct snd_soc_dai_link_ch_map *ch_map;
const struct snd_soc_dai_link_component *codec_dlc;
struct snd_soc_dai *codec_dai;
u8 ch_slot[8] = {};
unsigned int amps_per_bus, ch_per_amp, mask;
int i, ret;

WARN_ON(dai_link->num_cpus > ARRAY_SIZE(ch_slot));

/*
* CS35L56 has 4 TX channels. When the capture is aggregated the
* same bus slots will be allocated to all the amps on a bus. Only
* one amp on that bus can be transmitting in each slot so divide
* the available 4 slots between all the amps on a bus.
*/
amps_per_bus = dai_link->num_codecs / dai_link->num_cpus;
if ((amps_per_bus == 0) || (amps_per_bus > CS_AMP_CHANNELS_PER_AMP)) {
dev_err(rtd->card->dev, "Illegal num_codecs:%u / num_cpus:%u\n",
dai_link->num_codecs, dai_link->num_cpus);
return -EINVAL;
}

ch_per_amp = CS_AMP_CHANNELS_PER_AMP / amps_per_bus;

for_each_rtd_ch_maps(rtd, i, ch_map) {
codec_dlc = snd_soc_link_to_codec(rtd->dai_link, i);
codec_dai = snd_soc_find_dai(codec_dlc);
mask = GENMASK(ch_per_amp - 1, 0) << ch_slot[ch_map->cpu];

ret = snd_soc_dai_set_tdm_slot(codec_dai, 0, mask, 4, 32);
if (ret < 0) {
dev_err(rtd->card->dev, "Failed to set TDM slot:%d\n", ret);
return ret;
}

ch_slot[ch_map->cpu] += ch_per_amp;
}

return 0;
}
EXPORT_SYMBOL_NS(asoc_sdw_cs_spk_feedback_rtd_init, "SND_SOC_SDW_UTILS");

int asoc_sdw_cs_amp_init(struct snd_soc_card *card,
struct snd_soc_dai_link *dai_links,
struct asoc_sdw_codec_info *info,
Expand Down
24 changes: 14 additions & 10 deletions sound/soc/sdw_utils/soc_sdw_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,6 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.dai_name = "cs35l56-sdw1c",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
.rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
},
},
.dai_num = 2,
Expand Down Expand Up @@ -829,7 +828,6 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.dai_name = "cs35l56-sdw1c",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
.rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
},
},
.dai_num = 2,
Expand Down Expand Up @@ -858,7 +856,6 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.dai_name = "cs35l56-sdw1c",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
.rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
},
},
.dai_num = 2,
Expand Down Expand Up @@ -887,7 +884,6 @@ struct asoc_sdw_codec_info codec_info_list[] = {
.dai_name = "cs35l56-sdw1c",
.dai_type = SOC_SDW_DAI_TYPE_AMP,
.dailink = {SOC_SDW_UNUSED_DAI_ID, SOC_SDW_AMP_IN_DAI_ID},
.rtd_init = asoc_sdw_cs_spk_feedback_rtd_init,
},
},
.dai_num = 2,
Expand Down Expand Up @@ -1539,7 +1535,7 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
struct snd_soc_dai_link_ch_map *ch_maps;
int ch = params_channels(params);
unsigned int ch_mask;
unsigned int cpu_ch_mask, codec_ch_mask;
int num_codecs;
int step;
int i;
Expand All @@ -1549,8 +1545,9 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,

/* Identical data will be sent to all codecs in playback */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
ch_mask = GENMASK(ch - 1, 0);
cpu_ch_mask = GENMASK(ch - 1, 0);
step = 0;
codec_ch_mask = 0;
} else {
num_codecs = rtd->dai_link->num_codecs;

Expand All @@ -1560,17 +1557,24 @@ int asoc_sdw_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
}

ch_mask = GENMASK(ch / num_codecs - 1, 0);
step = hweight_long(ch_mask);
cpu_ch_mask = GENMASK(ch / num_codecs - 1, 0);
step = hweight_long(cpu_ch_mask);
codec_ch_mask = cpu_ch_mask;
}

/*
* The captured data will be combined from each cpu DAI if the dai
* link has more than one codec DAIs. Set codec channel mask and
* ASoC will set the corresponding channel numbers for each cpu dai.
*
* sdw_stream_add_slave() assigns different payload offsets to each
* codec in a capture stream, so that the same channels on each
* codec map to different channels on the CPU.
*/
for_each_link_ch_maps(rtd->dai_link, i, ch_maps)
ch_maps->ch_mask = ch_mask << (i * step);
for_each_link_ch_maps(rtd->dai_link, i, ch_maps) {
ch_maps->cpu_ch_mask = cpu_ch_mask << (i * step);
ch_maps->codec_ch_mask = codec_ch_mask;
}

return 0;
}
Expand Down
17 changes: 14 additions & 3 deletions sound/soc/soc-pcm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,9 @@ static int __soc_pcm_hw_params(struct snd_pcm_substream *substream,

for_each_rtd_codec_dais(rtd, i, codec_dai) {
unsigned int tdm_mask = snd_soc_dai_tdm_mask_get(codec_dai, substream->stream);
struct snd_soc_dai_link_ch_map *ch_maps;
unsigned int ch_mask = 0;
int j;

/*
* Skip CODECs which don't support the current stream type,
Expand All @@ -1228,9 +1231,17 @@ static int __soc_pcm_hw_params(struct snd_pcm_substream *substream,
/* copy params for each codec */
tmp_params = *params;

/* fixup params based on TDM slot masks */
if (tdm_mask)
/* fixup params based on TDM or ch_map masks */
if (tdm_mask) {
soc_pcm_codec_params_fixup(&tmp_params, tdm_mask);
} else {
for_each_rtd_ch_maps(rtd, j, ch_maps)
if (ch_maps->codec == i)
ch_mask |= ch_maps->codec_ch_mask;

if (ch_mask)
soc_pcm_codec_params_fixup(&tmp_params, ch_mask);
}

ret = snd_soc_dai_hw_params(codec_dai, substream,
&tmp_params);
Expand Down Expand Up @@ -1264,7 +1275,7 @@ static int __soc_pcm_hw_params(struct snd_pcm_substream *substream,
*/
for_each_rtd_ch_maps(rtd, j, ch_maps)
if (ch_maps->cpu == i)
ch_mask |= ch_maps->ch_mask;
ch_mask |= ch_maps->cpu_ch_mask;

/* fixup cpu channel number */
if (ch_mask)
Expand Down
Loading