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_dai *dai, 20 struct asoc_simple_dai *set, 21 unsigned int daifmt) 22 { 23 int ret = 0; 24 25 daifmt |= set->fmt; 26 27 if (!ret && daifmt) 28 ret = snd_soc_dai_set_fmt(dai, daifmt); 29 30 if (!ret && set->sysclk) 31 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0); 32 33 return ret; 34 } 35 36 static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) 37 { 38 struct asoc_simple_card_info *info = asoc_simple_get_card_info(rtd); 39 struct snd_soc_dai *codec = rtd->codec_dai; 40 struct snd_soc_dai *cpu = rtd->cpu_dai; 41 unsigned int daifmt = info->daifmt; 42 int ret; 43 44 ret = __asoc_simple_card_dai_init(codec, &info->codec_dai, daifmt); 45 if (ret < 0) 46 return ret; 47 48 ret = __asoc_simple_card_dai_init(cpu, &info->cpu_dai, daifmt); 49 if (ret < 0) 50 return ret; 51 52 return 0; 53 } 54 55 static int asoc_simple_card_probe(struct platform_device *pdev) 56 { 57 struct asoc_simple_card_info *cinfo = pdev->dev.platform_data; 58 struct device *dev = &pdev->dev; 59 60 if (!cinfo) { 61 dev_err(dev, "no info for asoc-simple-card\n"); 62 return -EINVAL; 63 } 64 65 if (!cinfo->name || 66 !cinfo->card || 67 !cinfo->codec || 68 !cinfo->platform || 69 !cinfo->cpu_dai.name || 70 !cinfo->codec_dai.name) { 71 dev_err(dev, "insufficient asoc_simple_card_info settings\n"); 72 return -EINVAL; 73 } 74 75 /* 76 * init snd_soc_dai_link 77 */ 78 cinfo->snd_link.name = cinfo->name; 79 cinfo->snd_link.stream_name = cinfo->name; 80 cinfo->snd_link.cpu_dai_name = cinfo->cpu_dai.name; 81 cinfo->snd_link.platform_name = cinfo->platform; 82 cinfo->snd_link.codec_name = cinfo->codec; 83 cinfo->snd_link.codec_dai_name = cinfo->codec_dai.name; 84 cinfo->snd_link.init = asoc_simple_card_dai_init; 85 86 /* 87 * init snd_soc_card 88 */ 89 cinfo->snd_card.name = cinfo->card; 90 cinfo->snd_card.owner = THIS_MODULE; 91 cinfo->snd_card.dai_link = &cinfo->snd_link; 92 cinfo->snd_card.num_links = 1; 93 cinfo->snd_card.dev = &pdev->dev; 94 95 return snd_soc_register_card(&cinfo->snd_card); 96 } 97 98 static int asoc_simple_card_remove(struct platform_device *pdev) 99 { 100 struct asoc_simple_card_info *cinfo = pdev->dev.platform_data; 101 102 return snd_soc_unregister_card(&cinfo->snd_card); 103 } 104 105 static struct platform_driver asoc_simple_card = { 106 .driver = { 107 .name = "asoc-simple-card", 108 .owner = THIS_MODULE, 109 }, 110 .probe = asoc_simple_card_probe, 111 .remove = asoc_simple_card_remove, 112 }; 113 114 module_platform_driver(asoc_simple_card); 115 116 MODULE_ALIAS("platform:asoc-simple-card"); 117 MODULE_LICENSE("GPL"); 118 MODULE_DESCRIPTION("ASoC Simple Sound Card"); 119 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 120