1 /* 2 * ASoC simple sound card support 3 * 4 * Copyright (C) 2012 Renesas Solutions Corp. 5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 12 #include <linux/platform_device.h> 13 #include <linux/module.h> 14 #include <sound/simple_card.h> 15 16 #define asoc_simple_get_card_info(p) \ 17 container_of(p->dai_link, struct asoc_simple_card_info, snd_link) 18 19 static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) 20 { 21 struct asoc_simple_card_info *cinfo = asoc_simple_get_card_info(rtd); 22 struct asoc_simple_dai_init_info *iinfo = cinfo->init; 23 struct snd_soc_dai *codec = rtd->codec_dai; 24 struct snd_soc_dai *cpu = rtd->cpu_dai; 25 unsigned int cpu_daifmt = iinfo->fmt | iinfo->cpu_daifmt; 26 unsigned int codec_daifmt = iinfo->fmt | iinfo->codec_daifmt; 27 int ret; 28 29 if (codec_daifmt) { 30 ret = snd_soc_dai_set_fmt(codec, codec_daifmt); 31 if (ret < 0) 32 return ret; 33 } 34 35 if (iinfo->sysclk) { 36 ret = snd_soc_dai_set_sysclk(codec, 0, iinfo->sysclk, 0); 37 if (ret < 0) 38 return ret; 39 } 40 41 if (cpu_daifmt) { 42 ret = snd_soc_dai_set_fmt(cpu, cpu_daifmt); 43 if (ret < 0) 44 return ret; 45 } 46 47 return 0; 48 } 49 50 static int asoc_simple_card_probe(struct platform_device *pdev) 51 { 52 struct asoc_simple_card_info *cinfo = pdev->dev.platform_data; 53 54 if (!cinfo) { 55 dev_err(&pdev->dev, "no info for asoc-simple-card\n"); 56 return -EINVAL; 57 } 58 59 if (!cinfo->name || 60 !cinfo->card || 61 !cinfo->cpu_dai || 62 !cinfo->codec || 63 !cinfo->platform || 64 !cinfo->codec_dai) { 65 dev_err(&pdev->dev, "insufficient asoc_simple_card_info settings\n"); 66 return -EINVAL; 67 } 68 69 /* 70 * init snd_soc_dai_link 71 */ 72 cinfo->snd_link.name = cinfo->name; 73 cinfo->snd_link.stream_name = cinfo->name; 74 cinfo->snd_link.cpu_dai_name = cinfo->cpu_dai; 75 cinfo->snd_link.platform_name = cinfo->platform; 76 cinfo->snd_link.codec_name = cinfo->codec; 77 cinfo->snd_link.codec_dai_name = cinfo->codec_dai; 78 79 /* enable snd_link.init if cinfo has settings */ 80 if (cinfo->init) 81 cinfo->snd_link.init = asoc_simple_card_dai_init; 82 83 /* 84 * init snd_soc_card 85 */ 86 cinfo->snd_card.name = cinfo->card; 87 cinfo->snd_card.owner = THIS_MODULE; 88 cinfo->snd_card.dai_link = &cinfo->snd_link; 89 cinfo->snd_card.num_links = 1; 90 cinfo->snd_card.dev = &pdev->dev; 91 92 return snd_soc_register_card(&cinfo->snd_card); 93 } 94 95 static int asoc_simple_card_remove(struct platform_device *pdev) 96 { 97 struct asoc_simple_card_info *cinfo = pdev->dev.platform_data; 98 99 return snd_soc_unregister_card(&cinfo->snd_card); 100 } 101 102 static struct platform_driver asoc_simple_card = { 103 .driver = { 104 .name = "asoc-simple-card", 105 }, 106 .probe = asoc_simple_card_probe, 107 .remove = asoc_simple_card_remove, 108 }; 109 110 module_platform_driver(asoc_simple_card); 111 112 MODULE_LICENSE("GPL"); 113 MODULE_DESCRIPTION("ASoC Simple Sound Card"); 114 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 115