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@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