Commit 273d778e authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown

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: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent fbb16563
...@@ -837,6 +837,7 @@ struct snd_soc_component_driver { ...@@ -837,6 +837,7 @@ struct snd_soc_component_driver {
unsigned int idle_bias_on:1; unsigned int idle_bias_on:1;
unsigned int suspend_bias_off:1; unsigned int suspend_bias_off:1;
unsigned int pmdown_time:1; /* care pmdown_time at stop */ unsigned int pmdown_time:1; /* care pmdown_time at stop */
unsigned int endianness:1;
}; };
struct snd_soc_component { struct snd_soc_component {
......
...@@ -3404,6 +3404,41 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component) ...@@ -3404,6 +3404,41 @@ static void snd_soc_component_del_unlocked(struct snd_soc_component *component)
list_del(&component->list); 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, int snd_soc_add_component(struct device *dev,
struct snd_soc_component *component, struct snd_soc_component *component,
const struct snd_soc_component_driver *component_driver, const struct snd_soc_component_driver *component_driver,
...@@ -3411,6 +3446,7 @@ int snd_soc_add_component(struct device *dev, ...@@ -3411,6 +3446,7 @@ int snd_soc_add_component(struct device *dev,
int num_dai) int num_dai)
{ {
int ret; int ret;
int i;
ret = snd_soc_component_initialize(component, component_driver, dev); ret = snd_soc_component_initialize(component, component_driver, dev);
if (ret) if (ret)
...@@ -3419,6 +3455,13 @@ int snd_soc_add_component(struct device *dev, ...@@ -3419,6 +3455,13 @@ int snd_soc_add_component(struct device *dev,
component->ignore_pmdown_time = true; component->ignore_pmdown_time = true;
component->registered_as_component = 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); ret = snd_soc_register_dais(component, dai_drv, num_dai, true);
if (ret < 0) { if (ret < 0) {
dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret); dev_err(dev, "ASoC: Failed to register DAIs: %d\n", ret);
...@@ -3675,39 +3718,6 @@ void snd_soc_unregister_platform(struct device *dev) ...@@ -3675,39 +3718,6 @@ void snd_soc_unregister_platform(struct device *dev)
} }
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];
}
static int snd_soc_codec_drv_probe(struct snd_soc_component *component) static int snd_soc_codec_drv_probe(struct snd_soc_component *component)
{ {
struct snd_soc_codec *codec = snd_soc_component_to_codec(component); struct snd_soc_codec *codec = snd_soc_component_to_codec(component);
...@@ -3858,8 +3868,8 @@ int snd_soc_register_codec(struct device *dev, ...@@ -3858,8 +3868,8 @@ int snd_soc_register_codec(struct device *dev,
codec->component.regmap = codec_drv->get_regmap(dev); codec->component.regmap = codec_drv->get_regmap(dev);
for (i = 0; i < num_dai; i++) { for (i = 0; i < num_dai; i++) {
fixup_codec_formats(&dai_drv[i].playback); convert_endianness_formats(&dai_drv[i].playback);
fixup_codec_formats(&dai_drv[i].capture); convert_endianness_formats(&dai_drv[i].capture);
} }
ret = snd_soc_register_dais(&codec->component, dai_drv, num_dai, false); ret = snd_soc_register_dais(&codec->component, dai_drv, num_dai, false);
......
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