aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/soc.h2
-rw-r--r--sound/soc/soc-core.c115
2 files changed, 117 insertions, 0 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index bc56738cb109..571562340e5a 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -1171,6 +1171,8 @@ int snd_soc_of_parse_card_name(struct snd_soc_card *card,
1171 const char *propname); 1171 const char *propname);
1172int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, 1172int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
1173 const char *propname); 1173 const char *propname);
1174unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
1175 const char *prefix);
1174 1176
1175#include <sound/soc-dai.h> 1177#include <sound/soc-dai.h>
1176 1178
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,
4208} 4208}
4209EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing); 4209EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
4210 4210
4211unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
4212 const char *prefix)
4213{
4214 int ret, i;
4215 char prop[128];
4216 unsigned int format = 0;
4217 int bit, frame;
4218 const char *str;
4219 struct {
4220 char *name;
4221 unsigned int val;
4222 } of_fmt_table[] = {
4223 { "i2s", SND_SOC_DAIFMT_I2S },
4224 { "right_j", SND_SOC_DAIFMT_RIGHT_J },
4225 { "left_j", SND_SOC_DAIFMT_LEFT_J },
4226 { "dsp_a", SND_SOC_DAIFMT_DSP_A },
4227 { "dsp_b", SND_SOC_DAIFMT_DSP_B },
4228 { "ac97", SND_SOC_DAIFMT_AC97 },
4229 { "pdm", SND_SOC_DAIFMT_PDM},
4230 { "msb", SND_SOC_DAIFMT_MSB },
4231 { "lsb", SND_SOC_DAIFMT_LSB },
4232 }, of_clock_table[] = {
4233 { "continuous", SND_SOC_DAIFMT_CONT },
4234 { "gated", SND_SOC_DAIFMT_GATED },
4235 };
4236
4237 if (!prefix)
4238 prefix = "";
4239
4240 /*
4241 * check "[prefix]format = xxx"
4242 * SND_SOC_DAIFMT_FORMAT_MASK area
4243 */
4244 snprintf(prop, sizeof(prop), "%sformat", prefix);
4245 ret = of_property_read_string(np, prop, &str);
4246 if (ret == 0) {
4247 for (i = 0; i < ARRAY_SIZE(of_fmt_table); i++) {
4248 if (strcmp(str, of_fmt_table[i].name) == 0) {
4249 format |= of_fmt_table[i].val;
4250 break;
4251 }
4252 }
4253 }
4254
4255 /*
4256 * check "[prefix]clock-gating = xxx"
4257 * SND_SOC_DAIFMT_CLOCK_MASK area
4258 */
4259 snprintf(prop, sizeof(prop), "%sclock-gating", prefix);
4260 ret = of_property_read_string(np, prop, &str);
4261 if (ret == 0) {
4262 for (i = 0; i < ARRAY_SIZE(of_clock_table); i++) {
4263 if (strcmp(str, of_clock_table[i].name) == 0) {
4264 format |= of_clock_table[i].val;
4265 break;
4266 }
4267 }
4268 }
4269
4270 /*
4271 * check "[prefix]bitclock-inversion"
4272 * check "[prefix]frame-inversion"
4273 * SND_SOC_DAIFMT_INV_MASK area
4274 */
4275 snprintf(prop, sizeof(prop), "%sbitclock-inversion", prefix);
4276 bit = !!of_get_property(np, prop, NULL);
4277
4278 snprintf(prop, sizeof(prop), "%sframe-inversion", prefix);
4279 frame = !!of_get_property(np, prop, NULL);
4280
4281 switch ((bit << 4) + frame) {
4282 case 0x11:
4283 format |= SND_SOC_DAIFMT_IB_IF;
4284 break;
4285 case 0x10:
4286 format |= SND_SOC_DAIFMT_IB_NF;
4287 break;
4288 case 0x01:
4289 format |= SND_SOC_DAIFMT_NB_IF;
4290 break;
4291 default:
4292 /* SND_SOC_DAIFMT_NB_NF is default */
4293 break;
4294 }
4295
4296 /*
4297 * check "[prefix]bitclock-master"
4298 * check "[prefix]frame-master"
4299 * SND_SOC_DAIFMT_MASTER_MASK area
4300 */
4301 snprintf(prop, sizeof(prop), "%sbitclock-master", prefix);
4302 bit = !!of_get_property(np, prop, NULL);
4303
4304 snprintf(prop, sizeof(prop), "%sframe-master", prefix);
4305 frame = !!of_get_property(np, prop, NULL);
4306
4307 switch ((bit << 4) + frame) {
4308 case 0x11:
4309 format |= SND_SOC_DAIFMT_CBM_CFM;
4310 break;
4311 case 0x10:
4312 format |= SND_SOC_DAIFMT_CBM_CFS;
4313 break;
4314 case 0x01:
4315 format |= SND_SOC_DAIFMT_CBS_CFM;
4316 break;
4317 default:
4318 format |= SND_SOC_DAIFMT_CBS_CFS;
4319 break;
4320 }
4321
4322 return format;
4323}
4324EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
4325
4211static int __init snd_soc_init(void) 4326static int __init snd_soc_init(void)
4212{ 4327{
4213#ifdef CONFIG_DEBUG_FS 4328#ifdef CONFIG_DEBUG_FS