summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-04-09 16:29:21 +0100
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-04-16 19:36:29 +0100
commitf04209a7b0a9942aa78f8b27e63a8a5cc097adf8 (patch)
treeb2f07c053c943e370dd2ab39c17fdd5f132e9779
parent1eee1b3833d67eb52c0f4d293cbb796a776c5eed (diff)
downloadop-kernel-dev-f04209a7b0a9942aa78f8b27e63a8a5cc097adf8.zip
op-kernel-dev-f04209a7b0a9942aa78f8b27e63a8a5cc097adf8.tar.gz
ASoC: core: Flip master for CODECs in the CPU slot of a CODEC<->CODEC link
When two CODEC DAIs are linked directly to each other then if we give the same master mode settings to both devices things won't work as either neither will drive or they'll drive against each other. Flip the settings for the DAI in the CPU slot of the DAI link. Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/soc-core.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 98a4f7a..9eefe90 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1416,7 +1416,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
struct snd_soc_codec_conf *codec_conf;
enum snd_soc_compress_type compress_type;
struct snd_soc_dai_link *dai_link;
- int ret, i, order;
+ int ret, i, order, dai_fmt;
mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
@@ -1525,17 +1525,46 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
for (i = 0; i < card->num_links; i++) {
dai_link = &card->dai_link[i];
+ dai_fmt = dai_link->dai_fmt;
- if (dai_link->dai_fmt) {
+ if (dai_fmt) {
ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai,
- dai_link->dai_fmt);
+ dai_fmt);
if (ret != 0 && ret != -ENOTSUPP)
dev_warn(card->rtd[i].codec_dai->dev,
"Failed to set DAI format: %d\n",
ret);
+ }
+
+ /* If this is a regular CPU link there will be a platform */
+ if (dai_fmt && dai_link->platform_name) {
+ ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
+ dai_fmt);
+ if (ret != 0 && ret != -ENOTSUPP)
+ dev_warn(card->rtd[i].cpu_dai->dev,
+ "Failed to set DAI format: %d\n",
+ ret);
+ } else if (dai_fmt) {
+ /* Flip the polarity for the "CPU" end */
+ dai_fmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
+ switch (dai_link->dai_fmt &
+ SND_SOC_DAIFMT_MASTER_MASK) {
+ case SND_SOC_DAIFMT_CBM_CFM:
+ dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
+ break;
+ case SND_SOC_DAIFMT_CBM_CFS:
+ dai_fmt |= SND_SOC_DAIFMT_CBS_CFM;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFM:
+ dai_fmt |= SND_SOC_DAIFMT_CBM_CFS;
+ break;
+ case SND_SOC_DAIFMT_CBS_CFS:
+ dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
+ break;
+ }
ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
- dai_link->dai_fmt);
+ dai_fmt);
if (ret != 0 && ret != -ENOTSUPP)
dev_warn(card->rtd[i].cpu_dai->dev,
"Failed to set DAI format: %d\n",
OpenPOWER on IntegriCloud