diff options
Diffstat (limited to 'sound/soc/codecs/spdif_transciever.c')
-rw-r--r-- | sound/soc/codecs/spdif_transciever.c | 94 |
1 files changed, 93 insertions, 1 deletions
diff --git a/sound/soc/codecs/spdif_transciever.c b/sound/soc/codecs/spdif_transciever.c index a6319114105..9119836051a 100644 --- a/sound/soc/codecs/spdif_transciever.c +++ b/sound/soc/codecs/spdif_transciever.c | |||
@@ -16,8 +16,10 @@ | |||
16 | 16 | ||
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/moduleparam.h> | 18 | #include <linux/moduleparam.h> |
19 | #include <linux/slab.h> | ||
19 | #include <sound/soc.h> | 20 | #include <sound/soc.h> |
20 | #include <sound/pcm.h> | 21 | #include <sound/pcm.h> |
22 | #include <sound/initval.h> | ||
21 | 23 | ||
22 | #include "spdif_transciever.h" | 24 | #include "spdif_transciever.h" |
23 | 25 | ||
@@ -26,6 +28,48 @@ MODULE_LICENSE("GPL"); | |||
26 | #define STUB_RATES SNDRV_PCM_RATE_8000_96000 | 28 | #define STUB_RATES SNDRV_PCM_RATE_8000_96000 |
27 | #define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE | 29 | #define STUB_FORMATS SNDRV_PCM_FMTBIT_S16_LE |
28 | 30 | ||
31 | static struct snd_soc_codec *spdif_dit_codec; | ||
32 | |||
33 | static int spdif_dit_codec_probe(struct platform_device *pdev) | ||
34 | { | ||
35 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
36 | struct snd_soc_codec *codec; | ||
37 | int ret; | ||
38 | |||
39 | if (spdif_dit_codec == NULL) { | ||
40 | dev_err(&pdev->dev, "Codec device not registered\n"); | ||
41 | return -ENODEV; | ||
42 | } | ||
43 | |||
44 | socdev->card->codec = spdif_dit_codec; | ||
45 | codec = spdif_dit_codec; | ||
46 | |||
47 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
48 | if (ret < 0) { | ||
49 | dev_err(codec->dev, "failed to create pcms: %d\n", ret); | ||
50 | goto err_create_pcms; | ||
51 | } | ||
52 | |||
53 | return 0; | ||
54 | |||
55 | err_create_pcms: | ||
56 | return ret; | ||
57 | } | ||
58 | |||
59 | static int spdif_dit_codec_remove(struct platform_device *pdev) | ||
60 | { | ||
61 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
62 | |||
63 | snd_soc_free_pcms(socdev); | ||
64 | |||
65 | return 0; | ||
66 | } | ||
67 | |||
68 | struct snd_soc_codec_device soc_codec_dev_spdif_dit = { | ||
69 | .probe = spdif_dit_codec_probe, | ||
70 | .remove = spdif_dit_codec_remove, | ||
71 | }; EXPORT_SYMBOL_GPL(soc_codec_dev_spdif_dit); | ||
72 | |||
29 | struct snd_soc_dai dit_stub_dai = { | 73 | struct snd_soc_dai dit_stub_dai = { |
30 | .name = "DIT", | 74 | .name = "DIT", |
31 | .playback = { | 75 | .playback = { |
@@ -40,13 +84,61 @@ EXPORT_SYMBOL_GPL(dit_stub_dai); | |||
40 | 84 | ||
41 | static int spdif_dit_probe(struct platform_device *pdev) | 85 | static int spdif_dit_probe(struct platform_device *pdev) |
42 | { | 86 | { |
87 | struct snd_soc_codec *codec; | ||
88 | int ret; | ||
89 | |||
90 | if (spdif_dit_codec) { | ||
91 | dev_err(&pdev->dev, "Another Codec is registered\n"); | ||
92 | ret = -EINVAL; | ||
93 | goto err_reg_codec; | ||
94 | } | ||
95 | |||
96 | codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); | ||
97 | if (codec == NULL) | ||
98 | return -ENOMEM; | ||
99 | |||
100 | codec->dev = &pdev->dev; | ||
101 | |||
102 | mutex_init(&codec->mutex); | ||
103 | |||
104 | INIT_LIST_HEAD(&codec->dapm_widgets); | ||
105 | INIT_LIST_HEAD(&codec->dapm_paths); | ||
106 | |||
107 | codec->name = "spdif-dit"; | ||
108 | codec->owner = THIS_MODULE; | ||
109 | codec->dai = &dit_stub_dai; | ||
110 | codec->num_dai = 1; | ||
111 | |||
112 | spdif_dit_codec = codec; | ||
113 | |||
114 | ret = snd_soc_register_codec(codec); | ||
115 | if (ret < 0) { | ||
116 | dev_err(codec->dev, "Failed to register codec: %d\n", ret); | ||
117 | goto err_reg_codec; | ||
118 | } | ||
119 | |||
43 | dit_stub_dai.dev = &pdev->dev; | 120 | dit_stub_dai.dev = &pdev->dev; |
44 | return snd_soc_register_dai(&dit_stub_dai); | 121 | ret = snd_soc_register_dai(&dit_stub_dai); |
122 | if (ret < 0) { | ||
123 | dev_err(codec->dev, "Failed to register dai: %d\n", ret); | ||
124 | goto err_reg_dai; | ||
125 | } | ||
126 | |||
127 | return 0; | ||
128 | |||
129 | err_reg_dai: | ||
130 | snd_soc_unregister_codec(codec); | ||
131 | err_reg_codec: | ||
132 | kfree(spdif_dit_codec); | ||
133 | return ret; | ||
45 | } | 134 | } |
46 | 135 | ||
47 | static int spdif_dit_remove(struct platform_device *pdev) | 136 | static int spdif_dit_remove(struct platform_device *pdev) |
48 | { | 137 | { |
49 | snd_soc_unregister_dai(&dit_stub_dai); | 138 | snd_soc_unregister_dai(&dit_stub_dai); |
139 | snd_soc_unregister_codec(spdif_dit_codec); | ||
140 | kfree(spdif_dit_codec); | ||
141 | spdif_dit_codec = NULL; | ||
50 | return 0; | 142 | return 0; |
51 | } | 143 | } |
52 | 144 | ||