ASoC: snd_soc_component_driver has endianness
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Wed, 11 Oct 2017 01:38:29 +0000 (01:38 +0000)
committerMark Brown <broonie@kernel.org>
Mon, 23 Oct 2017 09:38:59 +0000 (11:38 +0200)
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>
include/sound/soc.h
sound/soc/soc-core.c

index 44fab95..747d080 100644 (file)
@@ -837,6 +837,7 @@ struct snd_soc_component_driver {
        unsigned int idle_bias_on:1;
        unsigned int suspend_bias_off:1;
        unsigned int pmdown_time:1; /* care pmdown_time at stop */
+       unsigned int endianness:1;
 };
 
 struct snd_soc_component {
index a3dcf14..61c3d36 100644 (file)
@@ -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);