ASoC: Allow DAI formats to be specified in the dai_link
authorMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 27 Sep 2011 15:41:01 +0000 (16:41 +0100)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Wed, 28 Sep 2011 12:22:28 +0000 (13:22 +0100)
For almost all machines the DAI format is a constant, always set to the
same thing. This means that not only should we normally set it on init
rather than in hw_params() (where it has been for historical reasons) we
should also allow users to configure this by setting a variable in the
dai_link structure. The combination of these two will make many machine
drivers even more data driven.

Implement a new dai_fmt field in the dai_link doing just that. Since 0 is
a valid value for many format flags and we need to be able to tell if the
field is actually set also add one to all the values used to configure
formats.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
include/sound/soc-dai.h
include/sound/soc.h
sound/soc/soc-core.c

index 12d98b4354448fc2fd29cfeabe6c88c65649c517..2413acc54883aad471cf0256b3fc2f8fc6d7ae11 100644 (file)
@@ -24,13 +24,13 @@ struct snd_pcm_substream;
  * Describes the physical PCM data formating and clocking. Add new formats
  * to the end.
  */
-#define SND_SOC_DAIFMT_I2S             0 /* I2S mode */
-#define SND_SOC_DAIFMT_RIGHT_J         1 /* Right Justified mode */
-#define SND_SOC_DAIFMT_LEFT_J          2 /* Left Justified mode */
-#define SND_SOC_DAIFMT_DSP_A           3 /* L data MSB after FRM LRC */
-#define SND_SOC_DAIFMT_DSP_B           4 /* L data MSB during FRM LRC */
-#define SND_SOC_DAIFMT_AC97            5 /* AC97 */
-#define SND_SOC_DAIFMT_PDM             6 /* Pulse density modulation */
+#define SND_SOC_DAIFMT_I2S             1 /* I2S mode */
+#define SND_SOC_DAIFMT_RIGHT_J         2 /* Right Justified mode */
+#define SND_SOC_DAIFMT_LEFT_J          3 /* Left Justified mode */
+#define SND_SOC_DAIFMT_DSP_A           4 /* L data MSB after FRM LRC */
+#define SND_SOC_DAIFMT_DSP_B           5 /* L data MSB during FRM LRC */
+#define SND_SOC_DAIFMT_AC97            6 /* AC97 */
+#define SND_SOC_DAIFMT_PDM             7 /* Pulse density modulation */
 
 /* left and right justified also known as MSB and LSB respectively */
 #define SND_SOC_DAIFMT_MSB             SND_SOC_DAIFMT_LEFT_J
@@ -42,8 +42,8 @@ struct snd_pcm_substream;
  * DAI bit clocks can be be gated (disabled) when the DAI is not
  * sending or receiving PCM data in a frame. This can be used to save power.
  */
-#define SND_SOC_DAIFMT_CONT            (0 << 4) /* continuous clock */
-#define SND_SOC_DAIFMT_GATED           (1 << 4) /* clock is gated */
+#define SND_SOC_DAIFMT_CONT            (1 << 4) /* continuous clock */
+#define SND_SOC_DAIFMT_GATED           (2 << 4) /* clock is gated */
 
 /*
  * DAI hardware signal inversions.
@@ -51,10 +51,10 @@ struct snd_pcm_substream;
  * Specifies whether the DAI can also support inverted clocks for the specified
  * format.
  */
-#define SND_SOC_DAIFMT_NB_NF           (0 << 8) /* normal bit clock + frame */
-#define SND_SOC_DAIFMT_NB_IF           (1 << 8) /* normal BCLK + inv FRM */
-#define SND_SOC_DAIFMT_IB_NF           (2 << 8) /* invert BCLK + nor FRM */
-#define SND_SOC_DAIFMT_IB_IF           (3 << 8) /* invert BCLK + FRM */
+#define SND_SOC_DAIFMT_NB_NF           (1 << 8) /* normal bit clock + frame */
+#define SND_SOC_DAIFMT_NB_IF           (2 << 8) /* normal BCLK + inv FRM */
+#define SND_SOC_DAIFMT_IB_NF           (3 << 8) /* invert BCLK + nor FRM */
+#define SND_SOC_DAIFMT_IB_IF           (4 << 8) /* invert BCLK + FRM */
 
 /*
  * DAI hardware clock masters.
@@ -63,10 +63,10 @@ struct snd_pcm_substream;
  * i.e. if the codec is clk and FRM master then the interface is
  * clk and frame slave.
  */
-#define SND_SOC_DAIFMT_CBM_CFM         (0 << 12) /* codec clk & FRM master */
-#define SND_SOC_DAIFMT_CBS_CFM         (1 << 12) /* codec clk slave & FRM master */
-#define SND_SOC_DAIFMT_CBM_CFS         (2 << 12) /* codec clk master & frame slave */
-#define SND_SOC_DAIFMT_CBS_CFS         (3 << 12) /* codec clk & FRM slave */
+#define SND_SOC_DAIFMT_CBM_CFM         (1 << 12) /* codec clk & FRM master */
+#define SND_SOC_DAIFMT_CBS_CFM         (2 << 12) /* codec clk slave & FRM master */
+#define SND_SOC_DAIFMT_CBM_CFS         (3 << 12) /* codec clk master & frame slave */
+#define SND_SOC_DAIFMT_CBS_CFS         (4 << 12) /* codec clk & FRM slave */
 
 #define SND_SOC_DAIFMT_FORMAT_MASK     0x000f
 #define SND_SOC_DAIFMT_CLOCK_MASK      0x00f0
index b499b37a67767de3c3d85fbcdcbbd62fa5e530e8..a4dc699d4801b21d99f42e2354b2b6cbbdea4197 100644 (file)
@@ -713,6 +713,8 @@ struct snd_soc_dai_link {
        const char *cpu_dai_name;
        const char *codec_dai_name;
 
+       unsigned int dai_fmt;           /* format to set on init */
+
        /* Keep DAI active over suspend */
        unsigned int ignore_suspend:1;
 
index bd20154e8b344caa8565f520a4cc4b1588a50fc8..a58c1fc966eb69d44762c83e0f5a6936082bf071 100644 (file)
@@ -1317,6 +1317,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
        struct snd_soc_codec *codec;
        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;
 
        mutex_lock(&card->mutex);
@@ -1429,6 +1430,26 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
                snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
                                        card->num_dapm_routes);
 
+       for (i = 0; i < card->num_links; i++) {
+               dai_link = &card->dai_link[i];
+
+               if (dai_link->dai_fmt) {
+                       ret = snd_soc_dai_set_fmt(card->rtd[i].codec_dai,
+                                                 dai_link->dai_fmt);
+                       if (ret != 0)
+                               dev_warn(card->rtd[i].codec_dai->dev,
+                                        "Failed to set DAI format: %d\n",
+                                        ret);
+
+                       ret = snd_soc_dai_set_fmt(card->rtd[i].cpu_dai,
+                                                 dai_link->dai_fmt);
+                       if (ret != 0)
+                               dev_warn(card->rtd[i].cpu_dai->dev,
+                                        "Failed to set DAI format: %d\n",
+                                        ret);
+               }
+       }
+
        snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
                 "%s", card->name);
        snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),