aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2009-05-09 11:22:58 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2009-05-09 11:35:21 -0400
commit151ab22cf71b7a1b9dd696d65a1a41e13d90cd00 (patch)
tree8e0bdcb4b35408563915625eed7685f2d66765bf
parentb4df0a6c9d88cfff77c73d33873cd60f9ab909b6 (diff)
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: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/soc-core.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index af11791a3b8c..6ac68e47b3a6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -2387,6 +2387,39 @@ void snd_soc_unregister_platform(struct snd_soc_platform *platform)
2387} 2387}
2388EXPORT_SYMBOL_GPL(snd_soc_unregister_platform); 2388EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
2389 2389
2390static u64 codec_format_map[] = {
2391 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE,
2392 SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_U16_BE,
2393 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE,
2394 SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_U24_BE,
2395 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE,
2396 SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_U32_BE,
2397 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3BE,
2398 SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_U24_3BE,
2399 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE,
2400 SNDRV_PCM_FMTBIT_U20_3LE | SNDRV_PCM_FMTBIT_U20_3BE,
2401 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S18_3BE,
2402 SNDRV_PCM_FMTBIT_U18_3LE | SNDRV_PCM_FMTBIT_U18_3BE,
2403 SNDRV_PCM_FMTBIT_FLOAT_LE | SNDRV_PCM_FMTBIT_FLOAT_BE,
2404 SNDRV_PCM_FMTBIT_FLOAT64_LE | SNDRV_PCM_FMTBIT_FLOAT64_BE,
2405 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE
2406 | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE,
2407};
2408
2409/* Fix up the DAI formats for endianness: codecs don't actually see
2410 * the endianness of the data but we're using the CPU format
2411 * definitions which do need to include endianness so we ensure that
2412 * codec DAIs always have both big and little endian variants set.
2413 */
2414static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
2415{
2416 int i;
2417
2418 for (i = 0; i < ARRAY_SIZE(codec_format_map); i++)
2419 if (stream->formats & codec_format_map[i])
2420 stream->formats |= codec_format_map[i];
2421}
2422
2390/** 2423/**
2391 * snd_soc_register_codec - Register a codec with the ASoC core 2424 * snd_soc_register_codec - Register a codec with the ASoC core
2392 * 2425 *
@@ -2394,6 +2427,8 @@ EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
2394 */ 2427 */
2395int snd_soc_register_codec(struct snd_soc_codec *codec) 2428int snd_soc_register_codec(struct snd_soc_codec *codec)
2396{ 2429{
2430 int i;
2431
2397 if (!codec->name) 2432 if (!codec->name)
2398 return -EINVAL; 2433 return -EINVAL;
2399 2434
@@ -2403,6 +2438,11 @@ int snd_soc_register_codec(struct snd_soc_codec *codec)
2403 2438
2404 INIT_LIST_HEAD(&codec->list); 2439 INIT_LIST_HEAD(&codec->list);
2405 2440
2441 for (i = 0; i < codec->num_dai; i++) {
2442 fixup_codec_formats(&codec->dai[i].playback);
2443 fixup_codec_formats(&codec->dai[i].capture);
2444 }
2445
2406 mutex_lock(&client_mutex); 2446 mutex_lock(&client_mutex);
2407 list_add(&codec->list, &codec_list); 2447 list_add(&codec->list, &codec_list);
2408 snd_soc_instantiate_cards(); 2448 snd_soc_instantiate_cards();