[alsa-devel] [PATCH 0/3] ASoC: DPCM can care FE/BE merged format
Hi Mark
These patches add new .dpcm_merged_foramt to merge FE/BE formats. It will be no sound if DPCM were below style, and user selects S24_LE.
FE: S16_LE/S24_LE BE: S16_LE
DPCM will selects FE/BE merged formats (= S16_LE here) if FE has .dpcm_merged_foramt.
Kuninori Morimoto (3): ASoC: soc.h: tidyup struct snd_soc_dai_link definition order ASoC: soc-pcm: DPCM cares BE format ASoC: rsnd: rsrc-card uses FE/BE merged format when DPCM
include/sound/soc.h | 39 +++++++++++++++++++++------------------ sound/soc/sh/rcar/rsrc-card.c | 1 + sound/soc/soc-pcm.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 64 insertions(+), 23 deletions(-)
Best regards --- Kuninori Morimoto
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current struct snd_soc_dai_link has many members, but definition order was random. Especially, bool / bit field are defined randomly. This patch tidyups these definition order to calculate data alignment easy.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index f6226914..183cbb7 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -961,6 +961,24 @@ struct snd_soc_dai_link {
enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */
+ /* codec/machine specific init - e.g. add machine controls */ + int (*init)(struct snd_soc_pcm_runtime *rtd); + + /* optional hw_params re-writing for BE and FE sync */ + int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params); + + /* machine stream operations */ + const struct snd_soc_ops *ops; + const struct snd_soc_compr_ops *compr_ops; + + /* For unidirectional dai links */ + bool playback_only; + bool capture_only; + + /* Mark this pcm with non atomic ops */ + bool nonatomic; + /* Keep DAI active over suspend */ unsigned int ignore_suspend:1;
@@ -969,9 +987,6 @@ struct snd_soc_dai_link { unsigned int symmetric_channels:1; unsigned int symmetric_samplebits:1;
- /* Mark this pcm with non atomic ops */ - bool nonatomic; - /* Do not create a PCM for this DAI link (Backend link) */ unsigned int no_pcm:1;
@@ -984,21 +999,6 @@ struct snd_soc_dai_link {
/* pmdown_time is ignored at stop */ unsigned int ignore_pmdown_time:1; - - /* codec/machine specific init - e.g. add machine controls */ - int (*init)(struct snd_soc_pcm_runtime *rtd); - - /* optional hw_params re-writing for BE and FE sync */ - int (*be_hw_params_fixup)(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params); - - /* machine stream operations */ - const struct snd_soc_ops *ops; - const struct snd_soc_compr_ops *compr_ops; - - /* For unidirectional dai links */ - bool playback_only; - bool capture_only; };
struct snd_soc_codec_conf {
On Tue, Apr 21, 2015 at 07:02:34AM +0000, Kuninori Morimoto wrote:
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current struct snd_soc_dai_link has many members, but definition order was random. Especially, bool / bit field are defined randomly. This patch tidyups these definition order to calculate data alignment easy.
Applied, thanks.
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Current DPCM is caring only FE format. but it will be no sound if FE/BE was below style, and user selects S24_LE format.
FE: S16_LE/S24_LE BE: S16_LE
DPCM can rewrite the format, so basically we don't want to constrain with the BE constraints. But sometimes it will be trouble. This patch adds new .dpcm_merged_foramt on struct snd_soc_dai_link. DPCM will use FE / BE merged format if .struct snd_soc_dai_link was set.
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- include/sound/soc.h | 3 +++ sound/soc/soc-pcm.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 45 insertions(+), 5 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h index 183cbb7..4774dfd 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -997,6 +997,9 @@ struct snd_soc_dai_link { unsigned int dpcm_capture:1; unsigned int dpcm_playback:1;
+ /* DPCM used FE & BE merged format */ + unsigned int dpcm_merged_foramt:1; + /* pmdown_time is ignored at stop */ unsigned int ignore_pmdown_time:1; }; diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 35fe58f4..4179563 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -1485,30 +1485,67 @@ unwind: }
static void dpcm_init_runtime_hw(struct snd_pcm_runtime *runtime, - struct snd_soc_pcm_stream *stream) + struct snd_soc_pcm_stream *stream, + u64 formats) { runtime->hw.rate_min = stream->rate_min; runtime->hw.rate_max = stream->rate_max; runtime->hw.channels_min = stream->channels_min; runtime->hw.channels_max = stream->channels_max; if (runtime->hw.formats) - runtime->hw.formats &= stream->formats; + runtime->hw.formats &= formats & stream->formats; else - runtime->hw.formats = stream->formats; + runtime->hw.formats = formats & stream->formats; runtime->hw.rates = stream->rates; }
+static u64 dpcm_runtime_base_foramt(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *fe = substream->private_data; + struct snd_soc_dpcm *dpcm; + u64 formats = ULLONG_MAX; + int stream = substream->stream; + + if (!fe->dai_link->dpcm_merged_foramt) + return formats; + + /* + * It returns merged BE codec format + * if FE want to use it (= dpcm_merged_foramt) + */ + + list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { + struct snd_soc_pcm_runtime *be = dpcm->be; + struct snd_soc_dai_driver *codec_dai_drv; + struct snd_soc_pcm_stream *codec_stream; + int i; + + for (i = 0; i < be->num_codecs; i++) { + codec_dai_drv = be->codec_dais[i]->driver; + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + codec_stream = &codec_dai_drv->playback; + else + codec_stream = &codec_dai_drv->capture; + + formats &= codec_stream->formats; + } + } + + return formats; +} + static void dpcm_set_fe_runtime(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; struct snd_soc_dai_driver *cpu_dai_drv = cpu_dai->driver; + u64 format = dpcm_runtime_base_foramt(substream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback); + dpcm_init_runtime_hw(runtime, &cpu_dai_drv->playback, format); else - dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture); + dpcm_init_runtime_hw(runtime, &cpu_dai_drv->capture, format); }
static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd);
From: Kuninori Morimoto kuninori.morimoto.gx@renesas.com
Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/sh/rcar/rsrc-card.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/soc/sh/rcar/rsrc-card.c b/sound/soc/sh/rcar/rsrc-card.c index a68517a..86f14cd 100644 --- a/sound/soc/sh/rcar/rsrc-card.c +++ b/sound/soc/sh/rcar/rsrc-card.c @@ -232,6 +232,7 @@ rsrc_card_sub_parse_of(struct rsrc_card_priv *priv, if (args_count) { *args_count = args.args_count; dai_link->dynamic = 1; + dai_link->dpcm_merged_foramt = 1; } else { dai_link->no_pcm = 1; priv->codec_conf.of_node = (*p_node);
At Tue, 21 Apr 2015 07:01:56 +0000, Kuninori Morimoto wrote:
Hi Mark
These patches add new .dpcm_merged_foramt to merge FE/BE formats. It will be no sound if DPCM were below style, and user selects S24_LE.
FE: S16_LE/S24_LE BE: S16_LE
DPCM will selects FE/BE merged formats (= S16_LE here) if FE has .dpcm_merged_foramt.
Conceptually, you need to refine all FE hw_params with BE's, not only formats.
Takashi
Hi Takashi-san
Thank you for your feedback
These patches add new .dpcm_merged_foramt to merge FE/BE formats. It will be no sound if DPCM were below style, and user selects S24_LE.
FE: S16_LE/S24_LE BE: S16_LE
DPCM will selects FE/BE merged formats (= S16_LE here) if FE has .dpcm_merged_foramt.
Conceptually, you need to refine all FE hw_params with BE's, not only formats.
Hmm... I think DPCM can rewrite all .hw_params, and basically it don't want to constrain with the BE constraints. So, I thought we can have below for each purpose ?
.dpcm_merged_foramt .dpcm_merged_rate .dpcm_merged_chan
Maybe I'm misunderstanding, but if this feature refines above all hw_params, it will conflicts with .be_hw_params_fixup ?
Best regards --- Kuninori Morimoto
At Tue, 21 Apr 2015 08:15:27 +0000, Kuninori Morimoto wrote:
Hi Takashi-san
Thank you for your feedback
These patches add new .dpcm_merged_foramt to merge FE/BE formats. It will be no sound if DPCM were below style, and user selects S24_LE.
FE: S16_LE/S24_LE BE: S16_LE
DPCM will selects FE/BE merged formats (= S16_LE here) if FE has .dpcm_merged_foramt.
Conceptually, you need to refine all FE hw_params with BE's, not only formats.
Hmm... I think DPCM can rewrite all .hw_params, and basically it don't want to constrain with the BE constraints.
There are indeed cases where a BE takes incompatible hw configuration, which needs be_hw_params_fixup. But, in general, the FE's hw_params is just copied to BE. That is, we assume here blindly that FE's configuration is compatible with BE's. And, now this assumption isn't true in rcar's case, so we face the issue.
So, I thought we can have below for each purpose ?
.dpcm_merged_foramt .dpcm_merged_rate .dpcm_merged_chan
Better to have bit flags.
Maybe I'm misunderstanding, but if this feature refines above all hw_params, it will conflicts with .be_hw_params_fixup ?
Yeah, there it'll need to clear the flag.
thanks,
Takashi
On Tue, Apr 21, 2015 at 10:51:26AM +0200, Takashi Iwai wrote:
There are indeed cases where a BE takes incompatible hw configuration, which needs be_hw_params_fixup. But, in general, the FE's hw_params is just copied to BE. That is, we assume here blindly that FE's configuration is compatible with BE's. And, now this assumption isn't true in rcar's case, so we face the issue.
Well, it's as much that we're assuming there's rewriting going on which handles things - in many of these systems everything will be going through a DSP which rewrites everything on the way.
Hi Takashi, Mark
Thank you for your feedback
.dpcm_merged_foramt .dpcm_merged_rate .dpcm_merged_chan
Better to have bit flags.
Maybe I'm misunderstanding, but if this feature refines above all hw_params, it will conflicts with .be_hw_params_fixup ?
Yeah, there it'll need to clear the flag.
.dpcm_merged_foramt is using bit field, like this
unsigned int dpcm_merged_foramt:1;
I think we don't need flag control, but should I ? (many other options are same style in struct snd_soc_dai_link)
There are indeed cases where a BE takes incompatible hw configuration, which needs be_hw_params_fixup. But, in general, the FE's hw_params is just copied to BE. That is, we assume here blindly that FE's configuration is compatible with BE's. And, now this assumption isn't true in rcar's case, so we face the issue.
Well, it's as much that we're assuming there's rewriting going on which handles things - in many of these systems everything will be going through a DSP which rewrites everything on the way.
I guess we can use .be_hw_params_fixup if it is "special rewrite" (ex 48kHz -> 44.1kHz, 8ch -> 2ch etc...). But like this case (= it needs rewrite but normally we assume it) using general method is useful.
I'm happy to create/send v2 patch, but, it will be "flag" fixup ?
On Wed, Apr 22, 2015 at 12:13:31AM +0000, Kuninori Morimoto wrote:
Maybe I'm misunderstanding, but if this feature refines above all hw_params, it will conflicts with .be_hw_params_fixup ?
Yeah, there it'll need to clear the flag.
.dpcm_merged_foramt is using bit field, like this
unsigned int dpcm_merged_foramt:1;
Note that you've misspelt this - should be "format".
I think we don't need flag control, but should I ? (many other options are same style in struct snd_soc_dai_link)
Not quite sure what "flag control" is here, sorry?
There are indeed cases where a BE takes incompatible hw configuration, which needs be_hw_params_fixup. But, in general, the FE's hw_params is just copied to BE. That is, we assume here blindly that FE's configuration is compatible with BE's. And, now this assumption isn't true in rcar's case, so we face the issue.
Well, it's as much that we're assuming there's rewriting going on which handles things - in many of these systems everything will be going through a DSP which rewrites everything on the way.
I guess we can use .be_hw_params_fixup if it is "special rewrite" (ex 48kHz -> 44.1kHz, 8ch -> 2ch etc...). But like this case (= it needs rewrite but normally we assume it) using general method is useful.
I'm happy to create/send v2 patch, but, it will be "flag" fixup ?
I'm having a bit of a hard time following, sorry. If what you're saying here is that if we have a fixup method we should by default assume that only the front end constraints are relevant and ignore the back end then that does actually seem reasonable.
Hi Mark
unsigned int dpcm_merged_foramt:1;
Note that you've misspelt this - should be "format".
Ahh.. will fix in v2
I think we don't need flag control, but should I ? (many other options are same style in struct snd_soc_dai_link)
Not quite sure what "flag control" is here, sorry?
Sorry for my confusable words. Takashi mentioned
> .dpcm_merged_foramt > .dpcm_merged_rate > .dpcm_merged_chan
Better to have bit flags.
I guess Takashi means like this
u32 xxx_flags #define DPCM_xxxx_FORMAT (1 << 0) #define DPCM_xxxx_RATE (1 << 1) #define DPCM_xxxx_CHAN (1 << 2)
But, this .dpcm_merged_xxx is defined as
unsigned int dpcm_merged_foramt:1;
"flag control" here means #defined DPCM_xxxx_CHAN flag, and I think we don't need it.
There are indeed cases where a BE takes incompatible hw configuration, which needs be_hw_params_fixup. But, in general, the FE's hw_params is just copied to BE. That is, we assume here blindly that FE's configuration is compatible with BE's. And, now this assumption isn't true in rcar's case, so we face the issue.
Well, it's as much that we're assuming there's rewriting going on which handles things - in many of these systems everything will be going through a DSP which rewrites everything on the way.
I guess we can use .be_hw_params_fixup if it is "special rewrite" (ex 48kHz -> 44.1kHz, 8ch -> 2ch etc...). But like this case (= it needs rewrite but normally we assume it) using general method is useful.
I'm happy to create/send v2 patch, but, it will be "flag" fixup ?
I'm having a bit of a hard time following, sorry. If what you're saying here is that if we have a fixup method we should by default assume that only the front end constraints are relevant and ignore the back end then that does actually seem reasonable.
Yes it is !!
Best regards --- Kuninori Morimoto
On Mon, May 11, 2015 at 04:14:47AM +0000, Kuninori Morimoto wrote:
Not quite sure what "flag control" is here, sorry?
Sorry for my confusable words. Takashi mentioned
.dpcm_merged_foramt .dpcm_merged_rate .dpcm_merged_chan
Better to have bit flags.
I guess Takashi means like this
u32 xxx_flags #define DPCM_xxxx_FORMAT (1 << 0) #define DPCM_xxxx_RATE (1 << 1) #define DPCM_xxxx_CHAN (1 << 2)
But, this .dpcm_merged_xxx is defined as
unsigned int dpcm_merged_foramt:1;
"flag control" here means #defined DPCM_xxxx_CHAN flag, and I think we don't need it.
OK, right. Yes, we can probably live without.
participants (3)
-
Kuninori Morimoto
-
Mark Brown
-
Takashi Iwai