Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
simple-card.c
Go to the documentation of this file.
1 /*
2  * ASoC simple sound card support
3  *
4  * Copyright (C) 2012 Renesas Solutions Corp.
5  * Kuninori Morimoto <[email protected]>
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 {
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 <[email protected]>");