diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2017-10-10 21:38:29 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2017-10-23 05:38:59 -0400 |
commit | 273d778ef38a8861f880e9df5799029dc82bd55d (patch) | |
tree | fa55ea50808e9515c9c2cb6cfc73b7575bfa438e | |
parent | fbb16563c6c2b7fc4944adc49f93c1dc6fe25770 (diff) |
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>
-rw-r--r-- | include/sound/soc.h | 1 | ||||
-rw-r--r-- | sound/soc/soc-core.c | 80 |
2 files changed, 46 insertions, 35 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h index 44fab951b686..747d080a0853 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h | |||
@@ -837,6 +837,7 @@ struct snd_soc_component_driver { | |||
837 | unsigned int idle_bias_on:1; | 837 | unsigned int idle_bias_on:1; |
838 | unsigned int suspend_bias_off:1; | 838 | unsigned int suspend_bias_off:1; |
839 | unsigned int pmdown_time:1; /* care pmdown_time at stop */ | 839 | unsigned int pmdown_time:1; /* care pmdown_time at stop */ |
840 | unsigned int endianness:1; | ||
840 | }; | 841 | }; |
841 | 842 | ||
842 | struct snd_soc_component { | 843 | struct snd_soc_component { |
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) | |||
3404 | list_del(&component->list); | 3404 | list_del(&component->list); |
3405 | } | 3405 | } |
3406 | 3406 | ||
3407 | #define ENDIANNESS_MAP(name) \ | ||
3408 | (SNDRV_PCM_FMTBIT_##name##LE | SNDRV_PCM_FMTBIT_##name##BE) | ||
3409 | static u64 endianness_format_map[] = { | ||
3410 | ENDIANNESS_MAP(S16_), | ||
3411 | ENDIANNESS_MAP(U16_), | ||
3412 | ENDIANNESS_MAP(S24_), | ||
3413 | ENDIANNESS_MAP(U24_), | ||
3414 | ENDIANNESS_MAP(S32_), | ||
3415 | ENDIANNESS_MAP(U32_), | ||
3416 | ENDIANNESS_MAP(S24_3), | ||
3417 | ENDIANNESS_MAP(U24_3), | ||
3418 | ENDIANNESS_MAP(S20_3), | ||
3419 | ENDIANNESS_MAP(U20_3), | ||
3420 | ENDIANNESS_MAP(S18_3), | ||
3421 | ENDIANNESS_MAP(U18_3), | ||
3422 | ENDIANNESS_MAP(FLOAT_), | ||
3423 | ENDIANNESS_MAP(FLOAT64_), | ||
3424 | ENDIANNESS_MAP(IEC958_SUBFRAME_), | ||
3425 | }; | ||
3426 | |||
3427 | /* | ||
3428 | * Fix up the DAI formats for endianness: codecs don't actually see | ||
3429 | * the endianness of the data but we're using the CPU format | ||
3430 | * definitions which do need to include endianness so we ensure that | ||
3431 | * codec DAIs always have both big and little endian variants set. | ||
3432 | */ | ||
3433 | static void convert_endianness_formats(struct snd_soc_pcm_stream *stream) | ||
3434 | { | ||
3435 | int i; | ||
3436 | |||
3437 | for (i = 0; i < ARRAY_SIZE(endianness_format_map); i++) | ||
3438 | if (stream->formats & endianness_format_map[i]) | ||
3439 | stream->formats |= endianness_format_map[i]; | ||
3440 | } | ||
3441 | |||
3407 | int snd_soc_add_component(struct device *dev, | 3442 | int snd_soc_add_component(struct device *dev, |
3408 | struct snd_soc_component *component, | 3443 | struct snd_soc_component *component, |
3409 | const struct snd_soc_component_driver *component_driver, | 3444 | const struct snd_soc_component_driver *component_driver, |
@@ -3411,6 +3446,7 @@ int snd_soc_add_component(struct device *dev, | |||
3411 | int num_dai) | 3446 | int num_dai) |
3412 | { | 3447 | { |
3413 | int ret; | 3448 | int ret; |
3449 | int i; | ||
3414 | 3450 | ||
3415 | ret = snd_soc_component_initialize(component, component_driver, dev); | 3451 | ret = snd_soc_component_initialize(component, component_driver, dev); |
3416 | if (ret) | 3452 | if (ret) |
@@ -3419,6 +3455,13 @@ int snd_soc_add_component(struct device *dev, | |||
3419 | component->ignore_pmdown_time = true; | 3455 | component->ignore_pmdown_time = true; |
3420 | component->registered_as_component = true; | 3456 | component->registered_as_component = true; |
3421 | 3457 | ||
3458 | if (component_driver->endianness) { | ||
3459 | for (i = 0; i < num_dai; i++) { | ||
3460 | convert_endianness_formats(&dai_drv[i].playback); | ||
3461 | convert_endianness_formats(&dai_drv[i].capture); | ||
3462 | } | ||
3463 | } | ||
3464 | |||
3422 | ret = snd_soc_register_dais(component, dai_drv, num_dai, true); | 3465 | ret = snd_soc_register_dais(component, dai_drv, num_dai, true); |
3423 | if (ret < 0) { | 3466 | if (ret < 0) { |
3424 | dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret); | 3467 | dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret); |
@@ -3675,39 +3718,6 @@ void snd_soc_unregister_platform(struct device *dev) | |||
3675 | } | 3718 | } |
3676 | EXPORT_SYMBOL_GPL(snd_soc_unregister_platform); | 3719 | EXPORT_SYMBOL_GPL(snd_soc_unregister_platform); |
3677 | 3720 | ||
3678 | static u64 codec_format_map[] = { | ||
3679 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE, | ||
3680 | SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE, | ||
3681 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE, | ||
3682 | SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE, | ||
3683 | SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE, | ||
3684 | SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE, | ||
3685 | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3BE, | ||
3686 | SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_U24_3BE, | ||
3687 | SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE, | ||
3688 | SNDRV_PCM_FMTBIT_U20_3LE | SNDRV_PCM_FMTBIT_U20_3BE, | ||
3689 | SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE, | ||
3690 | SNDRV_PCM_FMTBIT_U18_3LE | SNDRV_PCM_FMTBIT_U18_3BE, | ||
3691 | SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE, | ||
3692 | SNDRV_PCM_FMTBIT_FLOAT64_LE | SNDRV_PCM_FMTBIT_FLOAT64_BE, | ||
3693 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | ||
3694 | | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE, | ||
3695 | }; | ||
3696 | |||
3697 | /* Fix up the DAI formats for endianness: codecs don't actually see | ||
3698 | * the endianness of the data but we're using the CPU format | ||
3699 | * definitions which do need to include endianness so we ensure that | ||
3700 | * codec DAIs always have both big and little endian variants set. | ||
3701 | */ | ||
3702 | static void fixup_codec_formats(struct snd_soc_pcm_stream *stream) | ||
3703 | { | ||
3704 | int i; | ||
3705 | |||
3706 | for (i = 0; i < ARRAY_SIZE(codec_format_map); i++) | ||
3707 | if (stream->formats & codec_format_map[i]) | ||
3708 | stream->formats |= codec_format_map[i]; | ||
3709 | } | ||
3710 | |||
3711 | static int snd_soc_codec_drv_probe(struct snd_soc_component *component) | 3721 | static int snd_soc_codec_drv_probe(struct snd_soc_component *component) |
3712 | { | 3722 | { |
3713 | struct snd_soc_codec *codec = snd_soc_component_to_codec(component); | 3723 | struct snd_soc_codec *codec = snd_soc_component_to_codec(component); |
@@ -3858,8 +3868,8 @@ int snd_soc_register_codec(struct device *dev, | |||
3858 | codec->component.regmap = codec_drv->get_regmap(dev); | 3868 | codec->component.regmap = codec_drv->get_regmap(dev); |
3859 | 3869 | ||
3860 | for (i = 0; i < num_dai; i++) { | 3870 | for (i = 0; i < num_dai; i++) { |
3861 | fixup_codec_formats(&dai_drv[i].playback); | 3871 | convert_endianness_formats(&dai_drv[i].playback); |
3862 | fixup_codec_formats(&dai_drv[i].capture); | 3872 | convert_endianness_formats(&dai_drv[i].capture); |
3863 | } | 3873 | } |
3864 | 3874 | ||
3865 | ret = snd_soc_register_dais(&codec->component, dai_drv, num_dai, false); | 3875 | ret = snd_soc_register_dais(&codec->component, dai_drv, num_dai, false); |