ASoC: add snd_soc_of_parse_daifmt() for DeviceTree
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Tue, 15 Jan 2013 02:36:04 +0000 (18:36 -0800)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Sun, 27 Jan 2013 03:41:54 +0000 (11:41 +0800)
This patch adds snd_soc_of_parse_daifmt() and supports below style on DT.

        [prefix]format = "i2c";
        [prefix]clock-gating = "continuous";
        [prefix]bitclock-inversion;
        [prefix]bitclock-master;
        [prefix]frame-master;

Each driver can use specific [prefix]
(ex simple-card,cpu,dai,format = xxx;)

This sample will be
SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CONT |
SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBM_CFM

Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
include/sound/soc.h
sound/soc/soc-core.c

index bc56738cb1091b8319b2413fe7e6b2f105ba0ac8..571562340e5a1d2c7b1c6533c7fb020457e9b74a 100644 (file)
@@ -1171,6 +1171,8 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
                               const char *propname);
 int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
                                   const char *propname);
+unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
+                                    const char *prefix);
 
 #include <sound/soc-dai.h>
 
index 2370063b58245946f71adfa05f361097d3e53374..9d07dc03a1d3d04c6c4475a9444fe6aa393fbe07 100644 (file)
@@ -4208,6 +4208,121 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
 }
 EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
 
+unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
+                                    const char *prefix)
+{
+       int ret, i;
+       char prop[128];
+       unsigned int format = 0;
+       int bit, frame;
+       const char *str;
+       struct {
+               char *name;
+               unsigned int val;
+       } of_fmt_table[] = {
+               { "i2s",        SND_SOC_DAIFMT_I2S },
+               { "right_j",    SND_SOC_DAIFMT_RIGHT_J },
+               { "left_j",     SND_SOC_DAIFMT_LEFT_J },
+               { "dsp_a",      SND_SOC_DAIFMT_DSP_A },
+               { "dsp_b",      SND_SOC_DAIFMT_DSP_B },
+               { "ac97",       SND_SOC_DAIFMT_AC97 },
+               { "pdm",        SND_SOC_DAIFMT_PDM},
+               { "msb",        SND_SOC_DAIFMT_MSB },
+               { "lsb",        SND_SOC_DAIFMT_LSB },
+       }, of_clock_table[] = {
+               { "continuous", SND_SOC_DAIFMT_CONT },
+               { "gated",      SND_SOC_DAIFMT_GATED },
+       };
+
+       if (!prefix)
+               prefix = "";
+
+       /*
+        * check "[prefix]format = xxx"
+        * SND_SOC_DAIFMT_FORMAT_MASK area
+        */
+       snprintf(prop, sizeof(prop), "%sformat", prefix);
+       ret = of_property_read_string(np, prop, &str);
+       if (ret == 0) {
+               for (i = 0; i < ARRAY_SIZE(of_fmt_table); i++) {
+                       if (strcmp(str, of_fmt_table[i].name) == 0) {
+                               format |= of_fmt_table[i].val;
+                               break;
+                       }
+               }
+       }
+
+       /*
+        * check "[prefix]clock-gating = xxx"
+        * SND_SOC_DAIFMT_CLOCK_MASK area
+        */
+       snprintf(prop, sizeof(prop), "%sclock-gating", prefix);
+       ret = of_property_read_string(np, prop, &str);
+       if (ret == 0) {
+               for (i = 0; i < ARRAY_SIZE(of_clock_table); i++) {
+                       if (strcmp(str, of_clock_table[i].name) == 0) {
+                               format |= of_clock_table[i].val;
+                               break;
+                       }
+               }
+       }
+
+       /*
+        * check "[prefix]bitclock-inversion"
+        * check "[prefix]frame-inversion"
+        * SND_SOC_DAIFMT_INV_MASK area
+        */
+       snprintf(prop, sizeof(prop), "%sbitclock-inversion", prefix);
+       bit = !!of_get_property(np, prop, NULL);
+
+       snprintf(prop, sizeof(prop), "%sframe-inversion", prefix);
+       frame = !!of_get_property(np, prop, NULL);
+
+       switch ((bit << 4) + frame) {
+       case 0x11:
+               format |= SND_SOC_DAIFMT_IB_IF;
+               break;
+       case 0x10:
+               format |= SND_SOC_DAIFMT_IB_NF;
+               break;
+       case 0x01:
+               format |= SND_SOC_DAIFMT_NB_IF;
+               break;
+       default:
+               /* SND_SOC_DAIFMT_NB_NF is default */
+               break;
+       }
+
+       /*
+        * check "[prefix]bitclock-master"
+        * check "[prefix]frame-master"
+        * SND_SOC_DAIFMT_MASTER_MASK area
+        */
+       snprintf(prop, sizeof(prop), "%sbitclock-master", prefix);
+       bit = !!of_get_property(np, prop, NULL);
+
+       snprintf(prop, sizeof(prop), "%sframe-master", prefix);
+       frame = !!of_get_property(np, prop, NULL);
+
+       switch ((bit << 4) + frame) {
+       case 0x11:
+               format |= SND_SOC_DAIFMT_CBM_CFM;
+               break;
+       case 0x10:
+               format |= SND_SOC_DAIFMT_CBM_CFS;
+               break;
+       case 0x01:
+               format |= SND_SOC_DAIFMT_CBS_CFM;
+               break;
+       default:
+               format |= SND_SOC_DAIFMT_CBS_CFS;
+               break;
+       }
+
+       return format;
+}
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
+
 static int __init snd_soc_init(void)
 {
 #ifdef CONFIG_DEBUG_FS
This page took 0.029434 seconds and 5 git commands to generate.