]> bbs.cooldavid.org Git - net-next-2.6.git/blob - sound/soc/codecs/spdif_transciever.c
f0945ab2002eab8862647bb111e9e0b7dc236b2f
[net-next-2.6.git] / sound / soc / codecs / spdif_transciever.c
1 /*
2  * ALSA SoC SPDIF DIT driver
3  *
4  *  This driver is used by controllers which can operate in DIT (SPDI/F) where
5  *  no codec is needed.  This file provides stub codec that can be used
6  *  in these configurations. TI DaVinci Audio controller uses this driver.
7  *
8  * Author:      Steve Chen,  <schen@mvista.com>
9  * Copyright:   (C) 2009 MontaVista Software, Inc., <source@mvista.com>
10  * Copyright:   (C) 2009  Texas Instruments, India
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  */
16
17 #include <linux/module.h>
18 #include <linux/moduleparam.h>
19 #include <sound/soc.h>
20 #include <sound/pcm.h>
21 #include <sound/initval.h>
22
23 #include "spdif_transciever.h"
24
25 MODULE_LICENSE("GPL");
26
27 #define STUB_RATES      SNDRV_PCM_RATE_8000_96000
28 #define STUB_FORMATS    SNDRV_PCM_FMTBIT_S16_LE
29
30 static struct snd_soc_codec *spdif_dit_codec;
31
32 static int spdif_dit_codec_probe(struct platform_device *pdev)
33 {
34         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
35         struct snd_soc_codec *codec;
36         int ret;
37
38         if (spdif_dit_codec == NULL) {
39                 dev_err(&pdev->dev, "Codec device not registered\n");
40                 return -ENODEV;
41         }
42
43         socdev->card->codec = spdif_dit_codec;
44         codec = spdif_dit_codec;
45
46         ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
47         if (ret < 0) {
48                 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
49                 goto err_create_pcms;
50         }
51
52         return 0;
53
54 err_create_pcms:
55         return ret;
56 }
57
58 static int spdif_dit_codec_remove(struct platform_device *pdev)
59 {
60         struct snd_soc_device *socdev = platform_get_drvdata(pdev);
61
62         snd_soc_free_pcms(socdev);
63
64         return 0;
65 }
66
67 struct snd_soc_codec_device soc_codec_dev_spdif_dit = {
68         .probe          = spdif_dit_codec_probe,
69         .remove         = spdif_dit_codec_remove,
70 }; EXPORT_SYMBOL_GPL(soc_codec_dev_spdif_dit);
71
72 struct snd_soc_dai dit_stub_dai = {
73         .name           = "DIT",
74         .playback       = {
75                 .stream_name    = "Playback",
76                 .channels_min   = 1,
77                 .channels_max   = 384,
78                 .rates          = STUB_RATES,
79                 .formats        = STUB_FORMATS,
80         },
81 };
82 EXPORT_SYMBOL_GPL(dit_stub_dai);
83
84 static int spdif_dit_probe(struct platform_device *pdev)
85 {
86         struct snd_soc_codec *codec;
87         int ret;
88
89         if (spdif_dit_codec) {
90                 dev_err(&pdev->dev, "Another Codec is registered\n");
91                 ret = -EINVAL;
92                 goto err_reg_codec;
93         }
94
95         codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
96         if (codec == NULL)
97                 return -ENOMEM;
98
99         codec->dev = &pdev->dev;
100
101         mutex_init(&codec->mutex);
102
103         INIT_LIST_HEAD(&codec->dapm_widgets);
104         INIT_LIST_HEAD(&codec->dapm_paths);
105
106         codec->name = "spdif-dit";
107         codec->owner = THIS_MODULE;
108         codec->dai = &dit_stub_dai;
109         codec->num_dai = 1;
110
111         spdif_dit_codec = codec;
112
113         ret = snd_soc_register_codec(codec);
114         if (ret < 0) {
115                 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
116                 goto err_reg_codec;
117         }
118
119         dit_stub_dai.dev = &pdev->dev;
120         ret = snd_soc_register_dai(&dit_stub_dai);
121         if (ret < 0) {
122                 dev_err(codec->dev, "Failed to register dai: %d\n", ret);
123                 goto err_reg_dai;
124         }
125
126         return 0;
127
128 err_reg_dai:
129         snd_soc_unregister_codec(codec);
130 err_reg_codec:
131         kfree(spdif_dit_codec);
132         return ret;
133 }
134
135 static int spdif_dit_remove(struct platform_device *pdev)
136 {
137         snd_soc_unregister_dai(&dit_stub_dai);
138         snd_soc_unregister_codec(spdif_dit_codec);
139         kfree(spdif_dit_codec);
140         spdif_dit_codec = NULL;
141         return 0;
142 }
143
144 static struct platform_driver spdif_dit_driver = {
145         .probe          = spdif_dit_probe,
146         .remove         = spdif_dit_remove,
147         .driver         = {
148                 .name   = "spdif-dit",
149                 .owner  = THIS_MODULE,
150         },
151 };
152
153 static int __init dit_modinit(void)
154 {
155         return platform_driver_register(&spdif_dit_driver);
156 }
157
158 static void __exit dit_exit(void)
159 {
160         platform_driver_unregister(&spdif_dit_driver);
161 }
162
163 module_init(dit_modinit);
164 module_exit(dit_exit);
165