[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