Commit | Line | Data |
---|---|---|
f2390880 KM |
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>"); |