blob: 1c6382fa54a02a0bcd244db8976fd9dbea6828fd [file] [log] [blame]
Kuninori Morimoto9afe58f2018-07-02 06:30:58 +00001// SPDX-License-Identifier: GPL-2.0
2//
3// ASoC simple SCU sound card support
4//
5// Copyright (C) 2015 Renesas Solutions Corp.
6// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7//
8// based on ${LINUX}/sound/soc/generic/simple-card.c
9
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000010#include <linux/clk.h>
11#include <linux/device.h>
12#include <linux/module.h>
13#include <linux/of.h>
14#include <linux/of_device.h>
15#include <linux/platform_device.h>
16#include <linux/string.h>
17#include <sound/jack.h>
18#include <sound/soc.h>
19#include <sound/soc-dai.h>
Kuninori Morimotod6a4a9a42016-06-30 06:03:13 +000020#include <sound/simple_card_utils.h>
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000021
Kuninori Morimoto6910e862016-10-28 03:37:44 +000022struct simple_card_data {
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000023 struct snd_soc_card snd_card;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000024 struct snd_soc_codec_conf codec_conf;
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +000025 struct simple_dai_props {
26 struct asoc_simple_dai dai;
Kuninori Morimoto2289cc12018-08-31 03:08:51 +000027 struct snd_soc_dai_link_component codecs;
Kuninori Morimoto24f3bea2018-08-31 03:10:46 +000028 struct snd_soc_dai_link_component platform;
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +000029 } *dai_props;
Kuninori Morimoto3433bf02015-06-15 06:22:30 +000030 struct snd_soc_dai_link *dai_link;
Kuninori Morimotocd8957f2017-06-15 00:24:28 +000031 struct asoc_simple_card_data adata;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000032};
33
Kuninori Morimotod27f3b42017-03-15 04:44:16 +000034#define simple_priv_to_card(priv) (&(priv)->snd_card)
Kuninori Morimoto53e682b2016-08-23 01:34:17 +000035#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
Kuninori Morimotod27f3b42017-03-15 04:44:16 +000036#define simple_priv_to_dev(priv) (simple_priv_to_card(priv)->dev)
37#define simple_priv_to_link(priv, i) (simple_priv_to_card(priv)->dai_link + (i))
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000038
Kuninori Morimoto5bbf38662016-08-08 06:02:31 +000039#define DAI "sound-dai"
40#define CELL "#sound-dai-cells"
Kuninori Morimoto64df0e62016-08-23 01:34:43 +000041#define PREFIX "simple-audio-card,"
Kuninori Morimoto5bbf38662016-08-08 06:02:31 +000042
Kuninori Morimoto53e682b2016-08-23 01:34:17 +000043static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000044{
45 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto6910e862016-10-28 03:37:44 +000046 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +000047 struct simple_dai_props *dai_props =
Kuninori Morimoto53e682b2016-08-23 01:34:17 +000048 simple_priv_to_props(priv, rtd->num);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000049
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +000050 return asoc_simple_card_clk_enable(&dai_props->dai);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000051}
52
Kuninori Morimoto53e682b2016-08-23 01:34:17 +000053static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000054{
55 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto6910e862016-10-28 03:37:44 +000056 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +000057 struct simple_dai_props *dai_props =
Kuninori Morimoto53e682b2016-08-23 01:34:17 +000058 simple_priv_to_props(priv, rtd->num);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000059
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +000060 asoc_simple_card_clk_disable(&dai_props->dai);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000061}
62
Julia Lawall9b6fdef2016-10-15 16:55:49 +020063static const struct snd_soc_ops asoc_simple_card_ops = {
Kuninori Morimoto53e682b2016-08-23 01:34:17 +000064 .startup = asoc_simple_card_startup,
65 .shutdown = asoc_simple_card_shutdown,
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000066};
67
Kuninori Morimoto53e682b2016-08-23 01:34:17 +000068static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000069{
Kuninori Morimoto6910e862016-10-28 03:37:44 +000070 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
Kuninori Morimoto04700022015-06-15 06:24:15 +000071 struct snd_soc_dai *dai;
72 struct snd_soc_dai_link *dai_link;
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +000073 struct simple_dai_props *dai_props;
Mengdong Lin1a497982015-11-18 02:34:11 -050074 int num = rtd->num;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000075
Kuninori Morimoto53e682b2016-08-23 01:34:17 +000076 dai_link = simple_priv_to_link(priv, num);
77 dai_props = simple_priv_to_props(priv, num);
Kuninori Morimoto04700022015-06-15 06:24:15 +000078 dai = dai_link->dynamic ?
79 rtd->cpu_dai :
80 rtd->codec_dai;
81
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +000082 return asoc_simple_card_init_dai(dai, &dai_props->dai);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +000083}
84
Kuninori Morimoto53e682b2016-08-23 01:34:17 +000085static int asoc_simple_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
Kuninori Morimotoaf7e2be2015-03-26 04:01:46 +000086 struct snd_pcm_hw_params *params)
87{
Kuninori Morimoto6910e862016-10-28 03:37:44 +000088 struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
Kuninori Morimotoaf7e2be2015-03-26 04:01:46 +000089
Kuninori Morimotocd8957f2017-06-15 00:24:28 +000090 asoc_simple_card_convert_fixup(&priv->adata, params);
Kuninori Morimotoaf7e2be2015-03-26 04:01:46 +000091
92 return 0;
93}
94
Kuninori Morimotodbd08fe2018-12-04 08:20:13 +000095static int asoc_simple_card_dai_link_of(struct device_node *link,
96 struct device_node *np,
97 struct device_node *codec,
Kuninori Morimoto6910e862016-10-28 03:37:44 +000098 struct simple_card_data *priv,
Kuninori Morimotodbd08fe2018-12-04 08:20:13 +000099 int idx, bool is_fe,
100 bool is_top_level_node)
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000101{
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000102 struct device *dev = simple_priv_to_dev(priv);
103 struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +0000104 struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
Kuninori Morimotod27f3b42017-03-15 04:44:16 +0000105 struct snd_soc_card *card = simple_priv_to_card(priv);
Kuninori Morimotodbd08fe2018-12-04 08:20:13 +0000106 char *prefix = "";
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000107 int ret;
108
Kuninori Morimotodbd08fe2018-12-04 08:20:13 +0000109 /* For single DAI link & old style of DT node */
110 if (is_top_level_node)
111 prefix = PREFIX;
112
Kuninori Morimoto04700022015-06-15 06:24:15 +0000113 if (is_fe) {
Kuninori Morimoto27b01082016-08-10 02:21:03 +0000114 int is_single_links = 0;
Kuninori Morimoto2289cc12018-08-31 03:08:51 +0000115 struct snd_soc_dai_link_component *codecs;
Kuninori Morimoto27b01082016-08-10 02:21:03 +0000116
Kuninori Morimoto04700022015-06-15 06:24:15 +0000117 /* BE is dummy */
Kuninori Morimoto2289cc12018-08-31 03:08:51 +0000118 codecs = dai_link->codecs;
119 codecs->of_node = NULL;
120 codecs->dai_name = "snd-soc-dummy-dai";
121 codecs->name = "snd-soc-dummy";
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000122
Kuninori Morimoto04700022015-06-15 06:24:15 +0000123 /* FE settings */
124 dai_link->dynamic = 1;
125 dai_link->dpcm_merged_format = 1;
Kuninori Morimoto5bbf38662016-08-08 06:02:31 +0000126
127 ret = asoc_simple_card_parse_cpu(np, dai_link, DAI, CELL,
128 &is_single_links);
129 if (ret)
Kuninori Morimoto575f1f92015-12-01 08:33:23 +0000130 return ret;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000131
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +0000132 ret = asoc_simple_card_parse_clk_cpu(dev, np, dai_link, &dai_props->dai);
Kuninori Morimotoc9a235d2016-07-19 02:53:32 +0000133 if (ret < 0)
134 return ret;
135
Kuninori Morimoto8a99a6b2016-07-11 23:58:25 +0000136 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
137 "fe.%s",
138 dai_link->cpu_dai_name);
139 if (ret < 0)
140 return ret;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000141
Kuninori Morimoto27b01082016-08-10 02:21:03 +0000142 asoc_simple_card_canonicalize_cpu(dai_link, is_single_links);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000143 } else {
Kuninori Morimoto04700022015-06-15 06:24:15 +0000144 /* FE is dummy */
145 dai_link->cpu_of_node = NULL;
146 dai_link->cpu_dai_name = "snd-soc-dummy-dai";
147 dai_link->cpu_name = "snd-soc-dummy";
148
149 /* BE settings */
150 dai_link->no_pcm = 1;
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000151 dai_link->be_hw_params_fixup = asoc_simple_card_be_hw_params_fixup;
Kuninori Morimoto5bbf38662016-08-08 06:02:31 +0000152
153 ret = asoc_simple_card_parse_codec(np, dai_link, DAI, CELL);
Kuninori Morimoto575f1f92015-12-01 08:33:23 +0000154 if (ret < 0)
155 return ret;
Kuninori Morimoto04700022015-06-15 06:24:15 +0000156
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +0000157 ret = asoc_simple_card_parse_clk_codec(dev, np, dai_link, &dai_props->dai);
Kuninori Morimotoc9a235d2016-07-19 02:53:32 +0000158 if (ret < 0)
159 return ret;
160
Kuninori Morimoto8a99a6b2016-07-11 23:58:25 +0000161 ret = asoc_simple_card_set_dailink_name(dev, dai_link,
162 "be.%s",
Kuninori Morimoto2289cc12018-08-31 03:08:51 +0000163 dai_link->codecs->dai_name);
Kuninori Morimoto8a99a6b2016-07-11 23:58:25 +0000164 if (ret < 0)
165 return ret;
166
Kuninori Morimotoca8d95c2018-11-22 00:55:40 +0000167 /* check "prefix" from top node */
Kuninori Morimotod27f3b42017-03-15 04:44:16 +0000168 snd_soc_of_parse_audio_prefix(card,
Kuninori Morimoto64df0e62016-08-23 01:34:43 +0000169 &priv->codec_conf,
Kuninori Morimoto2289cc12018-08-31 03:08:51 +0000170 dai_link->codecs->of_node,
Kuninori Morimoto64df0e62016-08-23 01:34:43 +0000171 PREFIX "prefix");
Kuninori Morimotoca8d95c2018-11-22 00:55:40 +0000172 /* check "prefix" from each node if top doesn't have */
173 if (!priv->codec_conf.of_node)
174 snd_soc_of_parse_node_prefix(np,
175 &priv->codec_conf,
176 dai_link->codecs->of_node,
177 "prefix");
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000178 }
179
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +0000180 ret = asoc_simple_card_of_parse_tdm(np, &dai_props->dai);
Kuninori Morimoto9f645422016-08-25 01:58:55 +0000181 if (ret)
182 return ret;
183
Kuninori Morimotoa09f3832016-08-09 05:50:19 +0000184 ret = asoc_simple_card_canonicalize_dailink(dai_link);
185 if (ret < 0)
186 return ret;
187
Kuninori Morimotodbd08fe2018-12-04 08:20:13 +0000188 ret = asoc_simple_card_parse_daifmt(dev, link, codec,
189 prefix, &dai_link->dai_fmt);
190 if (ret < 0)
191 return ret;
192
Kuninori Morimoto04700022015-06-15 06:24:15 +0000193 dai_link->dpcm_playback = 1;
194 dai_link->dpcm_capture = 1;
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000195 dai_link->ops = &asoc_simple_card_ops;
196 dai_link->init = asoc_simple_card_dai_init;
Kuninori Morimoto04700022015-06-15 06:24:15 +0000197
Kuninori Morimotoc9a235d2016-07-19 02:53:32 +0000198 return 0;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000199}
200
Kuninori Morimoto0d6b3522017-06-07 00:37:30 +0000201static int asoc_simple_card_parse_of(struct simple_card_data *priv)
Kuninori Morimoto15a190ff2016-10-28 03:37:26 +0000202
Kuninori Morimotoaf998f82015-12-17 02:49:43 +0000203{
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000204 struct device *dev = simple_priv_to_dev(priv);
Kuninori Morimotoda32d652018-12-11 03:24:57 +0000205 struct device_node *top = dev->of_node;
206 struct device_node *node;
Kuninori Morimotodbd08fe2018-12-04 08:20:13 +0000207 struct device_node *np;
208 struct device_node *codec;
209 struct snd_soc_card *card = simple_priv_to_card(priv);
Kuninori Morimotoaf998f82015-12-17 02:49:43 +0000210 bool is_fe;
Kuninori Morimotoda32d652018-12-11 03:24:57 +0000211 int ret, i, loop;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000212
Kuninori Morimotoda32d652018-12-11 03:24:57 +0000213 if (!top)
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000214 return -EINVAL;
215
Daniel Balutad0148eb2017-08-11 17:12:19 +0300216 ret = asoc_simple_card_of_parse_widgets(card, PREFIX);
217 if (ret < 0)
218 return ret;
219
Kuninori Morimoto33404f32018-11-21 02:11:13 +0000220 ret = asoc_simple_card_of_parse_routing(card, PREFIX);
Kuninori Morimoto64df0e62016-08-23 01:34:43 +0000221 if (ret < 0)
222 return ret;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000223
Kuninori Morimotoda32d652018-12-11 03:24:57 +0000224 asoc_simple_card_parse_convert(dev, top, PREFIX, &priv->adata);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000225
Kuninori Morimotoda32d652018-12-11 03:24:57 +0000226 loop = 1;
Kuninori Morimotodbd08fe2018-12-04 08:20:13 +0000227 i = 0;
Kuninori Morimotoda32d652018-12-11 03:24:57 +0000228 node = of_get_child_by_name(top, PREFIX "dai-link");
229 if (!node) {
230 node = dev->of_node;
231 loop = 0;
Kuninori Morimoto15a190ff2016-10-28 03:37:26 +0000232 }
233
Kuninori Morimotoda32d652018-12-11 03:24:57 +0000234 do {
235 codec = of_get_child_by_name(node,
236 loop ? "codec" : PREFIX "codec");
237 if (!codec)
238 return -ENODEV;
239
240 for_each_child_of_node(node, np) {
241 is_fe = (np != codec);
242
243 ret = asoc_simple_card_dai_link_of(node, np, codec, priv,
244 i, is_fe, !loop);
245 if (ret < 0)
246 return ret;
247 i++;
248 }
249 node = of_get_next_child(top, node);
250 } while (loop && node);
251
Kuninori Morimotod27f3b42017-03-15 04:44:16 +0000252 ret = asoc_simple_card_parse_card_name(card, PREFIX);
Kuninori Morimoto53ae9182016-07-12 00:00:00 +0000253 if (ret < 0)
254 return ret;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000255
256 return 0;
257}
258
Kuninori Morimotob8d8f9a2018-12-11 03:25:08 +0000259static void asoc_simple_card_get_dais_count(struct device *dev,
260 int *link_num,
261 int *dais_num,
262 int *ccnf_num)
263{
264 struct device_node *top = dev->of_node;
265 struct device_node *node;
266 int loop;
267 int num;
268
269 /*
270 * link_num : number of links.
271 * CPU-Codec / CPU-dummy / dummy-Codec
272 * dais_num : number of DAIs
273 * ccnf_num : number of codec_conf
274 * same number for "dummy-Codec"
275 *
276 * ex1)
277 * CPU0 --- Codec0 link : 5
278 * CPU1 --- Codec1 dais : 7
279 * CPU2 -/ ccnf : 1
280 * CPU3 --- Codec2
281 *
282 * => 5 links = 2xCPU-Codec + 2xCPU-dummy + 1xdummy-Codec
283 * => 7 DAIs = 4xCPU + 3xCodec
284 * => 1 ccnf = 1xdummy-Codec
285 *
286 * ex2)
287 * CPU0 --- Codec0 link : 5
288 * CPU1 --- Codec1 dais : 6
289 * CPU2 -/ ccnf : 1
290 * CPU3 -/
291 *
292 * => 5 links = 1xCPU-Codec + 3xCPU-dummy + 1xdummy-Codec
293 * => 6 DAIs = 4xCPU + 2xCodec
294 * => 1 ccnf = 1xdummy-Codec
295 *
296 * ex3)
297 * CPU0 --- Codec0 link : 6
298 * CPU1 -/ dais : 6
299 * CPU2 --- Codec1 ccnf : 2
300 * CPU3 -/
301 *
302 * => 6 links = 0xCPU-Codec + 4xCPU-dummy + 2xdummy-Codec
303 * => 6 DAIs = 4xCPU + 2xCodec
304 * => 2 ccnf = 2xdummy-Codec
305 */
306 if (!top) {
307 (*link_num) = 1;
308 (*dais_num) = 2;
309 (*ccnf_num) = 0;
310 return;
311 }
312
313 loop = 1;
314 node = of_get_child_by_name(top, PREFIX "dai-link");
315 if (!node) {
316 node = top;
317 loop = 0;
318 }
319
320 do {
321 num = of_get_child_count(node);
322 (*dais_num) += num;
323 if (num > 2) {
324 (*link_num) += num;
325 (*ccnf_num)++;
326 } else {
327 (*link_num)++;
328 }
329 node = of_get_next_child(top, node);
330 } while (loop && node);
331}
332
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000333static int asoc_simple_card_probe(struct platform_device *pdev)
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000334{
Kuninori Morimoto6910e862016-10-28 03:37:44 +0000335 struct simple_card_data *priv;
Kuninori Morimoto19359922016-10-28 03:38:00 +0000336 struct snd_soc_dai_link *dai_link;
Kuninori Morimoto5ece10a2018-08-31 03:08:38 +0000337 struct simple_dai_props *dai_props;
Kuninori Morimotod27f3b42017-03-15 04:44:16 +0000338 struct snd_soc_card *card;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000339 struct device *dev = &pdev->dev;
Kuninori Morimotob8d8f9a2018-12-11 03:25:08 +0000340 int ret, i;
341 int lnum = 0, dnum = 0, cnum = 0;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000342
343 /* Allocate the private data */
344 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
345 if (!priv)
346 return -ENOMEM;
347
Kuninori Morimotob8d8f9a2018-12-11 03:25:08 +0000348 asoc_simple_card_get_dais_count(dev, &lnum, &dnum, &cnum);
349 if (!lnum || !dnum)
350 return -EINVAL;
Kuninori Morimoto15a190ff2016-10-28 03:37:26 +0000351
Kuninori Morimotob8d8f9a2018-12-11 03:25:08 +0000352 dai_props = devm_kcalloc(dev, lnum, sizeof(*dai_props), GFP_KERNEL);
353 dai_link = devm_kcalloc(dev, lnum, sizeof(*dai_link), GFP_KERNEL);
Kuninori Morimoto19359922016-10-28 03:38:00 +0000354 if (!dai_props || !dai_link)
Kuninori Morimoto15a190ff2016-10-28 03:37:26 +0000355 return -ENOMEM;
356
Kuninori Morimoto2289cc12018-08-31 03:08:51 +0000357 /*
358 * Use snd_soc_dai_link_component instead of legacy style
359 * It is codec only. but cpu/platform will be supported in the future.
360 * see
361 * soc-core.c :: snd_soc_init_multicodec()
362 */
Kuninori Morimotob8d8f9a2018-12-11 03:25:08 +0000363 for (i = 0; i < lnum; i++) {
Kuninori Morimoto2289cc12018-08-31 03:08:51 +0000364 dai_link[i].codecs = &dai_props[i].codecs;
365 dai_link[i].num_codecs = 1;
Kuninori Morimoto24f3bea2018-08-31 03:10:46 +0000366 dai_link[i].platform = &dai_props[i].platform;
Kuninori Morimoto2289cc12018-08-31 03:08:51 +0000367 }
368
Kuninori Morimoto19359922016-10-28 03:38:00 +0000369 priv->dai_props = dai_props;
370 priv->dai_link = dai_link;
Kuninori Morimoto15a190ff2016-10-28 03:37:26 +0000371
372 /* Init snd_soc_card */
Kuninori Morimotod27f3b42017-03-15 04:44:16 +0000373 card = simple_priv_to_card(priv);
374 card->owner = THIS_MODULE;
375 card->dev = dev;
376 card->dai_link = priv->dai_link;
Kuninori Morimotob8d8f9a2018-12-11 03:25:08 +0000377 card->num_links = lnum;
Kuninori Morimotod27f3b42017-03-15 04:44:16 +0000378 card->codec_conf = &priv->codec_conf;
379 card->num_configs = 1;
Kuninori Morimoto15a190ff2016-10-28 03:37:26 +0000380
Kuninori Morimoto0d6b3522017-06-07 00:37:30 +0000381 ret = asoc_simple_card_parse_of(priv);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000382 if (ret < 0) {
383 if (ret != -EPROBE_DEFER)
384 dev_err(dev, "parse error %d\n", ret);
385 goto err;
386 }
387
Kuninori Morimotod27f3b42017-03-15 04:44:16 +0000388 snd_soc_card_set_drvdata(card, priv);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000389
Kuninori Morimotod27f3b42017-03-15 04:44:16 +0000390 ret = devm_snd_soc_register_card(dev, card);
Kuninori Morimotoc73df772017-05-19 00:57:44 +0000391 if (ret < 0)
392 goto err;
393
394 return 0;
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000395err:
Kuninori Morimotod27f3b42017-03-15 04:44:16 +0000396 asoc_simple_card_clean_reference(card);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000397
398 return ret;
399}
400
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000401static int asoc_simple_card_remove(struct platform_device *pdev)
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000402{
403 struct snd_soc_card *card = platform_get_drvdata(pdev);
404
Kuninori Morimoto239486b2016-08-10 02:22:01 +0000405 return asoc_simple_card_clean_reference(card);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000406}
407
Kuninori Morimotof4d707092016-08-25 01:58:31 +0000408static const struct of_device_id asoc_simple_of_match[] = {
409 { .compatible = "renesas,rsrc-card", },
410 { .compatible = "simple-scu-audio-card", },
411 {},
412};
413MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
414
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000415static struct platform_driver asoc_simple_card = {
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000416 .driver = {
Kuninori Morimoto64df0e62016-08-23 01:34:43 +0000417 .name = "simple-scu-audio-card",
Kuninori Morimotob4e01802017-08-22 04:56:06 +0000418 .pm = &snd_soc_pm_ops,
Kuninori Morimotof4d707092016-08-25 01:58:31 +0000419 .of_match_table = asoc_simple_of_match,
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000420 },
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000421 .probe = asoc_simple_card_probe,
422 .remove = asoc_simple_card_remove,
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000423};
424
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000425module_platform_driver(asoc_simple_card);
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000426
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000427MODULE_ALIAS("platform:asoc-simple-scu-card");
Kuninori Morimoto93bc0472016-08-25 01:56:38 +0000428MODULE_LICENSE("GPL v2");
Kuninori Morimoto53e682b2016-08-23 01:34:17 +0000429MODULE_DESCRIPTION("ASoC Simple SCU Sound Card");
Kuninori Morimoto415f1cb2015-03-26 04:01:27 +0000430MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");