mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
ASoC: grace time for DPCM cleanup
Merge series from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>: As we discussed in [1], we don't need to use dpcm_playback/capture flag, so we remove it. But we have been using it for 10 years, some driver might get damage. The most likely case is that the device/driver can use both playback/capture, but have only one flag, and not using xxx_only flag. [1/3] patch indicates warning in such case. These adds grace time for DPCM cleanup. I'm not sure when dpcm_xxx will be removed, and Codec check bypass will be error, but maybe v6.12 or v6.13 ? Please check each driver by that time. Previous patch-set try to check both CPU and Codec in DPCM, but we noticed that there are some special DAI which we can't handle today [2]. So I will escape it in this patch-set. [1] https://lore.kernel.org/r/87edaym2cg.wl-kuninori.morimoto.gx@renesas.com [2] https://lore.kernel.org/all/3e67d62d-fe08-4f55-ab5b-ece8a57154f9@linux.intel.com/ Link: https://lore.kernel.org/r/87edaym2cg.wl-kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/87wmo6dyxg.wl-kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/87msole5wc.wl-kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/871q5tnuok.wl-kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/87bk4oqerx.wl-kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/8734pctmte.wl-kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/87r0ctwzr4.wl-kuninori.morimoto.gx@renesas.com Link: https://lore.kernel.org/r/87cymvlmki.wl-kuninori.morimoto.gx@renesas.com
This commit is contained in:
commit
ca39fab8b7
@ -219,7 +219,6 @@ void snd_soc_dai_resume(struct snd_soc_dai *dai);
|
||||
int snd_soc_dai_compress_new(struct snd_soc_dai *dai,
|
||||
struct snd_soc_pcm_runtime *rtd, int num);
|
||||
bool snd_soc_dai_stream_valid(const struct snd_soc_dai *dai, int stream);
|
||||
void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link);
|
||||
void snd_soc_dai_action(struct snd_soc_dai *dai,
|
||||
int stream, int action);
|
||||
static inline void snd_soc_dai_activate(struct snd_soc_dai *dai,
|
||||
|
@ -815,6 +815,7 @@ struct snd_soc_dai_link {
|
||||
/* This DAI link can route to other DAI links at runtime (Frontend)*/
|
||||
unsigned int dynamic:1;
|
||||
|
||||
/* REMOVE ME */
|
||||
/* DPCM capture and Playback support */
|
||||
unsigned int dpcm_capture:1;
|
||||
unsigned int dpcm_playback:1;
|
||||
|
@ -650,9 +650,6 @@ static int imx_card_parse_of(struct imx_card_data *data)
|
||||
link->ops = &imx_aif_ops;
|
||||
}
|
||||
|
||||
if (link->no_pcm || link->dynamic)
|
||||
snd_soc_dai_link_set_capabilities(link);
|
||||
|
||||
/* Get dai fmt */
|
||||
ret = simple_util_parse_daifmt(dev, np, codec,
|
||||
NULL, &link->dai_fmt);
|
||||
|
@ -279,8 +279,6 @@ static int graph_dai_link_of_dpcm(struct simple_util_priv *priv,
|
||||
|
||||
graph_parse_convert(dev, ep, &dai_props->adata);
|
||||
|
||||
snd_soc_dai_link_set_capabilities(dai_link);
|
||||
|
||||
ret = graph_link_init(priv, cpu_ep, codec_ep, li, dai_name);
|
||||
|
||||
li->link++;
|
||||
|
@ -966,8 +966,6 @@ int audio_graph2_link_dpcm(struct simple_util_priv *priv,
|
||||
graph_parse_convert(ep, dai_props); /* at node of <dpcm> */
|
||||
graph_parse_convert(rep, dai_props); /* at node of <CPU/Codec> */
|
||||
|
||||
snd_soc_dai_link_set_capabilities(dai_link);
|
||||
|
||||
graph_link_init(priv, lnk, cpu_port, codec_port, li, is_cpu);
|
||||
err:
|
||||
of_node_put(ep);
|
||||
|
@ -291,8 +291,6 @@ static int simple_dai_link_of_dpcm(struct simple_util_priv *priv,
|
||||
|
||||
simple_parse_convert(dev, np, &dai_props->adata);
|
||||
|
||||
snd_soc_dai_link_set_capabilities(dai_link);
|
||||
|
||||
ret = simple_link_init(priv, np, codec, li, prefix, dai_name);
|
||||
|
||||
out_put_node:
|
||||
|
@ -132,7 +132,7 @@ static int axg_card_add_tdm_loopback(struct snd_soc_card *card,
|
||||
lb->stream_name = lb->name;
|
||||
lb->cpus->of_node = pad->cpus->of_node;
|
||||
lb->cpus->dai_name = "TDM Loopback";
|
||||
lb->dpcm_capture = 1;
|
||||
lb->capture_only = 1;
|
||||
lb->no_pcm = 1;
|
||||
lb->ops = &axg_card_tdm_be_ops;
|
||||
lb->init = axg_card_tdm_dai_lb_init;
|
||||
@ -176,7 +176,7 @@ static int axg_card_parse_cpu_tdm_slots(struct snd_soc_card *card,
|
||||
|
||||
/* Disable playback is the interface has no tx slots */
|
||||
if (!tx)
|
||||
link->dpcm_playback = 0;
|
||||
link->capture_only = 1;
|
||||
|
||||
for (i = 0, rx = 0; i < AXG_TDM_NUM_LANES; i++) {
|
||||
snprintf(propname, 32, "dai-tdm-slot-rx-mask-%d", i);
|
||||
@ -186,9 +186,9 @@ static int axg_card_parse_cpu_tdm_slots(struct snd_soc_card *card,
|
||||
|
||||
/* Disable capture is the interface has no rx slots */
|
||||
if (!rx)
|
||||
link->dpcm_capture = 0;
|
||||
link->playback_only = 1;
|
||||
|
||||
/* ... but the interface should at least have one of them */
|
||||
/* ... but the interface should at least have one direction */
|
||||
if (!tx && !rx) {
|
||||
dev_err(card->dev, "tdm link has no cpu slots\n");
|
||||
return -EINVAL;
|
||||
@ -275,7 +275,7 @@ static int axg_card_parse_tdm(struct snd_soc_card *card,
|
||||
return ret;
|
||||
|
||||
/* Add loopback if the pad dai has playback */
|
||||
if (link->dpcm_playback) {
|
||||
if (!link->capture_only) {
|
||||
ret = axg_card_add_tdm_loopback(card, index);
|
||||
if (ret)
|
||||
return ret;
|
||||
@ -339,7 +339,6 @@ static int axg_card_add_link(struct snd_soc_card *card, struct device_node *np,
|
||||
dai_link->num_c2c_params = 1;
|
||||
} else {
|
||||
dai_link->no_pcm = 1;
|
||||
snd_soc_dai_link_set_capabilities(dai_link);
|
||||
if (axg_card_cpu_is_tdm_iface(dai_link->cpus->of_node))
|
||||
ret = axg_card_parse_tdm(card, np, index);
|
||||
}
|
||||
|
@ -107,7 +107,6 @@ static int gx_card_add_link(struct snd_soc_card *card, struct device_node *np,
|
||||
dai_link->num_c2c_params = 1;
|
||||
} else {
|
||||
dai_link->no_pcm = 1;
|
||||
snd_soc_dai_link_set_capabilities(dai_link);
|
||||
/* Check if the cpu is the i2s encoder and parse i2s data */
|
||||
if (gx_card_cpu_identify(dai_link->cpus, "I2S Encoder"))
|
||||
ret = gx_card_parse_i2s(card, np, index);
|
||||
|
@ -186,9 +186,9 @@ int meson_card_set_fe_link(struct snd_soc_card *card,
|
||||
link->dpcm_merged_rate = 1;
|
||||
|
||||
if (is_playback)
|
||||
link->dpcm_playback = 1;
|
||||
link->playback_only = 1;
|
||||
else
|
||||
link->dpcm_capture = 1;
|
||||
link->capture_only = 1;
|
||||
|
||||
return meson_card_set_link_name(card, link, node, "fe");
|
||||
}
|
||||
|
@ -155,7 +155,6 @@ int qcom_snd_parse_of(struct snd_soc_card *card)
|
||||
|
||||
if (platform || !codec) {
|
||||
/* DPCM */
|
||||
snd_soc_dai_link_set_capabilities(link);
|
||||
link->ignore_suspend = 1;
|
||||
link->nonatomic = 1;
|
||||
}
|
||||
|
@ -950,8 +950,8 @@ void asoc_sdw_init_dai_link(struct device *dev, struct snd_soc_dai_link *dai_lin
|
||||
dai_links->num_cpus = cpus_num;
|
||||
dai_links->codecs = codecs;
|
||||
dai_links->num_codecs = codecs_num;
|
||||
dai_links->dpcm_playback = playback;
|
||||
dai_links->dpcm_capture = capture;
|
||||
dai_links->playback_only = playback && !capture;
|
||||
dai_links->capture_only = !playback && capture;
|
||||
dai_links->init = init;
|
||||
dai_links->ops = ops;
|
||||
}
|
||||
|
@ -479,44 +479,6 @@ bool snd_soc_dai_stream_valid(const struct snd_soc_dai *dai, int dir)
|
||||
return stream->channels_min;
|
||||
}
|
||||
|
||||
/*
|
||||
* snd_soc_dai_link_set_capabilities() - set dai_link properties based on its DAIs
|
||||
*/
|
||||
void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link *dai_link)
|
||||
{
|
||||
bool supported[SNDRV_PCM_STREAM_LAST + 1];
|
||||
int direction;
|
||||
|
||||
for_each_pcm_streams(direction) {
|
||||
struct snd_soc_dai_link_component *cpu;
|
||||
struct snd_soc_dai_link_component *codec;
|
||||
struct snd_soc_dai *dai;
|
||||
bool supported_cpu = false;
|
||||
bool supported_codec = false;
|
||||
int i;
|
||||
|
||||
for_each_link_cpus(dai_link, i, cpu) {
|
||||
dai = snd_soc_find_dai_with_mutex(cpu);
|
||||
if (dai && snd_soc_dai_stream_valid(dai, direction)) {
|
||||
supported_cpu = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for_each_link_codecs(dai_link, i, codec) {
|
||||
dai = snd_soc_find_dai_with_mutex(codec);
|
||||
if (dai && snd_soc_dai_stream_valid(dai, direction)) {
|
||||
supported_codec = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
supported[direction] = supported_cpu && supported_codec;
|
||||
}
|
||||
|
||||
dai_link->dpcm_playback = supported[SNDRV_PCM_STREAM_PLAYBACK];
|
||||
dai_link->dpcm_capture = supported[SNDRV_PCM_STREAM_CAPTURE];
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_soc_dai_link_set_capabilities);
|
||||
|
||||
void snd_soc_dai_action(struct snd_soc_dai *dai,
|
||||
int stream, int action)
|
||||
{
|
||||
|
@ -2739,6 +2739,7 @@ static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd,
|
||||
{
|
||||
struct snd_soc_dai_link *dai_link = rtd->dai_link;
|
||||
struct snd_soc_dai *cpu_dai;
|
||||
struct snd_soc_dai_link_ch_map *ch_maps;
|
||||
int has_playback = 0;
|
||||
int has_capture = 0;
|
||||
int i;
|
||||
@ -2749,43 +2750,51 @@ static int soc_get_playback_capture(struct snd_soc_pcm_runtime *rtd,
|
||||
}
|
||||
|
||||
if (dai_link->dynamic || dai_link->no_pcm) {
|
||||
int stream;
|
||||
|
||||
if (dai_link->dpcm_playback) {
|
||||
stream = SNDRV_PCM_STREAM_PLAYBACK;
|
||||
for_each_rtd_ch_maps(rtd, i, ch_maps) {
|
||||
cpu_dai = snd_soc_rtd_to_cpu(rtd, ch_maps->cpu);
|
||||
|
||||
for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
|
||||
if (snd_soc_dai_stream_valid(cpu_dai, stream)) {
|
||||
has_playback = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has_playback) {
|
||||
dev_err(rtd->card->dev,
|
||||
"No CPU DAIs support playback for stream %s\n",
|
||||
dai_link->stream_name);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK))
|
||||
has_playback = 1;
|
||||
|
||||
if (snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE))
|
||||
has_capture = 1;
|
||||
}
|
||||
if (dai_link->dpcm_capture) {
|
||||
stream = SNDRV_PCM_STREAM_CAPTURE;
|
||||
|
||||
for_each_rtd_cpu_dais(rtd, i, cpu_dai) {
|
||||
if (snd_soc_dai_stream_valid(cpu_dai, stream)) {
|
||||
has_capture = 1;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* REMOVE ME
|
||||
*
|
||||
* dpcm_xxx flag will be removed soon, Indicates warning if dpcm_xxx flag was used
|
||||
* as availability limitation
|
||||
*/
|
||||
if (has_playback && has_capture) {
|
||||
if ( dai_link->dpcm_playback &&
|
||||
!dai_link->dpcm_capture &&
|
||||
!dai_link->playback_only) {
|
||||
dev_warn(rtd->card->dev,
|
||||
"both playback/capture are available,"
|
||||
" but not using playback_only flag (%s)\n",
|
||||
dai_link->stream_name);
|
||||
dev_warn(rtd->card->dev,
|
||||
"dpcm_playback/capture are no longer needed,"
|
||||
" please use playback/capture_only instead\n");
|
||||
has_capture = 0;
|
||||
}
|
||||
|
||||
if (!has_capture) {
|
||||
dev_err(rtd->card->dev,
|
||||
"No CPU DAIs support capture for stream %s\n",
|
||||
dai_link->stream_name);
|
||||
return -EINVAL;
|
||||
if (!dai_link->dpcm_playback &&
|
||||
dai_link->dpcm_capture &&
|
||||
!dai_link->capture_only) {
|
||||
dev_warn(rtd->card->dev,
|
||||
"both playback/capture are available,"
|
||||
" but not using capture_only flag (%s)\n",
|
||||
dai_link->stream_name);
|
||||
dev_warn(rtd->card->dev,
|
||||
"dpcm_playback/capture are no longer needed,"
|
||||
" please use playback/capture_only instead\n");
|
||||
has_playback = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
struct snd_soc_dai_link_ch_map *ch_maps;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
|
||||
/* Adapt stream for codec2codec links */
|
||||
|
Loading…
Reference in New Issue
Block a user