Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / sound / soc / generic / simple-card.c
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 #include <linux/clk.h>
12 #include <linux/device.h>
13 #include <linux/gpio.h>
14 #include <linux/module.h>
15 #include <linux/of.h>
16 #include <linux/of_gpio.h>
17 #include <linux/platform_device.h>
18 #include <linux/string.h>
19 #include <sound/jack.h>
20 #include <sound/simple_card.h>
21 #include <sound/soc-dai.h>
22 #include <sound/soc.h>
23
24 struct simple_card_data {
25         struct snd_soc_card snd_card;
26         struct simple_dai_props {
27                 struct asoc_simple_dai cpu_dai;
28                 struct asoc_simple_dai codec_dai;
29         } *dai_props;
30         unsigned int mclk_fs;
31         int gpio_hp_det;
32         int gpio_hp_det_invert;
33         int gpio_mic_det;
34         int gpio_mic_det_invert;
35         struct snd_soc_dai_link dai_link[];     /* dynamically allocated */
36 };
37
38 #define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
39 #define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + i)
40 #define simple_priv_to_props(priv, i) ((priv)->dai_props + i)
41
42 static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
43 {
44         struct snd_soc_pcm_runtime *rtd = substream->private_data;
45         struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
46         struct simple_dai_props *dai_props =
47                 &priv->dai_props[rtd - rtd->card->rtd];
48         int ret;
49
50         ret = clk_prepare_enable(dai_props->cpu_dai.clk);
51         if (ret)
52                 return ret;
53         
54         ret = clk_prepare_enable(dai_props->codec_dai.clk);
55         if (ret)
56                 clk_disable_unprepare(dai_props->cpu_dai.clk);
57
58         return ret;
59 }
60
61 static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
62 {
63         struct snd_soc_pcm_runtime *rtd = substream->private_data;
64         struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
65         struct simple_dai_props *dai_props =
66                 &priv->dai_props[rtd - rtd->card->rtd];
67
68         clk_disable_unprepare(dai_props->cpu_dai.clk);
69
70         clk_disable_unprepare(dai_props->codec_dai.clk);
71 }
72
73 static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
74                                       struct snd_pcm_hw_params *params)
75 {
76         struct snd_soc_pcm_runtime *rtd = substream->private_data;
77         struct snd_soc_dai *codec_dai = rtd->codec_dai;
78         struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
79         unsigned int mclk;
80         int ret = 0;
81
82         if (priv->mclk_fs) {
83                 mclk = params_rate(params) * priv->mclk_fs;
84                 ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
85                                              SND_SOC_CLOCK_IN);
86         }
87
88         return ret;
89 }
90
91 static struct snd_soc_ops asoc_simple_card_ops = {
92         .startup = asoc_simple_card_startup,
93         .shutdown = asoc_simple_card_shutdown,
94         .hw_params = asoc_simple_card_hw_params,
95 };
96
97 static struct snd_soc_jack simple_card_hp_jack;
98 static struct snd_soc_jack_pin simple_card_hp_jack_pins[] = {
99         {
100                 .pin = "Headphones",
101                 .mask = SND_JACK_HEADPHONE,
102         },
103 };
104 static struct snd_soc_jack_gpio simple_card_hp_jack_gpio = {
105         .name = "Headphone detection",
106         .report = SND_JACK_HEADPHONE,
107         .debounce_time = 150,
108 };
109
110 static struct snd_soc_jack simple_card_mic_jack;
111 static struct snd_soc_jack_pin simple_card_mic_jack_pins[] = {
112         {
113                 .pin = "Mic Jack",
114                 .mask = SND_JACK_MICROPHONE,
115         },
116 };
117 static struct snd_soc_jack_gpio simple_card_mic_jack_gpio = {
118         .name = "Mic detection",
119         .report = SND_JACK_MICROPHONE,
120         .debounce_time = 150,
121 };
122
123 static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
124                                        struct asoc_simple_dai *set)
125 {
126         int ret;
127
128         if (set->sysclk) {
129                 ret = snd_soc_dai_set_sysclk(dai, 0, set->sysclk, 0);
130                 if (ret && ret != -ENOTSUPP) {
131                         dev_err(dai->dev, "simple-card: set_sysclk error\n");
132                         goto err;
133                 }
134         }
135
136         if (set->slots) {
137                 ret = snd_soc_dai_set_tdm_slot(dai, 0, 0,
138                                                 set->slots,
139                                                 set->slot_width);
140                 if (ret && ret != -ENOTSUPP) {
141                         dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
142                         goto err;
143                 }
144         }
145
146         ret = 0;
147
148 err:
149         return ret;
150 }
151
152 static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
153 {
154         struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
155         struct snd_soc_dai *codec = rtd->codec_dai;
156         struct snd_soc_dai *cpu = rtd->cpu_dai;
157         struct simple_dai_props *dai_props;
158         int num, ret;
159
160         num = rtd - rtd->card->rtd;
161         dai_props = &priv->dai_props[num];
162         ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai);
163         if (ret < 0)
164                 return ret;
165
166         ret = __asoc_simple_card_dai_init(cpu, &dai_props->cpu_dai);
167         if (ret < 0)
168                 return ret;
169
170         if (gpio_is_valid(priv->gpio_hp_det)) {
171                 snd_soc_card_jack_new(rtd->card, "Headphones",
172                                       SND_JACK_HEADPHONE,
173                                       &simple_card_hp_jack,
174                                       simple_card_hp_jack_pins,
175                                       ARRAY_SIZE(simple_card_hp_jack_pins));
176
177                 simple_card_hp_jack_gpio.gpio = priv->gpio_hp_det;
178                 simple_card_hp_jack_gpio.invert = priv->gpio_hp_det_invert;
179                 snd_soc_jack_add_gpios(&simple_card_hp_jack, 1,
180                                        &simple_card_hp_jack_gpio);
181         }
182
183         if (gpio_is_valid(priv->gpio_mic_det)) {
184                 snd_soc_card_jack_new(rtd->card, "Mic Jack",
185                                       SND_JACK_MICROPHONE,
186                                       &simple_card_mic_jack,
187                                       simple_card_mic_jack_pins,
188                                       ARRAY_SIZE(simple_card_mic_jack_pins));
189                 simple_card_mic_jack_gpio.gpio = priv->gpio_mic_det;
190                 simple_card_mic_jack_gpio.invert = priv->gpio_mic_det_invert;
191                 snd_soc_jack_add_gpios(&simple_card_mic_jack, 1,
192                                        &simple_card_mic_jack_gpio);
193         }
194         return 0;
195 }
196
197 static int
198 asoc_simple_card_sub_parse_of(struct device_node *np,
199                               struct asoc_simple_dai *dai,
200                               struct device_node **p_node,
201                               const char **name,
202                               int *args_count)
203 {
204         struct of_phandle_args args;
205         struct clk *clk;
206         u32 val;
207         int ret;
208
209         /*
210          * Get node via "sound-dai = <&phandle port>"
211          * it will be used as xxx_of_node on soc_bind_dai_link()
212          */
213         ret = of_parse_phandle_with_args(np, "sound-dai",
214                                          "#sound-dai-cells", 0, &args);
215         if (ret)
216                 return ret;
217
218         *p_node = args.np;
219
220         if (args_count)
221                 *args_count = args.args_count;
222
223         /* Get dai->name */
224         ret = snd_soc_of_get_dai_name(np, name);
225         if (ret < 0)
226                 return ret;
227
228         /* Parse TDM slot */
229         ret = snd_soc_of_parse_tdm_slot(np, &dai->slots, &dai->slot_width);
230         if (ret)
231                 return ret;
232
233         /*
234          * Parse dai->sysclk come from "clocks = <&xxx>"
235          * (if system has common clock)
236          *  or "system-clock-frequency = <xxx>"
237          *  or device's module clock.
238          */
239         if (of_property_read_bool(np, "clocks")) {
240                 clk = of_clk_get(np, 0);
241                 if (IS_ERR(clk)) {
242                         ret = PTR_ERR(clk);
243                         return ret;
244                 }
245
246                 dai->sysclk = clk_get_rate(clk);
247                 dai->clk = clk;
248         } else if (!of_property_read_u32(np, "system-clock-frequency", &val)) {
249                 dai->sysclk = val;
250         } else {
251                 clk = of_clk_get(args.np, 0);
252                 if (!IS_ERR(clk))
253                         dai->sysclk = clk_get_rate(clk);
254         }
255
256         return 0;
257 }
258
259 static int asoc_simple_card_parse_daifmt(struct device_node *node,
260                                          struct simple_card_data *priv,
261                                          struct device_node *codec,
262                                          char *prefix, int idx)
263 {
264         struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
265         struct device *dev = simple_priv_to_dev(priv);
266         struct device_node *bitclkmaster = NULL;
267         struct device_node *framemaster = NULL;
268         unsigned int daifmt;
269
270         daifmt = snd_soc_of_parse_daifmt(node, prefix,
271                                          &bitclkmaster, &framemaster);
272         daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
273
274         if (strlen(prefix) && !bitclkmaster && !framemaster) {
275                 /*
276                  * No dai-link level and master setting was not found from
277                  * sound node level, revert back to legacy DT parsing and
278                  * take the settings from codec node.
279                  */
280                 dev_dbg(dev, "Revert to legacy daifmt parsing\n");
281
282                 daifmt = snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
283                         (daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
284         } else {
285                 if (codec == bitclkmaster)
286                         daifmt |= (codec == framemaster) ?
287                                 SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
288                 else
289                         daifmt |= (codec == framemaster) ?
290                                 SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
291         }
292
293         dai_link->dai_fmt = daifmt;
294
295         of_node_put(bitclkmaster);
296         of_node_put(framemaster);
297
298         return 0;
299 }
300
301 static int asoc_simple_card_dai_link_of(struct device_node *node,
302                                         struct simple_card_data *priv,
303                                         int idx,
304                                         bool is_top_level_node)
305 {
306         struct device *dev = simple_priv_to_dev(priv);
307         struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
308         struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);
309         struct device_node *cpu = NULL;
310         struct device_node *codec = NULL;
311         char *name;
312         char prop[128];
313         char *prefix = "";
314         int ret, cpu_args;
315
316         /* For single DAI link & old style of DT node */
317         if (is_top_level_node)
318                 prefix = "simple-audio-card,";
319
320         snprintf(prop, sizeof(prop), "%scpu", prefix);
321         cpu = of_get_child_by_name(node, prop);
322
323         snprintf(prop, sizeof(prop), "%scodec", prefix);
324         codec = of_get_child_by_name(node, prop);
325
326         if (!cpu || !codec) {
327                 ret = -EINVAL;
328                 dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
329                 goto dai_link_of_err;
330         }
331
332         ret = asoc_simple_card_parse_daifmt(node, priv,
333                                             codec, prefix, idx);
334         if (ret < 0)
335                 goto dai_link_of_err;
336
337         ret = asoc_simple_card_sub_parse_of(cpu, &dai_props->cpu_dai,
338                                             &dai_link->cpu_of_node,
339                                             &dai_link->cpu_dai_name,
340                                             &cpu_args);
341         if (ret < 0)
342                 goto dai_link_of_err;
343
344         ret = asoc_simple_card_sub_parse_of(codec, &dai_props->codec_dai,
345                                             &dai_link->codec_of_node,
346                                             &dai_link->codec_dai_name, NULL);
347         if (ret < 0)
348                 goto dai_link_of_err;
349
350         if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
351                 ret = -EINVAL;
352                 goto dai_link_of_err;
353         }
354
355         /* Simple Card assumes platform == cpu */
356         dai_link->platform_of_node = dai_link->cpu_of_node;
357
358         /* DAI link name is created from CPU/CODEC dai name */
359         name = devm_kzalloc(dev,
360                             strlen(dai_link->cpu_dai_name)   +
361                             strlen(dai_link->codec_dai_name) + 2,
362                             GFP_KERNEL);
363         if (!name) {
364                 ret = -ENOMEM;
365                 goto dai_link_of_err;
366         }
367
368         sprintf(name, "%s-%s", dai_link->cpu_dai_name,
369                                 dai_link->codec_dai_name);
370         dai_link->name = dai_link->stream_name = name;
371         dai_link->ops = &asoc_simple_card_ops;
372         dai_link->init = asoc_simple_card_dai_init;
373
374         dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
375         dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
376         dev_dbg(dev, "\tcpu : %s / %d\n",
377                 dai_link->cpu_dai_name,
378                 dai_props->cpu_dai.sysclk);
379         dev_dbg(dev, "\tcodec : %s / %d\n",
380                 dai_link->codec_dai_name,
381                 dai_props->codec_dai.sysclk);
382
383         /*
384          * In soc_bind_dai_link() will check cpu name after
385          * of_node matching if dai_link has cpu_dai_name.
386          * but, it will never match if name was created by
387          * fmt_single_name() remove cpu_dai_name if cpu_args
388          * was 0. See:
389          *      fmt_single_name()
390          *      fmt_multiple_name()
391          */
392         if (!cpu_args)
393                 dai_link->cpu_dai_name = NULL;
394
395 dai_link_of_err:
396         of_node_put(cpu);
397         of_node_put(codec);
398
399         return ret;
400 }
401
402 static int asoc_simple_card_parse_of(struct device_node *node,
403                                      struct simple_card_data *priv)
404 {
405         struct device *dev = simple_priv_to_dev(priv);
406         enum of_gpio_flags flags;
407         u32 val;
408         int ret;
409
410         if (!node)
411                 return -EINVAL;
412
413         /* Parse the card name from DT */
414         snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name");
415
416         /* The off-codec widgets */
417         if (of_property_read_bool(node, "simple-audio-card,widgets")) {
418                 ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
419                                         "simple-audio-card,widgets");
420                 if (ret)
421                         return ret;
422         }
423
424         /* DAPM routes */
425         if (of_property_read_bool(node, "simple-audio-card,routing")) {
426                 ret = snd_soc_of_parse_audio_routing(&priv->snd_card,
427                                         "simple-audio-card,routing");
428                 if (ret)
429                         return ret;
430         }
431
432         /* Factor to mclk, used in hw_params() */
433         ret = of_property_read_u32(node, "simple-audio-card,mclk-fs", &val);
434         if (ret == 0)
435                 priv->mclk_fs = val;
436
437         dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?
438                 priv->snd_card.name : "");
439
440         /* Single/Muti DAI link(s) & New style of DT node */
441         if (of_get_child_by_name(node, "simple-audio-card,dai-link")) {
442                 struct device_node *np = NULL;
443                 int i = 0;
444
445                 for_each_child_of_node(node, np) {
446                         dev_dbg(dev, "\tlink %d:\n", i);
447                         ret = asoc_simple_card_dai_link_of(np, priv,
448                                                            i, false);
449                         if (ret < 0) {
450                                 of_node_put(np);
451                                 return ret;
452                         }
453                         i++;
454                 }
455         } else {
456                 /* For single DAI link & old style of DT node */
457                 ret = asoc_simple_card_dai_link_of(node, priv, 0, true);
458                 if (ret < 0)
459                         return ret;
460         }
461
462         priv->gpio_hp_det = of_get_named_gpio_flags(node,
463                                 "simple-audio-card,hp-det-gpio", 0, &flags);
464         priv->gpio_hp_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW);
465         if (priv->gpio_hp_det == -EPROBE_DEFER)
466                 return -EPROBE_DEFER;
467
468         priv->gpio_mic_det = of_get_named_gpio_flags(node,
469                                 "simple-audio-card,mic-det-gpio", 0, &flags);
470         priv->gpio_mic_det_invert = !!(flags & OF_GPIO_ACTIVE_LOW);
471         if (priv->gpio_mic_det == -EPROBE_DEFER)
472                 return -EPROBE_DEFER;
473
474         if (!priv->snd_card.name)
475                 priv->snd_card.name = priv->snd_card.dai_link->name;
476
477         return 0;
478 }
479
480 /* Decrease the reference count of the device nodes */
481 static int asoc_simple_card_unref(struct snd_soc_card *card)
482 {
483         struct snd_soc_dai_link *dai_link;
484         int num_links;
485
486         for (num_links = 0, dai_link = card->dai_link;
487              num_links < card->num_links;
488              num_links++, dai_link++) {
489                 of_node_put(dai_link->cpu_of_node);
490                 of_node_put(dai_link->codec_of_node);
491         }
492         return 0;
493 }
494
495 static int asoc_simple_card_probe(struct platform_device *pdev)
496 {
497         struct simple_card_data *priv;
498         struct snd_soc_dai_link *dai_link;
499         struct device_node *np = pdev->dev.of_node;
500         struct device *dev = &pdev->dev;
501         int num_links, ret;
502
503         /* Get the number of DAI links */
504         if (np && of_get_child_by_name(np, "simple-audio-card,dai-link"))
505                 num_links = of_get_child_count(np);
506         else
507                 num_links = 1;
508
509         /* Allocate the private data and the DAI link array */
510         priv = devm_kzalloc(dev,
511                         sizeof(*priv) + sizeof(*dai_link) * num_links,
512                         GFP_KERNEL);
513         if (!priv)
514                 return -ENOMEM;
515
516         /* Init snd_soc_card */
517         priv->snd_card.owner = THIS_MODULE;
518         priv->snd_card.dev = dev;
519         dai_link = priv->dai_link;
520         priv->snd_card.dai_link = dai_link;
521         priv->snd_card.num_links = num_links;
522
523         priv->gpio_hp_det = -ENOENT;
524         priv->gpio_mic_det = -ENOENT;
525
526         /* Get room for the other properties */
527         priv->dai_props = devm_kzalloc(dev,
528                         sizeof(*priv->dai_props) * num_links,
529                         GFP_KERNEL);
530         if (!priv->dai_props)
531                 return -ENOMEM;
532
533         if (np && of_device_is_available(np)) {
534
535                 ret = asoc_simple_card_parse_of(np, priv);
536                 if (ret < 0) {
537                         if (ret != -EPROBE_DEFER)
538                                 dev_err(dev, "parse error %d\n", ret);
539                         goto err;
540                 }
541
542         } else {
543                 struct asoc_simple_card_info *cinfo;
544
545                 cinfo = dev->platform_data;
546                 if (!cinfo) {
547                         dev_err(dev, "no info for asoc-simple-card\n");
548                         return -EINVAL;
549                 }
550
551                 if (!cinfo->name ||
552                     !cinfo->codec_dai.name ||
553                     !cinfo->codec ||
554                     !cinfo->platform ||
555                     !cinfo->cpu_dai.name) {
556                         dev_err(dev, "insufficient asoc_simple_card_info settings\n");
557                         return -EINVAL;
558                 }
559
560                 priv->snd_card.name     = (cinfo->card) ? cinfo->card : cinfo->name;
561                 dai_link->name          = cinfo->name;
562                 dai_link->stream_name   = cinfo->name;
563                 dai_link->platform_name = cinfo->platform;
564                 dai_link->codec_name    = cinfo->codec;
565                 dai_link->cpu_dai_name  = cinfo->cpu_dai.name;
566                 dai_link->codec_dai_name = cinfo->codec_dai.name;
567                 dai_link->dai_fmt       = cinfo->daifmt;
568                 dai_link->init          = asoc_simple_card_dai_init;
569                 memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai,
570                                         sizeof(priv->dai_props->cpu_dai));
571                 memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
572                                         sizeof(priv->dai_props->codec_dai));
573
574         }
575
576         snd_soc_card_set_drvdata(&priv->snd_card, priv);
577
578         ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
579         if (ret >= 0)
580                 return ret;
581
582 err:
583         asoc_simple_card_unref(&priv->snd_card);
584         return ret;
585 }
586
587 static int asoc_simple_card_remove(struct platform_device *pdev)
588 {
589         struct snd_soc_card *card = platform_get_drvdata(pdev);
590         struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
591
592         if (gpio_is_valid(priv->gpio_hp_det))
593                 snd_soc_jack_free_gpios(&simple_card_hp_jack, 1,
594                                         &simple_card_hp_jack_gpio);
595         if (gpio_is_valid(priv->gpio_mic_det))
596                 snd_soc_jack_free_gpios(&simple_card_mic_jack, 1,
597                                         &simple_card_mic_jack_gpio);
598
599         return asoc_simple_card_unref(card);
600 }
601
602 static const struct of_device_id asoc_simple_of_match[] = {
603         { .compatible = "simple-audio-card", },
604         {},
605 };
606 MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
607
608 static struct platform_driver asoc_simple_card = {
609         .driver = {
610                 .name = "asoc-simple-card",
611                 .of_match_table = asoc_simple_of_match,
612         },
613         .probe = asoc_simple_card_probe,
614         .remove = asoc_simple_card_remove,
615 };
616
617 module_platform_driver(asoc_simple_card);
618
619 MODULE_ALIAS("platform:asoc-simple-card");
620 MODULE_LICENSE("GPL");
621 MODULE_DESCRIPTION("ASoC Simple Sound Card");
622 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");