From a7930ed458afeacb029cee2b22f77b2a15472ad6 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 14 Jan 2013 18:36:04 -0800 Subject: ASoC: add snd_soc_of_parse_daifmt() for DeviceTree 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 Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'sound/soc/soc-core.c') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2370063b5824..9d07dc03a1d3 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -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 -- cgit v1.2.3 From 8c2d6a9f9cfa59acfa63ee88e70d58f0ba3eaf21 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 29 Jan 2013 21:03:36 -0800 Subject: ASoC: clock gating is decided by bool on snd_soc_of_parse_daifmt() ASoC clock gate settings are continuous/gated only. This patch decides it as bool, then, gated clock will be default. Special thanks to Stephen Cc: Stephen Warren Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'sound/soc/soc-core.c') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 9d07dc03a1d3..b3d75d2c966a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -4229,9 +4229,6 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, { "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) @@ -4253,19 +4250,14 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, } /* - * check "[prefix]clock-gating = xxx" + * check "[prefix]continuous-clock" * 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; - } - } - } + snprintf(prop, sizeof(prop), "%scontinuous-clock", prefix); + if (of_get_property(np, prop, NULL)) + format |= SND_SOC_DAIFMT_CONT; + else + format |= SND_SOC_DAIFMT_GATED; /* * check "[prefix]bitclock-inversion" -- cgit v1.2.3