diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2017-10-11 01:38:29 +0000 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-10-23 11:38:59 +0200 |
commit | 273d778ef38a8861f880e9df5799029dc82bd55d (patch) | |
tree | fa55ea50808e9515c9c2cb6cfc73b7575bfa438e /sound/soc/soc-core.c | |
parent | fbb16563c6c2b7fc4944adc49f93c1dc6fe25770 (diff) | |
download | linux-273d778ef38a8861f880e9df5799029dc82bd55d.tar.gz linux-273d778ef38a8861f880e9df5799029dc82bd55d.tar.xz |
ASoC: snd_soc_component_driver has endianness
Codec will be replaced into Component, then Codec side only
needs to call fixup_codec_formats() at this point.
This patch adds new endianness flag on Component driver
and call convert_endianness_formats() (= was fixup_codec_format())
if endianness was true.
When Codec is replaced into Component, Codec driver needs
to have endianness = 1 flags.
Existing CPU side of course doesn't have this flag, thus CPU doesn't
call it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r-- | sound/soc/soc-core.c | 80 |
1 files changed, 45 insertions, 35 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a3dcf14befd8..61c3d3649914 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3404,6 +3404,41 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component) list_del(&component->list); } +#define ENDIANNESS_MAP(name) \ + (SNDRV_PCM_FMTBIT_##name##LE | SNDRV_PCM_FMTBIT_##name##BE) +static u64 endianness_format_map[] = { + ENDIANNESS_MAP(S16_), + ENDIANNESS_MAP(U16_), + ENDIANNESS_MAP(S24_), + ENDIANNESS_MAP(U24_), + ENDIANNESS_MAP(S32_), + ENDIANNESS_MAP(U32_), + ENDIANNESS_MAP(S24_3), + ENDIANNESS_MAP(U24_3), + ENDIANNESS_MAP(S20_3), + ENDIANNESS_MAP(U20_3), + ENDIANNESS_MAP(S18_3), + ENDIANNESS_MAP(U18_3), + ENDIANNESS_MAP(FLOAT_), + ENDIANNESS_MAP(FLOAT64_), + ENDIANNESS_MAP(IEC958_SUBFRAME_), +}; + +/* + * Fix up the DAI formats for endianness: codecs don't actually see + * the endianness of the data but we're using the CPU format + * definitions which do need to include endianness so we ensure that + * codec DAIs always have both big and little endian variants set. + */ +static void convert_endianness_formats(struct snd_soc_pcm_stream *stream) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(endianness_format_map); i++) + if (stream->formats & endianness_format_map[i]) + stream->formats |= endianness_format_map[i]; +} + int snd_soc_add_component(struct device *dev, struct snd_soc_component *component, const struct snd_soc_component_driver *component_driver, @@ -3411,6 +3446,7 @@ int snd_soc_add_component(struct device *dev, int num_dai) { int ret; + int i; ret = snd_soc_component_initialize(component, component_driver, dev); if (ret) @@ -3419,6 +3455,13 @@ int snd_soc_add_component(struct device *dev, component->ignore_pmdown_time = true; component->registered_as_component = true; + if (component_driver->endianness) { + for (i = 0; i < num_dai; i++) { + convert_endianness_formats(&dai_drv[i].playback); + convert_endianness_formats(&dai_drv[i].capture); + } + } + ret = snd_soc_register_dais(component, dai_drv, num_dai, true); if (ret < 0) { dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret); @@ -3675,39 +3718,6 @@ void snd_soc_unregister_platform(struct device *dev) } EXPORT_SYMBOL_GPL(snd_soc_unregister_platform); -static u64 codec_format_map[] = { - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE, - SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE, - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE, - SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE, - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE, - SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE, - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3BE, - SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_U24_3BE, - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE, - SNDRV_PCM_FMTBIT_U20_3LE | SNDRV_PCM_FMTBIT_U20_3BE, - SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE, - SNDRV_PCM_FMTBIT_U18_3LE | SNDRV_PCM_FMTBIT_U18_3BE, - SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE, - SNDRV_PCM_FMTBIT_FLOAT64_LE | SNDRV_PCM_FMTBIT_FLOAT64_BE, - SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE - | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE, -}; - -/* Fix up the DAI formats for endianness: codecs don't actually see - * the endianness of the data but we're using the CPU format - * definitions which do need to include endianness so we ensure that - * codec DAIs always have both big and little endian variants set. - */ -static void fixup_codec_formats(struct snd_soc_pcm_stream *stream) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(codec_format_map); i++) - if (stream->formats & codec_format_map[i]) - stream->formats |= codec_format_map[i]; -} - static int snd_soc_codec_drv_probe(struct snd_soc_component *component) { struct snd_soc_codec *codec = snd_soc_component_to_codec(component); @@ -3858,8 +3868,8 @@ int snd_soc_register_codec(struct device *dev, codec->component.regmap = codec_drv->get_regmap(dev); for (i = 0; i < num_dai; i++) { - fixup_codec_formats(&dai_drv[i].playback); - fixup_codec_formats(&dai_drv[i].capture); + convert_endianness_formats(&dai_drv[i].playback); + convert_endianness_formats(&dai_drv[i].capture); } ret = snd_soc_register_dais(&codec->component, dai_drv, num_dai, false); |