Signed-off-by: Kuninori Morimoto kuninori.morimoto.gx@renesas.com --- sound/soc/generic/simple-card.c | 90 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 3 deletions(-)
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index b4b4cab..a59e88c 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c @@ -9,6 +9,7 @@ * published by the Free Software Foundation. */
+#include <linux/of.h> #include <linux/platform_device.h> #include <linux/module.h> #include <sound/simple_card.h> @@ -47,12 +48,89 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) return 0; }
+static void asoc_simple_card_parse_of(struct device_node *np, + struct asoc_simple_card_info *cinfo, + struct device *dev) +{ + struct asoc_simple_dai_init_info *iinfo; + unsigned int cpu_daifmt = 0; + unsigned int codec_daifmt = 0; + unsigned int sysclk = 0; + + /* + * it will find + * + * iinfo,cpu,snd,soc,daifmt,xxx + * iinfo,codec,snd,soc,daifmt,xxx + * iinfo,sysclk + */ + snd_soc_of_parse_daifmt(np, "iinfo,cpu,", &cpu_daifmt); + snd_soc_of_parse_daifmt(np, "iinfo,codec,", &codec_daifmt); + of_property_read_u32(np, "iinfo,sysclk", &sysclk); + + if (cpu_daifmt || codec_daifmt || sysclk) { + iinfo = devm_kzalloc(dev, sizeof(*iinfo), GFP_KERNEL); + if (!iinfo) + return; + + cinfo->init = iinfo; + iinfo->cpu_daifmt = cpu_daifmt; + iinfo->codec_daifmt = codec_daifmt; + iinfo->sysclk = sysclk; + } + + /* + * it will find + * + * cinfo,xxx + */ + of_property_read_string(np, "cinfo,name", &cinfo->name); + of_property_read_string(np, "cinfo,card", &cinfo->card); + of_property_read_string(np, "cinfo,cpu_dai", &cinfo->cpu_dai); + of_property_read_string(np, "cinfo,codec", &cinfo->codec); + of_property_read_string(np, "cinfo,platform", &cinfo->platform); + of_property_read_string(np, "cinfo,codec_dai", &cinfo->codec_dai); + + /* + * debug info + */ + if (cinfo->name) + dev_dbg(dev, "name = %s\n", cinfo->name); + if (cinfo->card) + dev_dbg(dev, "card = %s\n", cinfo->card); + if (cinfo->cpu_dai) + dev_dbg(dev, "cpu_dai = %s\n", cinfo->cpu_dai); + if (cinfo->codec) + dev_dbg(dev, "codec = %s\n", cinfo->codec); + if (cinfo->platform) + dev_dbg(dev, "platform = %s\n", cinfo->platform); + if (cinfo->codec_dai) + dev_dbg(dev, "codec_dai = %s\n", cinfo->codec_dai); + if (iinfo && iinfo->cpu_daifmt) + dev_dbg(dev, "cpu_daifmt = %08x\n", iinfo->cpu_daifmt); + if (iinfo && iinfo->codec_daifmt) + dev_dbg(dev, "codec_daifmt = %08x\n", iinfo->codec_daifmt); + if (iinfo && iinfo->sysclk) + dev_dbg(dev, "iinfo,sysclk = %d\n", iinfo->sysclk); +} + static int asoc_simple_card_probe(struct platform_device *pdev) { - struct asoc_simple_card_info *cinfo = pdev->dev.platform_data; + struct asoc_simple_card_info *cinfo; + struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; + + cinfo = NULL; + if (np && of_device_is_available(np)) { + cinfo = devm_kzalloc(dev, sizeof(*cinfo), GFP_KERNEL); + if (cinfo) + asoc_simple_card_parse_of(np, cinfo, dev); + } else { + cinfo = pdev->dev.platform_data; + }
if (!cinfo) { - dev_err(&pdev->dev, "no info for asoc-simple-card\n"); + dev_err(dev, "no info for asoc-simple-card\n"); return -EINVAL; }
@@ -62,7 +140,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev) !cinfo->codec || !cinfo->platform || !cinfo->codec_dai) { - dev_err(&pdev->dev, "insufficient asoc_simple_card_info settings\n"); + dev_err(dev, "insufficient asoc_simple_card_info settings\n"); return -EINVAL; }
@@ -99,9 +177,15 @@ static int asoc_simple_card_remove(struct platform_device *pdev) return snd_soc_unregister_card(&cinfo->snd_card); }
+static const struct of_device_id asoc_simple_of_match[] = { + { .compatible = "asoc,simple-card", }, + {}, +}; + static struct platform_driver asoc_simple_card = { .driver = { .name = "asoc-simple-card", + .of_match_table = asoc_simple_of_match, }, .probe = asoc_simple_card_probe, .remove = asoc_simple_card_remove,