···336336 struct snd_interval *chan = hw_param_interval(params,337337 SNDRV_PCM_HW_PARAM_CHANNELS);338338 struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);339339- struct snd_soc_dpcm *dpcm = container_of(340340- params, struct snd_soc_dpcm, hw_params);341341- struct snd_soc_dai_link *fe_dai_link = dpcm->fe->dai_link;342342- struct snd_soc_dai_link *be_dai_link = dpcm->be->dai_link;339339+ struct snd_soc_dpcm *dpcm, *rtd_dpcm = NULL;340340+341341+ /*342342+ * The following loop will be called only for playback stream343343+ * In this platform, there is only one playback device on every SSP344344+ */345345+ for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_PLAYBACK, dpcm) {346346+ rtd_dpcm = dpcm;347347+ break;348348+ }349349+350350+ /*351351+ * This following loop will be called only for capture stream352352+ * In this platform, there is only one capture device on every SSP353353+ */354354+ for_each_dpcm_fe(rtd, SNDRV_PCM_STREAM_CAPTURE, dpcm) {355355+ rtd_dpcm = dpcm;356356+ break;357357+ }358358+359359+ if (!rtd_dpcm)360360+ return -EINVAL;361361+362362+ /*363363+ * The above 2 loops are mutually exclusive based on the stream direction,364364+ * thus rtd_dpcm variable will never be overwritten365365+ */343366344367 /*345368 * The ADSP will convert the FE rate to 48k, stereo, 24 bit346369 */347347- if (!strcmp(fe_dai_link->name, "Kbl Audio Port") ||348348- !strcmp(fe_dai_link->name, "Kbl Audio Headset Playback") ||349349- !strcmp(fe_dai_link->name, "Kbl Audio Capture Port")) {370370+ if (!strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Port") ||371371+ !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Headset Playback") ||372372+ !strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio Capture Port")) {350373 rate->min = rate->max = 48000;351374 chan->min = chan->max = 2;352375 snd_mask_none(fmt);353376 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S24_LE);354354- } else if (!strcmp(fe_dai_link->name, "Kbl Audio DMIC cap")) {377377+ } else if (!strcmp(rtd_dpcm->fe->dai_link->name, "Kbl Audio DMIC cap")) {355378 if (params_channels(params) == 2 ||356379 DMIC_CH(dmic_constraints) == 2)357380 chan->min = chan->max = 2;···385362 * The speaker on the SSP0 supports S16_LE and not S24_LE.386363 * thus changing the mask here387364 */388388- if (!strcmp(be_dai_link->name, "SSP0-Codec"))365365+ if (!strcmp(rtd_dpcm->be->dai_link->name, "SSP0-Codec"))389366 snd_mask_set_format(fmt, SNDRV_PCM_FORMAT_S16_LE);390367391368 return 0;
···116116117117 lb = &card->dai_link[*index + 1];118118119119- lb->name = kasprintf(GFP_KERNEL, "%s-lb", pad->name);119119+ lb->name = devm_kasprintf(card->dev, GFP_KERNEL, "%s-lb", pad->name);120120 if (!lb->name)121121 return -ENOMEM;122122···327327 return ret;328328329329 if (axg_card_cpu_is_playback_fe(dai_link->cpus->of_node))330330- ret = meson_card_set_fe_link(card, dai_link, np, true);330330+ return meson_card_set_fe_link(card, dai_link, np, true);331331 else if (axg_card_cpu_is_capture_fe(dai_link->cpus->of_node))332332- ret = meson_card_set_fe_link(card, dai_link, np, false);333333- else334334- ret = meson_card_set_be_link(card, dai_link, np);332332+ return meson_card_set_fe_link(card, dai_link, np, false);335333334334+335335+ ret = meson_card_set_be_link(card, dai_link, np);336336 if (ret)337337 return ret;338338339339- if (axg_card_cpu_is_tdm_iface(dai_link->cpus->of_node))340340- ret = axg_card_parse_tdm(card, np, index);341341- else if (axg_card_cpu_is_codec(dai_link->cpus->of_node)) {339339+ if (axg_card_cpu_is_codec(dai_link->cpus->of_node)) {342340 dai_link->params = &codec_params;343343- dai_link->no_pcm = 0; /* link is not a DPCM BE */341341+ } else {342342+ dai_link->no_pcm = 1;343343+ snd_soc_dai_link_set_capabilities(dai_link);344344+ if (axg_card_cpu_is_tdm_iface(dai_link->cpus->of_node))345345+ ret = axg_card_parse_tdm(card, np, index);344346 }345347346348 return ret;
+6-5
sound/soc/meson/axg-tdm-formatter.c
···7070static int axg_tdm_formatter_enable(struct axg_tdm_formatter *formatter)7171{7272 struct axg_tdm_stream *ts = formatter->stream;7373- bool invert = formatter->drv->quirks->invert_sclk;7373+ bool invert;7474 int ret;75757676 /* Do nothing if the formatter is already enabled */···9696 return ret;97979898 /*9999- * If sclk is inverted, invert it back and provide the inversion100100- * required by the formatter9999+ * If sclk is inverted, it means the bit should latched on the100100+ * rising edge which is what our HW expects. If not, we need to101101+ * invert it before the formatter.101102 */102102- invert ^= axg_tdm_sclk_invert(ts->iface->fmt);103103- ret = clk_set_phase(formatter->sclk, invert ? 180 : 0);103103+ invert = axg_tdm_sclk_invert(ts->iface->fmt);104104+ ret = clk_set_phase(formatter->sclk, invert ? 0 : 180);104105 if (ret)105106 return ret;106107
-1
sound/soc/meson/axg-tdm-formatter.h
···16161717struct axg_tdm_formatter_hw {1818 unsigned int skew_offset;1919- bool invert_sclk;2019};21202221struct axg_tdm_formatter_ops {
+18-10
sound/soc/meson/axg-tdm-interface.c
···119119{120120 struct axg_tdm_iface *iface = snd_soc_dai_get_drvdata(dai);121121122122- /* These modes are not supported */123123- if (fmt & (SND_SOC_DAIFMT_CBS_CFM | SND_SOC_DAIFMT_CBM_CFS)) {124124- dev_err(dai->dev, "only CBS_CFS and CBM_CFM are supported\n");125125- return -EINVAL;126126- }122122+ switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {123123+ case SND_SOC_DAIFMT_CBS_CFS:124124+ if (!iface->mclk) {125125+ dev_err(dai->dev, "cpu clock master: mclk missing\n");126126+ return -ENODEV;127127+ }128128+ break;127129128128- /* If the TDM interface is the clock master, it requires mclk */129129- if (!iface->mclk && (fmt & SND_SOC_DAIFMT_CBS_CFS)) {130130- dev_err(dai->dev, "cpu clock master: mclk missing\n");131131- return -ENODEV;130130+ case SND_SOC_DAIFMT_CBM_CFM:131131+ break;132132+133133+ case SND_SOC_DAIFMT_CBS_CFM:134134+ case SND_SOC_DAIFMT_CBM_CFS:135135+ dev_err(dai->dev, "only CBS_CFS and CBM_CFM are supported\n");136136+ /* Fall-through */137137+ default:138138+ return -EINVAL;132139 }133140134141 iface->fmt = fmt;···326319 if (ret)327320 return ret;328321329329- if (iface->fmt & SND_SOC_DAIFMT_CBS_CFS) {322322+ if ((iface->fmt & SND_SOC_DAIFMT_MASTER_MASK) ==323323+ SND_SOC_DAIFMT_CBS_CFS) {330324 ret = axg_tdm_iface_set_sclk(dai, params);331325 if (ret)332326 return ret;
···9696 return ret;97979898 if (gx_card_cpu_identify(dai_link->cpus, "FIFO"))9999- ret = meson_card_set_fe_link(card, dai_link, np, true);100100- else101101- ret = meson_card_set_be_link(card, dai_link, np);9999+ return meson_card_set_fe_link(card, dai_link, np, true);102100101101+ ret = meson_card_set_be_link(card, dai_link, np);103102 if (ret)104103 return ret;105104106106- /* Check if the cpu is the i2s encoder and parse i2s data */107107- if (gx_card_cpu_identify(dai_link->cpus, "I2S Encoder"))108108- ret = gx_card_parse_i2s(card, np, index);109109-110105 /* Or apply codec to codec params if necessary */111111- else if (gx_card_cpu_identify(dai_link->cpus, "CODEC CTRL")) {106106+ if (gx_card_cpu_identify(dai_link->cpus, "CODEC CTRL")) {112107 dai_link->params = &codec_params;113113- dai_link->no_pcm = 0; /* link is not a DPCM BE */108108+ } else {109109+ dai_link->no_pcm = 1;110110+ snd_soc_dai_link_set_capabilities(dai_link);111111+ /* Check if the cpu is the i2s encoder and parse i2s data */112112+ if (gx_card_cpu_identify(dai_link->cpus, "I2S Encoder"))113113+ ret = gx_card_parse_i2s(card, np, index);114114 }115115116116 return ret;
-4
sound/soc/meson/meson-card-utils.c
···147147 struct device_node *np;148148 int ret, num_codecs;149149150150- link->no_pcm = 1;151151- link->dpcm_playback = 1;152152- link->dpcm_capture = 1;153153-154150 num_codecs = of_get_child_count(node);155151 if (!num_codecs) {156152 dev_err(card->dev, "be link %s has no codec\n",
···400400 struct snd_soc_dai_link_component *codec;401401 struct snd_soc_dai *dai;402402 bool supported[SNDRV_PCM_STREAM_LAST + 1];403403+ bool supported_cpu;404404+ bool supported_codec;403405 int direction;404406 int i;405407406408 for_each_pcm_streams(direction) {407407- supported[direction] = true;409409+ supported_cpu = false;410410+ supported_codec = false;408411409412 for_each_link_cpus(dai_link, i, cpu) {410413 dai = snd_soc_find_dai(cpu);411411- if (!dai || !snd_soc_dai_stream_valid(dai, direction)) {412412- supported[direction] = false;414414+ if (dai && snd_soc_dai_stream_valid(dai, direction)) {415415+ supported_cpu = true;413416 break;414417 }415418 }416416- if (!supported[direction])417417- continue;418419 for_each_link_codecs(dai_link, i, codec) {419420 dai = snd_soc_find_dai(codec);420420- if (!dai || !snd_soc_dai_stream_valid(dai, direction)) {421421- supported[direction] = false;421421+ if (dai && snd_soc_dai_stream_valid(dai, direction)) {422422+ supported_codec = true;422423 break;423424 }424425 }426426+ supported[direction] = supported_cpu && supported_codec;425427 }426428427429 dai_link->dpcm_playback = supported[SNDRV_PCM_STREAM_PLAYBACK];
+24-18
sound/soc/soc-pcm.c
···28022802 if (rtd->dai_link->dpcm_playback) {28032803 stream = SNDRV_PCM_STREAM_PLAYBACK;2804280428052805- for_each_rtd_cpu_dais(rtd, i, cpu_dai)28062806- if (!snd_soc_dai_stream_valid(cpu_dai,28072807- stream)) {28082808- dev_err(rtd->card->dev,28092809- "CPU DAI %s for rtd %s does not support playback\n",28102810- cpu_dai->name,28112811- rtd->dai_link->stream_name);28122812- return -EINVAL;28052805+ for_each_rtd_cpu_dais(rtd, i, cpu_dai) {28062806+ if (snd_soc_dai_stream_valid(cpu_dai, stream)) {28072807+ playback = 1;28082808+ break;28132809 }28142814- playback = 1;28102810+ }28112811+28122812+ if (!playback) {28132813+ dev_err(rtd->card->dev,28142814+ "No CPU DAIs support playback for stream %s\n",28152815+ rtd->dai_link->stream_name);28162816+ return -EINVAL;28172817+ }28152818 }28162819 if (rtd->dai_link->dpcm_capture) {28172820 stream = SNDRV_PCM_STREAM_CAPTURE;2818282128192819- for_each_rtd_cpu_dais(rtd, i, cpu_dai)28202820- if (!snd_soc_dai_stream_valid(cpu_dai,28212821- stream)) {28222822- dev_err(rtd->card->dev,28232823- "CPU DAI %s for rtd %s does not support capture\n",28242824- cpu_dai->name,28252825- rtd->dai_link->stream_name);28262826- return -EINVAL;28222822+ for_each_rtd_cpu_dais(rtd, i, cpu_dai) {28232823+ if (snd_soc_dai_stream_valid(cpu_dai, stream)) {28242824+ capture = 1;28252825+ break;28272826 }28282828- capture = 1;28272827+ }28282828+28292829+ if (!capture) {28302830+ dev_err(rtd->card->dev,28312831+ "No CPU DAIs support capture for stream %s\n",28322832+ rtd->dai_link->stream_name);28332833+ return -EINVAL;28342834+ }28292835 }28302836 } else {28312837 /* Adapt stream for codec2codec links */