[alsa-devel] [RFC][PATCH 1/2] ASoC: add snd_soc_of_parse_daifmt()
Kuninori Morimoto
kuninori.morimoto.gx at renesas.com
Wed Dec 5 08:55:28 CET 2012
Hi Stephen
Cc Mark
Thank you for your reply
> > + ret |= __snd_soc_of_parse_daifmt(np, prefix, fmt,
> > + "i2s", SND_SOC_DAIFMT_I2S);
> > + ret |= __snd_soc_of_parse_daifmt(np, prefix, fmt,
> > + "right_j", SND_SOC_DAIFMT_RIGHT_J);
> > + ret |= __snd_soc_of_parse_daifmt(np, prefix, fmt,
> > + "left_j", SND_SOC_DAIFMT_LEFT_J);
> > + ret |= __snd_soc_of_parse_daifmt(np, prefix, fmt,
> > + "dsp_a", SND_SOC_DAIFMT_DSP_A);
> > + ret |= __snd_soc_of_parse_daifmt(np, prefix, fmt,
> > + "dsp_b", SND_SOC_DAIFMT_DSP_B);
>
> I'd expect to see something more like:
>
> fmt = of_property_read_u32_array(np, "bit-format");
Ahh... I see.
> Well, once a DT binding is created, you can't change the numbers, or you
> would break the ability for an old DT to work with a newer kernel.
OK. I understand.
> > How about to use string ?
> >
> > snd.soc.daifmt.format = "left_j"
> > snd.soc.daifmt.clock_gate = "cont"
> > snd.soc.daifmt.inversion = "ib_nf"
> > snd.soc.daifmt.hw_clock = "cbs_cfm"
>
> That's probably the best we can do for now. Using a pre-processor would
> be best:
>
> #define SND_SOC_DAIFMT_LEFT_J 3
>
> snd.soc.daifmt.format = <SND_SOC_DAIFMT_LEFT_J>;
>
> ... but we can't do that yet...
Thank you.
I tried v2 of snd_soc_of_parse_daifmt() which is using "string" and "array" style
[prefix]snd,soc,daifmt = "i2c", "nb_if", "cbm_cfm";
I would like to know your opinion.
----------------------------------------------
This patch adds snd_soc_of_parse_daifmt() and supports below style on DT.
[prefix]snd,soc,daifmt = "i2c", "nb_if", "cbm_cfm";
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 91244a0..af64632 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1168,6 +1168,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);
+int snd_soc_of_parse_daifmt(struct device_node *np,
+ const char *prefix, unsigned int *fmt);
#include <sound/soc-dai.h>
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 9c768bc..6cac98a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -4179,6 +4179,74 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
}
EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
+int snd_soc_of_parse_daifmt(struct device_node *np,
+ const char *prefix, unsigned int *fmt)
+{
+ int num, i, j;
+ int ret;
+ char prop[128];
+ unsigned int format;
+ const char *str;
+ struct {
+ char *name;
+ unsigned int val;
+ unsigned int msk;
+ } of_parse_table[] = {
+ { "i2s", SND_SOC_DAIFMT_I2S, SND_SOC_DAIFMT_FORMAT_MASK },
+ { "right_j", SND_SOC_DAIFMT_RIGHT_J, SND_SOC_DAIFMT_FORMAT_MASK },
+ { "left_j", SND_SOC_DAIFMT_LEFT_J, SND_SOC_DAIFMT_FORMAT_MASK },
+ { "dsp_a", SND_SOC_DAIFMT_DSP_A, SND_SOC_DAIFMT_FORMAT_MASK },
+ { "dsp_b", SND_SOC_DAIFMT_DSP_B, SND_SOC_DAIFMT_FORMAT_MASK },
+ { "ac97", SND_SOC_DAIFMT_AC97, SND_SOC_DAIFMT_FORMAT_MASK },
+ { "pdm", SND_SOC_DAIFMT_PDM, SND_SOC_DAIFMT_FORMAT_MASK},
+ { "msb", SND_SOC_DAIFMT_MSB, SND_SOC_DAIFMT_FORMAT_MASK },
+ { "lsb", SND_SOC_DAIFMT_LSB, SND_SOC_DAIFMT_FORMAT_MASK },
+ { "cont", SND_SOC_DAIFMT_CONT, SND_SOC_DAIFMT_CLOCK_MASK },
+ { "gated", SND_SOC_DAIFMT_GATED, SND_SOC_DAIFMT_CLOCK_MASK },
+ /* SND_SOC_DAIFMT_NB_NF is default */
+ { "nb_if", SND_SOC_DAIFMT_NB_IF, SND_SOC_DAIFMT_INV_MASK },
+ { "ib_nf", SND_SOC_DAIFMT_IB_NF, SND_SOC_DAIFMT_INV_MASK },
+ { "ib_if", SND_SOC_DAIFMT_IB_IF, SND_SOC_DAIFMT_INV_MASK },
+ { "cbm_cfm", SND_SOC_DAIFMT_CBM_CFM, SND_SOC_DAIFMT_MASTER_MASK },
+ { "cbs_cfm", SND_SOC_DAIFMT_CBS_CFM, SND_SOC_DAIFMT_MASTER_MASK },
+ { "cbm_cfs", SND_SOC_DAIFMT_CBM_CFS, SND_SOC_DAIFMT_MASTER_MASK },
+ { "cbs_cfs", SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAIFMT_MASTER_MASK },
+ };
+
+ if (!prefix)
+ prefix = "";
+
+ /*
+ * it finds "[prefix]snd,soc,daifmt = xxx" from device_node,
+ * and set SND_SOC_DAIFMT_XXX
+ */
+ snprintf(prop, sizeof(prop), "%ssnd,soc,daifmt", prefix);
+ num = of_property_count_strings(np, prop);
+ if (num < 0)
+ return num;
+
+ format = 0;
+ for (i = 0; i < num; i++) {
+ ret = of_property_read_string_index(np, prop, i, &str);
+ if (ret < 0)
+ return ret;
+
+ for (j = 0; j < ARRAY_SIZE(of_parse_table); j++) {
+ if (strcmp(str, of_parse_table[j].name) == 0) {
+ if (format & of_parse_table[j].msk)
+ return -EINVAL;
+
+ format |= of_parse_table[j].val;
+ }
+ }
+ }
+
+ *fmt = format;
+
+ return num;
+}
+EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
+
static int __init snd_soc_init(void)
{
#ifdef CONFIG_DEBUG_FS
More information about the Alsa-devel
mailing list