Commit 151ab22c authored by Mark Brown's avatar Mark Brown

ASoC: Fix up CODEC DAI formats for big endian CPUs

ASoC uses the standard ALSA data format definitions to specify the wire
format used between the CPU and CODEC. Since the ALSA data formats all
include the endianess of the data but this information is not relevant
by the time the data has been encoded onto the serial link to the CODEC
this means that either all the CODEC drivers need to declare both big and
little endian variants or the core needs to fix up the format constraints
specified by CODEC drivers.

For now take the latter approach - this will need to be revisited if any
CODECs are endianness dependant.
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent b4df0a6c
...@@ -2387,6 +2387,39 @@ void snd_soc_unregister_platform(struct snd_soc_platform *platform) ...@@ -2387,6 +2387,39 @@ void snd_soc_unregister_platform(struct snd_soc_platform *platform)
} }
EXPORT_SYMBOL_GPL(snd_soc_unregister_platform); 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];
}
/** /**
* snd_soc_register_codec - Register a codec with the ASoC core * snd_soc_register_codec - Register a codec with the ASoC core
* *
...@@ -2394,6 +2427,8 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_platform); ...@@ -2394,6 +2427,8 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
*/ */
int snd_soc_register_codec(struct snd_soc_codec *codec) int snd_soc_register_codec(struct snd_soc_codec *codec)
{ {
int i;
if (!codec->name) if (!codec->name)
return -EINVAL; return -EINVAL;
...@@ -2403,6 +2438,11 @@ int snd_soc_register_codec(struct snd_soc_codec *codec) ...@@ -2403,6 +2438,11 @@ int snd_soc_register_codec(struct snd_soc_codec *codec)
INIT_LIST_HEAD(&codec->list); INIT_LIST_HEAD(&codec->list);
for (i = 0; i < codec->num_dai; i++) {
fixup_codec_formats(&codec->dai[i].playback);
fixup_codec_formats(&codec->dai[i].capture);
}
mutex_lock(&client_mutex); mutex_lock(&client_mutex);
list_add(&codec->list, &codec_list); list_add(&codec->list, &codec_list);
snd_soc_instantiate_cards(); snd_soc_instantiate_cards();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment