aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/samsung
diff options
context:
space:
mode:
authorSangbeom Kim <sbkim73@samsung.com>2011-04-08 21:57:59 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2011-04-11 16:31:31 -0400
commitb8eeee68dc81f08993ed5dc18dc6d574ba146674 (patch)
tree49bbd2a025a16389d4768be03498dfef6674a405 /sound/soc/samsung
parenta19809875fb0952631767e2d2484bcd81b4365a1 (diff)
ASoC: SAMSUNG: Add WM8580 PCM Machine driver
This patch add WM8580 PCM machine driver to support PCM audio on SMDKC110, SMDKV210, SMDK6450, SMDK6440 boards. Playback and Capture supports 8kHz sampling rates. and It is tested on SMDKC110, SMDKV210, SMDK6450 Signed-off-by: Sangbeom Kim <sbkim73@samsung.com> Acked-by: Jassi Brar <jassisinghbrar@gmail.com> Acked-by: Liam Girdwood <lrg@ti.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/samsung')
-rw-r--r--sound/soc/samsung/Kconfig8
-rw-r--r--sound/soc/samsung/Makefile2
-rw-r--r--sound/soc/samsung/smdk_wm8580pcm.c206
3 files changed, 216 insertions, 0 deletions
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
index a3fdfb631469..b8c7a2e0d21c 100644
--- a/sound/soc/samsung/Kconfig
+++ b/sound/soc/samsung/Kconfig
@@ -162,3 +162,11 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF
162 select SND_SAMSUNG_SPDIF 162 select SND_SAMSUNG_SPDIF
163 help 163 help
164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK. 164 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
165
166config SND_SOC_SMDK_WM8580_PCM
167 tristate "SoC PCM Audio support for WM8580 on SMDK"
168 depends on SND_SOC_SAMSUNG && (MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110)
169 select SND_SOC_WM8580
170 select SND_SAMSUNG_PCM
171 help
172 Say Y if you want to add support for SoC audio on the SMDK.
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
index 294dec05c26d..6c598fc51a01 100644
--- a/sound/soc/samsung/Makefile
+++ b/sound/soc/samsung/Makefile
@@ -34,6 +34,7 @@ snd-soc-smdk-wm9713-objs := smdk_wm9713.o
34snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o 34snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
35snd-soc-goni-wm8994-objs := goni_wm8994.o 35snd-soc-goni-wm8994-objs := goni_wm8994.o
36snd-soc-smdk-spdif-objs := smdk_spdif.o 36snd-soc-smdk-spdif-objs := smdk_spdif.o
37snd-soc-smdk-wm8580pcm-objs := smdk_wm8580pcm.o
37 38
38obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o 39obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
39obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 40obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -51,3 +52,4 @@ obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o
51obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o 52obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
52obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o 53obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o
53obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o 54obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o
55obj-$(CONFIG_SND_SOC_SMDK_WM8580_PCM) += snd-soc-smdk-wm8580pcm.o
diff --git a/sound/soc/samsung/smdk_wm8580pcm.c b/sound/soc/samsung/smdk_wm8580pcm.c
new file mode 100644
index 000000000000..0d12092df164
--- /dev/null
+++ b/sound/soc/samsung/smdk_wm8580pcm.c
@@ -0,0 +1,206 @@
1/*
2 * sound/soc/samsung/smdk_wm8580pcm.c
3 *
4 * Copyright (c) 2011 Samsung Electronics Co. Ltd
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11#include <sound/soc.h>
12#include <sound/pcm_params.h>
13#include <sound/pcm.h>
14
15#include <asm/mach-types.h>
16
17#include "../codecs/wm8580.h"
18#include "dma.h"
19#include "pcm.h"
20
21/*
22 * Board Settings:
23 * o '1' means 'ON'
24 * o '0' means 'OFF'
25 * o 'X' means 'Don't care'
26 *
27 * SMDK6410, SMDK6440, SMDK6450 Base B/D: CFG1-0000, CFG2-1111
28 * SMDKC110, SMDKV210: CFGB11-100100, CFGB12-0000
29 */
30
31#define SMDK_WM8580_EXT_OSC 12000000
32#define SMDK_WM8580_EXT_MCLK 4096000
33#define SMDK_WM8580_EXT_VOICE 2048000
34
35static unsigned long mclk_freq;
36static unsigned long xtal_freq;
37
38/*
39 * If MCLK clock directly gets from XTAL, we don't have to use PLL
40 * to make MCLK, but if XTAL clock source connects with other codec
41 * pin (like XTI), we should have to set codec's PLL to make MCLK.
42 * Because Samsung SoC does not support pcmcdclk output like I2S.
43 */
44
45static int smdk_wm8580_pcm_hw_params(struct snd_pcm_substream *substream,
46 struct snd_pcm_hw_params *params)
47{
48 struct snd_soc_pcm_runtime *rtd = substream->private_data;
49 struct snd_soc_dai *codec_dai = rtd->codec_dai;
50 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
51 int rfs, ret;
52
53 switch (params_rate(params)) {
54 case 8000:
55 break;
56 default:
57 printk(KERN_ERR "%s:%d Sampling Rate %u not supported!\n",
58 __func__, __LINE__, params_rate(params));
59 return -EINVAL;
60 }
61
62 rfs = mclk_freq / params_rate(params) / 2;
63
64 /* Set the codec DAI configuration */
65 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B
66 | SND_SOC_DAIFMT_IB_NF
67 | SND_SOC_DAIFMT_CBS_CFS);
68 if (ret < 0)
69 return ret;
70
71 /* Set the cpu DAI configuration */
72 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_B
73 | SND_SOC_DAIFMT_IB_NF
74 | SND_SOC_DAIFMT_CBS_CFS);
75 if (ret < 0)
76 return ret;
77
78 if (mclk_freq == xtal_freq) {
79 ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_MCLK,
80 mclk_freq, SND_SOC_CLOCK_IN);
81 if (ret < 0)
82 return ret;
83
84 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
85 WM8580_CLKSRC_MCLK);
86 if (ret < 0)
87 return ret;
88 } else {
89 ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA,
90 mclk_freq, SND_SOC_CLOCK_IN);
91 if (ret < 0)
92 return ret;
93
94 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
95 WM8580_CLKSRC_PLLA);
96 if (ret < 0)
97 return ret;
98
99 ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
100 xtal_freq, mclk_freq);
101 if (ret < 0)
102 return ret;
103 }
104
105 /* Set PCM source clock on CPU */
106 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C_PCM_CLKSRC_MUX,
107 mclk_freq, SND_SOC_CLOCK_IN);
108 if (ret < 0)
109 return ret;
110
111 /* Set SCLK_DIV for making bclk */
112 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_PCM_SCLK_PER_FS, rfs);
113 if (ret < 0)
114 return ret;
115
116 return 0;
117}
118
119static struct snd_soc_ops smdk_wm8580_pcm_ops = {
120 .hw_params = smdk_wm8580_pcm_hw_params,
121};
122
123static struct snd_soc_dai_link smdk_dai[] = {
124 {
125 .name = "WM8580 PAIF PCM RX",
126 .stream_name = "Playback",
127 .cpu_dai_name = "samsung-pcm.0",
128 .codec_dai_name = "wm8580-hifi-playback",
129 .platform_name = "samsung-audio",
130 .codec_name = "wm8580-codec.0-001b",
131 .ops = &smdk_wm8580_pcm_ops,
132 }, {
133 .name = "WM8580 PAIF PCM TX",
134 .stream_name = "Capture",
135 .cpu_dai_name = "samsung-pcm.0",
136 .codec_dai_name = "wm8580-hifi-capture",
137 .platform_name = "samsung-audio",
138 .codec_name = "wm8580-codec.0-001b",
139 .ops = &smdk_wm8580_pcm_ops,
140 },
141};
142
143static struct snd_soc_card smdk_pcm = {
144 .name = "SMDK-PCM",
145 .dai_link = smdk_dai,
146 .num_links = 2,
147};
148
149/*
150 * After SMDKC110 Base Board's Rev is '0.1', 12MHz External OSC(X1)
151 * is absent (or not connected), so we connect EXT_VOICE_CLK(OSC4),
152 * 2.0484Mhz, directly with MCLK both Codec and SoC.
153 */
154static int __devinit snd_smdk_probe(struct platform_device *pdev)
155{
156 int ret = 0;
157
158 xtal_freq = SMDK_WM8580_EXT_OSC;
159 mclk_freq = SMDK_WM8580_EXT_MCLK;
160
161 if (machine_is_smdkc110() || machine_is_smdkv210())
162 xtal_freq = mclk_freq = SMDK_WM8580_EXT_VOICE;
163
164 smdk_pcm.dev = &pdev->dev;
165 ret = snd_soc_register_card(&smdk_pcm);
166 if (ret) {
167 dev_err(&pdev->dev, "snd_soc_register_card failed %d\n", ret);
168 return ret;
169 }
170
171 return 0;
172}
173
174static int __devexit snd_smdk_remove(struct platform_device *pdev)
175{
176 snd_soc_unregister_card(&smdk_pcm);
177 platform_set_drvdata(pdev, NULL);
178 return 0;
179}
180
181static struct platform_driver snd_smdk_driver = {
182 .driver = {
183 .owner = THIS_MODULE,
184 .name = "samsung-smdk-pcm",
185 },
186 .probe = snd_smdk_probe,
187 .remove = __devexit_p(snd_smdk_remove),
188};
189
190static int __init smdk_audio_init(void)
191{
192 return platform_driver_register(&snd_smdk_driver);
193}
194
195module_init(smdk_audio_init);
196
197static void __exit smdk_audio_exit(void)
198{
199 platform_driver_unregister(&snd_smdk_driver);
200}
201
202module_exit(smdk_audio_exit);
203
204MODULE_AUTHOR("Sangbeom Kim, <sbkim73@samsung.com>");
205MODULE_DESCRIPTION("ALSA SoC SMDK WM8580 for PCM");
206MODULE_LICENSE("GPL");