~hui.wang/alsa-driver/dkms-packaging.audiosdw-ppa

« back to all changes in this revision

Viewing changes to buildroot/src/oem-audiosdw-lp1836324-0.6ubuntu1.2/soc/generic/simple-card-utils.c

  • Committer: Hui Wang
  • Date: 2019-12-13 02:41:40 UTC
  • Revision ID: hui.wang@canonical.com-20191213024140-1cprdcbl3122fn85
insert pc-oem-dkms

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// SPDX-License-Identifier: GPL-2.0
2
 
//
3
 
// simple-card-utils.c
4
 
//
5
 
// Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6
 
 
7
 
#include <linux/clk.h>
8
 
#include <linux/gpio.h>
9
 
#include <linux/gpio/consumer.h>
10
 
#include <linux/module.h>
11
 
#include <linux/of.h>
12
 
#include <linux/of_gpio.h>
13
 
#include <linux/of_graph.h>
14
 
#include <sound/jack.h>
15
 
#include <sound/simple_card_utils.h>
16
 
 
17
 
void asoc_simple_convert_fixup(struct asoc_simple_data *data,
18
 
                               struct snd_pcm_hw_params *params)
19
 
{
20
 
        struct snd_interval *rate = hw_param_interval(params,
21
 
                                                SNDRV_PCM_HW_PARAM_RATE);
22
 
        struct snd_interval *channels = hw_param_interval(params,
23
 
                                                SNDRV_PCM_HW_PARAM_CHANNELS);
24
 
 
25
 
        if (data->convert_rate)
26
 
                rate->min =
27
 
                rate->max = data->convert_rate;
28
 
 
29
 
        if (data->convert_channels)
30
 
                channels->min =
31
 
                channels->max = data->convert_channels;
32
 
}
33
 
EXPORT_SYMBOL_GPL(asoc_simple_convert_fixup);
34
 
 
35
 
void asoc_simple_parse_convert(struct device *dev,
36
 
                               struct device_node *np,
37
 
                               char *prefix,
38
 
                               struct asoc_simple_data *data)
39
 
{
40
 
        char prop[128];
41
 
 
42
 
        if (!prefix)
43
 
                prefix = "";
44
 
 
45
 
        /* sampling rate convert */
46
 
        snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-rate");
47
 
        of_property_read_u32(np, prop, &data->convert_rate);
48
 
 
49
 
        /* channels transfer */
50
 
        snprintf(prop, sizeof(prop), "%s%s", prefix, "convert-channels");
51
 
        of_property_read_u32(np, prop, &data->convert_channels);
52
 
}
53
 
EXPORT_SYMBOL_GPL(asoc_simple_parse_convert);
54
 
 
55
 
int asoc_simple_parse_daifmt(struct device *dev,
56
 
                             struct device_node *node,
57
 
                             struct device_node *codec,
58
 
                             char *prefix,
59
 
                             unsigned int *retfmt)
60
 
{
61
 
        struct device_node *bitclkmaster = NULL;
62
 
        struct device_node *framemaster = NULL;
63
 
        unsigned int daifmt;
64
 
 
65
 
        daifmt = snd_soc_of_parse_daifmt(node, prefix,
66
 
                                         &bitclkmaster, &framemaster);
67
 
        daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
68
 
 
69
 
        if (!bitclkmaster && !framemaster) {
70
 
                /*
71
 
                 * No dai-link level and master setting was not found from
72
 
                 * sound node level, revert back to legacy DT parsing and
73
 
                 * take the settings from codec node.
74
 
                 */
75
 
                dev_dbg(dev, "Revert to legacy daifmt parsing\n");
76
 
 
77
 
                daifmt = snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
78
 
                        (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
79
 
        } else {
80
 
                if (codec == bitclkmaster)
81
 
                        daifmt |= (codec == framemaster) ?
82
 
                                SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
83
 
                else
84
 
                        daifmt |= (codec == framemaster) ?
85
 
                                SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
86
 
        }
87
 
 
88
 
        of_node_put(bitclkmaster);
89
 
        of_node_put(framemaster);
90
 
 
91
 
        *retfmt = daifmt;
92
 
 
93
 
        return 0;
94
 
}
95
 
EXPORT_SYMBOL_GPL(asoc_simple_parse_daifmt);
96
 
 
97
 
int asoc_simple_set_dailink_name(struct device *dev,
98
 
                                 struct snd_soc_dai_link *dai_link,
99
 
                                 const char *fmt, ...)
100
 
{
101
 
        va_list ap;
102
 
        char *name = NULL;
103
 
        int ret = -ENOMEM;
104
 
 
105
 
        va_start(ap, fmt);
106
 
        name = devm_kvasprintf(dev, GFP_KERNEL, fmt, ap);
107
 
        va_end(ap);
108
 
 
109
 
        if (name) {
110
 
                ret = 0;
111
 
 
112
 
                dai_link->name          = name;
113
 
                dai_link->stream_name   = name;
114
 
        }
115
 
 
116
 
        return ret;
117
 
}
118
 
EXPORT_SYMBOL_GPL(asoc_simple_set_dailink_name);
119
 
 
120
 
int asoc_simple_parse_card_name(struct snd_soc_card *card,
121
 
                                char *prefix)
122
 
{
123
 
        int ret;
124
 
 
125
 
        if (!prefix)
126
 
                prefix = "";
127
 
 
128
 
        /* Parse the card name from DT */
129
 
        ret = snd_soc_of_parse_card_name(card, "label");
130
 
        if (ret < 0 || !card->name) {
131
 
                char prop[128];
132
 
 
133
 
                snprintf(prop, sizeof(prop), "%sname", prefix);
134
 
                ret = snd_soc_of_parse_card_name(card, prop);
135
 
                if (ret < 0)
136
 
                        return ret;
137
 
        }
138
 
 
139
 
        if (!card->name && card->dai_link)
140
 
                card->name = card->dai_link->name;
141
 
 
142
 
        return 0;
143
 
}
144
 
EXPORT_SYMBOL_GPL(asoc_simple_parse_card_name);
145
 
 
146
 
static int asoc_simple_clk_enable(struct asoc_simple_dai *dai)
147
 
{
148
 
        if (dai)
149
 
                return clk_prepare_enable(dai->clk);
150
 
 
151
 
        return 0;
152
 
}
153
 
 
154
 
static void asoc_simple_clk_disable(struct asoc_simple_dai *dai)
155
 
{
156
 
        if (dai)
157
 
                clk_disable_unprepare(dai->clk);
158
 
}
159
 
 
160
 
int asoc_simple_parse_clk(struct device *dev,
161
 
                          struct device_node *node,
162
 
                          struct asoc_simple_dai *simple_dai,
163
 
                          struct snd_soc_dai_link_component *dlc)
164
 
{
165
 
        struct clk *clk;
166
 
        u32 val;
167
 
 
168
 
        /*
169
 
         * Parse dai->sysclk come from "clocks = <&xxx>"
170
 
         * (if system has common clock)
171
 
         *  or "system-clock-frequency = <xxx>"
172
 
         *  or device's module clock.
173
 
         */
174
 
        clk = devm_get_clk_from_child(dev, node, NULL);
175
 
        if (!IS_ERR(clk)) {
176
 
                simple_dai->sysclk = clk_get_rate(clk);
177
 
 
178
 
                simple_dai->clk = clk;
179
 
        } else if (!of_property_read_u32(node, "system-clock-frequency", &val)) {
180
 
                simple_dai->sysclk = val;
181
 
        } else {
182
 
                clk = devm_get_clk_from_child(dev, dlc->of_node, NULL);
183
 
                if (!IS_ERR(clk))
184
 
                        simple_dai->sysclk = clk_get_rate(clk);
185
 
        }
186
 
 
187
 
        if (of_property_read_bool(node, "system-clock-direction-out"))
188
 
                simple_dai->clk_direction = SND_SOC_CLOCK_OUT;
189
 
 
190
 
        return 0;
191
 
}
192
 
EXPORT_SYMBOL_GPL(asoc_simple_parse_clk);
193
 
 
194
 
int asoc_simple_startup(struct snd_pcm_substream *substream)
195
 
{
196
 
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
197
 
        struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
198
 
        struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
199
 
        int ret;
200
 
 
201
 
        ret = asoc_simple_clk_enable(dai_props->cpu_dai);
202
 
        if (ret)
203
 
                return ret;
204
 
 
205
 
        ret = asoc_simple_clk_enable(dai_props->codec_dai);
206
 
        if (ret)
207
 
                asoc_simple_clk_disable(dai_props->cpu_dai);
208
 
 
209
 
        return ret;
210
 
}
211
 
EXPORT_SYMBOL_GPL(asoc_simple_startup);
212
 
 
213
 
void asoc_simple_shutdown(struct snd_pcm_substream *substream)
214
 
{
215
 
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
216
 
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
217
 
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
218
 
        struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
219
 
        struct simple_dai_props *dai_props =
220
 
                simple_priv_to_props(priv, rtd->num);
221
 
 
222
 
        if (dai_props->mclk_fs) {
223
 
                snd_soc_dai_set_sysclk(codec_dai, 0, 0, SND_SOC_CLOCK_IN);
224
 
                snd_soc_dai_set_sysclk(cpu_dai, 0, 0, SND_SOC_CLOCK_OUT);
225
 
        }
226
 
 
227
 
        asoc_simple_clk_disable(dai_props->cpu_dai);
228
 
 
229
 
        asoc_simple_clk_disable(dai_props->codec_dai);
230
 
}
231
 
EXPORT_SYMBOL_GPL(asoc_simple_shutdown);
232
 
 
233
 
static int asoc_simple_set_clk_rate(struct asoc_simple_dai *simple_dai,
234
 
                                    unsigned long rate)
235
 
{
236
 
        if (!simple_dai)
237
 
                return 0;
238
 
 
239
 
        if (!simple_dai->clk)
240
 
                return 0;
241
 
 
242
 
        if (clk_get_rate(simple_dai->clk) == rate)
243
 
                return 0;
244
 
 
245
 
        return clk_set_rate(simple_dai->clk, rate);
246
 
}
247
 
 
248
 
int asoc_simple_hw_params(struct snd_pcm_substream *substream,
249
 
                          struct snd_pcm_hw_params *params)
250
 
{
251
 
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
252
 
        struct snd_soc_dai *codec_dai = rtd->codec_dai;
253
 
        struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
254
 
        struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
255
 
        struct simple_dai_props *dai_props =
256
 
                simple_priv_to_props(priv, rtd->num);
257
 
        unsigned int mclk, mclk_fs = 0;
258
 
        int ret = 0;
259
 
 
260
 
        if (dai_props->mclk_fs)
261
 
                mclk_fs = dai_props->mclk_fs;
262
 
 
263
 
        if (mclk_fs) {
264
 
                mclk = params_rate(params) * mclk_fs;
265
 
 
266
 
                ret = asoc_simple_set_clk_rate(dai_props->codec_dai, mclk);
267
 
                if (ret < 0)
268
 
                        return ret;
269
 
 
270
 
                ret = asoc_simple_set_clk_rate(dai_props->cpu_dai, mclk);
271
 
                if (ret < 0)
272
 
                        return ret;
273
 
 
274
 
                ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
275
 
                                             SND_SOC_CLOCK_IN);
276
 
                if (ret && ret != -ENOTSUPP)
277
 
                        goto err;
278
 
 
279
 
                ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
280
 
                                             SND_SOC_CLOCK_OUT);
281
 
                if (ret && ret != -ENOTSUPP)
282
 
                        goto err;
283
 
        }
284
 
        return 0;
285
 
err:
286
 
        return ret;
287
 
}
288
 
EXPORT_SYMBOL_GPL(asoc_simple_hw_params);
289
 
 
290
 
int asoc_simple_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
291
 
                                   struct snd_pcm_hw_params *params)
292
 
{
293
 
        struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
294
 
        struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
295
 
 
296
 
        asoc_simple_convert_fixup(&dai_props->adata, params);
297
 
 
298
 
        return 0;
299
 
}
300
 
EXPORT_SYMBOL_GPL(asoc_simple_be_hw_params_fixup);
301
 
 
302
 
static int asoc_simple_init_dai(struct snd_soc_dai *dai,
303
 
                                     struct asoc_simple_dai *simple_dai)
304
 
{
305
 
        int ret;
306
 
 
307
 
        if (!simple_dai)
308
 
                return 0;
309
 
 
310
 
        if (simple_dai->sysclk) {
311
 
                ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk,
312
 
                                             simple_dai->clk_direction);
313
 
                if (ret && ret != -ENOTSUPP) {
314
 
                        dev_err(dai->dev, "simple-card: set_sysclk error\n");
315
 
                        return ret;
316
 
                }
317
 
        }
318
 
 
319
 
        if (simple_dai->slots) {
320
 
                ret = snd_soc_dai_set_tdm_slot(dai,
321
 
                                               simple_dai->tx_slot_mask,
322
 
                                               simple_dai->rx_slot_mask,
323
 
                                               simple_dai->slots,
324
 
                                               simple_dai->slot_width);
325
 
                if (ret && ret != -ENOTSUPP) {
326
 
                        dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
327
 
                        return ret;
328
 
                }
329
 
        }
330
 
 
331
 
        return 0;
332
 
}
333
 
 
334
 
int asoc_simple_dai_init(struct snd_soc_pcm_runtime *rtd)
335
 
{
336
 
        struct asoc_simple_priv *priv = snd_soc_card_get_drvdata(rtd->card);
337
 
        struct simple_dai_props *dai_props = simple_priv_to_props(priv, rtd->num);
338
 
        int ret;
339
 
 
340
 
        ret = asoc_simple_init_dai(rtd->codec_dai,
341
 
                                   dai_props->codec_dai);
342
 
        if (ret < 0)
343
 
                return ret;
344
 
 
345
 
        ret = asoc_simple_init_dai(rtd->cpu_dai,
346
 
                                   dai_props->cpu_dai);
347
 
        if (ret < 0)
348
 
                return ret;
349
 
 
350
 
        return 0;
351
 
}
352
 
EXPORT_SYMBOL_GPL(asoc_simple_dai_init);
353
 
 
354
 
void asoc_simple_canonicalize_platform(struct snd_soc_dai_link *dai_link)
355
 
{
356
 
        /* Assumes platform == cpu */
357
 
        if (!dai_link->platforms->of_node)
358
 
                dai_link->platforms->of_node = dai_link->cpus->of_node;
359
 
 
360
 
        /*
361
 
         * DPCM BE can be no platform.
362
 
         * Alloced memory will be waste, but not leak.
363
 
         */
364
 
        if (!dai_link->platforms->of_node)
365
 
                dai_link->num_platforms = 0;
366
 
}
367
 
EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_platform);
368
 
 
369
 
void asoc_simple_canonicalize_cpu(struct snd_soc_dai_link *dai_link,
370
 
                                  int is_single_links)
371
 
{
372
 
        /*
373
 
         * In soc_bind_dai_link() will check cpu name after
374
 
         * of_node matching if dai_link has cpu_dai_name.
375
 
         * but, it will never match if name was created by
376
 
         * fmt_single_name() remove cpu_dai_name if cpu_args
377
 
         * was 0. See:
378
 
         *      fmt_single_name()
379
 
         *      fmt_multiple_name()
380
 
         */
381
 
        if (is_single_links)
382
 
                dai_link->cpus->dai_name = NULL;
383
 
}
384
 
EXPORT_SYMBOL_GPL(asoc_simple_canonicalize_cpu);
385
 
 
386
 
int asoc_simple_clean_reference(struct snd_soc_card *card)
387
 
{
388
 
        struct snd_soc_dai_link *dai_link;
389
 
        int i;
390
 
 
391
 
        for_each_card_prelinks(card, i, dai_link) {
392
 
                of_node_put(dai_link->cpus->of_node);
393
 
                of_node_put(dai_link->codecs->of_node);
394
 
        }
395
 
        return 0;
396
 
}
397
 
EXPORT_SYMBOL_GPL(asoc_simple_clean_reference);
398
 
 
399
 
int asoc_simple_parse_routing(struct snd_soc_card *card,
400
 
                              char *prefix)
401
 
{
402
 
        struct device_node *node = card->dev->of_node;
403
 
        char prop[128];
404
 
 
405
 
        if (!prefix)
406
 
                prefix = "";
407
 
 
408
 
        snprintf(prop, sizeof(prop), "%s%s", prefix, "routing");
409
 
 
410
 
        if (!of_property_read_bool(node, prop))
411
 
                return 0;
412
 
 
413
 
        return snd_soc_of_parse_audio_routing(card, prop);
414
 
}
415
 
EXPORT_SYMBOL_GPL(asoc_simple_parse_routing);
416
 
 
417
 
int asoc_simple_parse_widgets(struct snd_soc_card *card,
418
 
                              char *prefix)
419
 
{
420
 
        struct device_node *node = card->dev->of_node;
421
 
        char prop[128];
422
 
 
423
 
        if (!prefix)
424
 
                prefix = "";
425
 
 
426
 
        snprintf(prop, sizeof(prop), "%s%s", prefix, "widgets");
427
 
 
428
 
        if (of_property_read_bool(node, prop))
429
 
                return snd_soc_of_parse_audio_simple_widgets(card, prop);
430
 
 
431
 
        /* no widgets is not error */
432
 
        return 0;
433
 
}
434
 
EXPORT_SYMBOL_GPL(asoc_simple_parse_widgets);
435
 
 
436
 
int asoc_simple_parse_pin_switches(struct snd_soc_card *card,
437
 
                                   char *prefix)
438
 
{
439
 
        const unsigned int nb_controls_max = 16;
440
 
        const char **strings, *control_name;
441
 
        struct snd_kcontrol_new *controls;
442
 
        struct device *dev = card->dev;
443
 
        unsigned int i, nb_controls;
444
 
        char prop[128];
445
 
        int ret;
446
 
 
447
 
        if (!prefix)
448
 
                prefix = "";
449
 
 
450
 
        snprintf(prop, sizeof(prop), "%s%s", prefix, "pin-switches");
451
 
 
452
 
        if (!of_property_read_bool(dev->of_node, prop))
453
 
                return 0;
454
 
 
455
 
        strings = devm_kcalloc(dev, nb_controls_max,
456
 
                               sizeof(*strings), GFP_KERNEL);
457
 
        if (!strings)
458
 
                return -ENOMEM;
459
 
 
460
 
        ret = of_property_read_string_array(dev->of_node, prop,
461
 
                                            strings, nb_controls_max);
462
 
        if (ret < 0)
463
 
                return ret;
464
 
 
465
 
        nb_controls = (unsigned int)ret;
466
 
 
467
 
        controls = devm_kcalloc(dev, nb_controls,
468
 
                                sizeof(*controls), GFP_KERNEL);
469
 
        if (!controls)
470
 
                return -ENOMEM;
471
 
 
472
 
        for (i = 0; i < nb_controls; i++) {
473
 
                control_name = devm_kasprintf(dev, GFP_KERNEL,
474
 
                                              "%s Switch", strings[i]);
475
 
                if (!control_name)
476
 
                        return -ENOMEM;
477
 
 
478
 
                controls[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;
479
 
                controls[i].name = control_name;
480
 
                controls[i].info = snd_soc_dapm_info_pin_switch;
481
 
                controls[i].get = snd_soc_dapm_get_pin_switch;
482
 
                controls[i].put = snd_soc_dapm_put_pin_switch;
483
 
                controls[i].private_value = (unsigned long)strings[i];
484
 
        }
485
 
 
486
 
        card->controls = controls;
487
 
        card->num_controls = nb_controls;
488
 
 
489
 
        return 0;
490
 
}
491
 
EXPORT_SYMBOL_GPL(asoc_simple_parse_pin_switches);
492
 
 
493
 
int asoc_simple_init_jack(struct snd_soc_card *card,
494
 
                          struct asoc_simple_jack *sjack,
495
 
                          int is_hp, char *prefix)
496
 
{
497
 
        struct device *dev = card->dev;
498
 
        enum of_gpio_flags flags;
499
 
        char prop[128];
500
 
        char *pin_name;
501
 
        char *gpio_name;
502
 
        int mask;
503
 
        int det;
504
 
 
505
 
        if (!prefix)
506
 
                prefix = "";
507
 
 
508
 
        sjack->gpio.gpio = -ENOENT;
509
 
 
510
 
        if (is_hp) {
511
 
                snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
512
 
                pin_name        = "Headphones";
513
 
                gpio_name       = "Headphone detection";
514
 
                mask            = SND_JACK_HEADPHONE;
515
 
        } else {
516
 
                snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
517
 
                pin_name        = "Mic Jack";
518
 
                gpio_name       = "Mic detection";
519
 
                mask            = SND_JACK_MICROPHONE;
520
 
        }
521
 
 
522
 
        det = of_get_named_gpio_flags(dev->of_node, prop, 0, &flags);
523
 
        if (det == -EPROBE_DEFER)
524
 
                return -EPROBE_DEFER;
525
 
 
526
 
        if (gpio_is_valid(det)) {
527
 
                sjack->pin.pin          = pin_name;
528
 
                sjack->pin.mask         = mask;
529
 
 
530
 
                sjack->gpio.name        = gpio_name;
531
 
                sjack->gpio.report      = mask;
532
 
                sjack->gpio.gpio        = det;
533
 
                sjack->gpio.invert      = !!(flags & OF_GPIO_ACTIVE_LOW);
534
 
                sjack->gpio.debounce_time = 150;
535
 
 
536
 
                snd_soc_card_jack_new(card, pin_name, mask,
537
 
                                      &sjack->jack,
538
 
                                      &sjack->pin, 1);
539
 
 
540
 
                snd_soc_jack_add_gpios(&sjack->jack, 1,
541
 
                                       &sjack->gpio);
542
 
        }
543
 
 
544
 
        return 0;
545
 
}
546
 
EXPORT_SYMBOL_GPL(asoc_simple_init_jack);
547
 
 
548
 
int asoc_simple_init_priv(struct asoc_simple_priv *priv,
549
 
                          struct link_info *li)
550
 
{
551
 
        struct snd_soc_card *card = simple_priv_to_card(priv);
552
 
        struct device *dev = simple_priv_to_dev(priv);
553
 
        struct snd_soc_dai_link *dai_link;
554
 
        struct simple_dai_props *dai_props;
555
 
        struct asoc_simple_dai *dais;
556
 
        struct snd_soc_codec_conf *cconf = NULL;
557
 
        int i;
558
 
 
559
 
        dai_props = devm_kcalloc(dev, li->link, sizeof(*dai_props), GFP_KERNEL);
560
 
        dai_link  = devm_kcalloc(dev, li->link, sizeof(*dai_link),  GFP_KERNEL);
561
 
        dais      = devm_kcalloc(dev, li->dais, sizeof(*dais),      GFP_KERNEL);
562
 
        if (!dai_props || !dai_link || !dais)
563
 
                return -ENOMEM;
564
 
 
565
 
        if (li->conf) {
566
 
                cconf = devm_kcalloc(dev, li->conf, sizeof(*cconf), GFP_KERNEL);
567
 
                if (!cconf)
568
 
                        return -ENOMEM;
569
 
        }
570
 
 
571
 
        /*
572
 
         * Use snd_soc_dai_link_component instead of legacy style
573
 
         * It is codec only. but cpu/platform will be supported in the future.
574
 
         * see
575
 
         *      soc-core.c :: snd_soc_init_multicodec()
576
 
         *
577
 
         * "platform" might be removed
578
 
         * see
579
 
         *      simple-card-utils.c :: asoc_simple_canonicalize_platform()
580
 
         */
581
 
        for (i = 0; i < li->link; i++) {
582
 
                dai_link[i].cpus                = &dai_props[i].cpus;
583
 
                dai_link[i].num_cpus            = 1;
584
 
                dai_link[i].codecs              = &dai_props[i].codecs;
585
 
                dai_link[i].num_codecs          = 1;
586
 
                dai_link[i].platforms           = &dai_props[i].platforms;
587
 
                dai_link[i].num_platforms       = 1;
588
 
        }
589
 
 
590
 
        priv->dai_props         = dai_props;
591
 
        priv->dai_link          = dai_link;
592
 
        priv->dais              = dais;
593
 
        priv->codec_conf        = cconf;
594
 
 
595
 
        card->dai_link          = priv->dai_link;
596
 
        card->num_links         = li->link;
597
 
        card->codec_conf        = cconf;
598
 
        card->num_configs       = li->conf;
599
 
 
600
 
        return 0;
601
 
}
602
 
EXPORT_SYMBOL_GPL(asoc_simple_init_priv);
603
 
 
604
 
/* Module information */
605
 
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
606
 
MODULE_DESCRIPTION("ALSA SoC Simple Card Utils");
607
 
MODULE_LICENSE("GPL v2");