Merge branch 'for-2.6.37' into for-2.6.38
[deliverable/linux.git] / sound / soc / pxa / zylonite.c
CommitLineData
2dac9217
MB
1/*
2 * zylonite.c -- SoC audio for Zylonite
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/device.h>
2c782f59 17#include <linux/clk.h>
2dac9217
MB
18#include <linux/i2c.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/pcm_params.h>
22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24
25#include "../codecs/wm9713.h"
2dac9217
MB
26#include "pxa2xx-ac97.h"
27#include "pxa-ssp.h"
28
2c782f59
MB
29/*
30 * There is a physical switch SW15 on the board which changes the MCLK
31 * for the WM9713 between the standard AC97 master clock and the
32 * output of the CLK_POUT signal from the PXA.
33 */
34static int clk_pout;
35module_param(clk_pout, int, 0);
36MODULE_PARM_DESC(clk_pout, "Use CLK_POUT as WM9713 MCLK (SW15 on board).");
37
38static struct clk *pout;
39
2dac9217
MB
40static struct snd_soc_card zylonite;
41
42static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = {
43 SND_SOC_DAPM_HP("Headphone", NULL),
44 SND_SOC_DAPM_MIC("Headset Microphone", NULL),
45 SND_SOC_DAPM_MIC("Handset Microphone", NULL),
46 SND_SOC_DAPM_SPK("Multiactor", NULL),
47 SND_SOC_DAPM_SPK("Headset Earpiece", NULL),
48};
49
50/* Currently supported audio map */
51static const struct snd_soc_dapm_route audio_map[] = {
52
53 /* Headphone output connected to HPL/HPR */
54 { "Headphone", NULL, "HPL" },
55 { "Headphone", NULL, "HPR" },
56
57 /* On-board earpiece */
58 { "Headset Earpiece", NULL, "OUT3" },
59
60 /* Headphone mic */
61 { "MIC2A", NULL, "Mic Bias" },
62 { "Mic Bias", NULL, "Headset Microphone" },
63
64 /* On-board mic */
65 { "MIC1", NULL, "Mic Bias" },
66 { "Mic Bias", NULL, "Handset Microphone" },
67
68 /* Multiactor differentially connected over SPKL/SPKR */
69 { "Multiactor", NULL, "SPKL" },
70 { "Multiactor", NULL, "SPKR" },
71};
72
f0fba2ad 73static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
2dac9217 74{
f0fba2ad 75 struct snd_soc_codec *codec = rtd->codec;
ce6120cc 76 struct snd_soc_dapm_context *dapm = &codec->dapm;
f0fba2ad 77
2c782f59 78 if (clk_pout)
f0fba2ad 79 snd_soc_dai_set_pll(rtd->codec_dai, 0, 0,
85488037 80 clk_get_rate(pout), 0);
2dac9217 81
ce6120cc 82 snd_soc_dapm_new_controls(dapm, zylonite_dapm_widgets,
2dac9217
MB
83 ARRAY_SIZE(zylonite_dapm_widgets));
84
ce6120cc 85 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
2dac9217
MB
86
87 /* Static setup for now */
ce6120cc
LG
88 snd_soc_dapm_enable_pin(dapm, "Headphone");
89 snd_soc_dapm_enable_pin(dapm, "Headset Earpiece");
2dac9217 90
ce6120cc 91 snd_soc_dapm_sync(dapm);
2dac9217
MB
92 return 0;
93}
94
95static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
96 struct snd_pcm_hw_params *params)
97{
98 struct snd_soc_pcm_runtime *rtd = substream->private_data;
f0fba2ad
LG
99 struct snd_soc_dai *codec_dai = rtd->codec_dai;
100 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
a435869c 101 unsigned int pll_out = 0;
2dac9217
MB
102 unsigned int wm9713_div = 0;
103 int ret = 0;
85fab780
MB
104 int rate = params_rate(params);
105 int width = snd_pcm_format_physical_width(params_format(params));
106
107 /* Only support ratios that we can generate neatly from the AC97
108 * based master clock - in particular, this excludes 44.1kHz.
109 * In most applications the voice DAC will be used for telephony
110 * data so multiples of 8kHz will be the common case.
111 */
112 switch (rate) {
2dac9217
MB
113 case 8000:
114 wm9713_div = 12;
2dac9217
MB
115 break;
116 case 16000:
117 wm9713_div = 6;
2dac9217
MB
118 break;
119 case 48000:
2dac9217 120 wm9713_div = 2;
2dac9217 121 break;
85fab780
MB
122 default:
123 /* Don't support OSS emulation */
124 return -EINVAL;
2dac9217
MB
125 }
126
85fab780
MB
127 /* Add 1 to the width for the leading clock cycle */
128 pll_out = rate * (width + 1) * 8;
2dac9217 129
85fab780 130 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
2dac9217
MB
131 if (ret < 0)
132 return ret;
133
85488037 134 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, pll_out);
a435869c
MB
135 if (ret < 0)
136 return ret;
137
2c782f59
MB
138 if (clk_pout)
139 ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV,
140 WM9713_PCMDIV(wm9713_div));
141 else
142 ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
143 WM9713_PCMDIV(wm9713_div));
2dac9217
MB
144 if (ret < 0)
145 return ret;
146
85fab780
MB
147 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
148 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
149 if (ret < 0)
150 return ret;
151
152 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
153 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
154 if (ret < 0)
155 return ret;
156
2dac9217
MB
157 return 0;
158}
159
160static struct snd_soc_ops zylonite_voice_ops = {
161 .hw_params = zylonite_voice_hw_params,
162};
163
164static struct snd_soc_dai_link zylonite_dai[] = {
165{
166 .name = "AC97",
167 .stream_name = "AC97 HiFi",
f0fba2ad
LG
168 .codec_name = "wm9713-codec",
169 .platform_name = "pxa-pcm-audio",
170 .cpu_dai_name = "pxa-ac97.0",
171 .codec_name = "wm9713-hifi",
2dac9217
MB
172 .init = zylonite_wm9713_init,
173},
174{
175 .name = "AC97 Aux",
176 .stream_name = "AC97 Aux",
f0fba2ad
LG
177 .codec_name = "wm9713-codec",
178 .platform_name = "pxa-pcm-audio",
179 .cpu_dai_name = "pxa-ac97.1",
180 .codec_name = "wm9713-aux",
2dac9217
MB
181},
182{
183 .name = "WM9713 Voice",
184 .stream_name = "WM9713 Voice",
f0fba2ad
LG
185 .codec_name = "wm9713-codec",
186 .platform_name = "pxa-pcm-audio",
187 .cpu_dai_name = "pxa-ssp-dai.2",
188 .codec_name = "wm9713-voice",
2dac9217
MB
189 .ops = &zylonite_voice_ops,
190},
191};
192
2c782f59
MB
193static int zylonite_probe(struct platform_device *pdev)
194{
195 int ret;
196
197 if (clk_pout) {
198 pout = clk_get(NULL, "CLK_POUT");
199 if (IS_ERR(pout)) {
200 dev_err(&pdev->dev, "Unable to obtain CLK_POUT: %ld\n",
201 PTR_ERR(pout));
202 return PTR_ERR(pout);
203 }
204
205 ret = clk_enable(pout);
206 if (ret != 0) {
207 dev_err(&pdev->dev, "Unable to enable CLK_POUT: %d\n",
208 ret);
209 clk_put(pout);
210 return ret;
211 }
212
213 dev_dbg(&pdev->dev, "MCLK enabled at %luHz\n",
214 clk_get_rate(pout));
215 }
216
217 return 0;
218}
219
220static int zylonite_remove(struct platform_device *pdev)
221{
222 if (clk_pout) {
223 clk_disable(pout);
224 clk_put(pout);
225 }
226
227 return 0;
228}
229
230static int zylonite_suspend_post(struct platform_device *pdev,
231 pm_message_t state)
232{
233 if (clk_pout)
234 clk_disable(pout);
235
236 return 0;
237}
238
239static int zylonite_resume_pre(struct platform_device *pdev)
240{
241 int ret = 0;
242
243 if (clk_pout) {
244 ret = clk_enable(pout);
245 if (ret != 0)
246 dev_err(&pdev->dev, "Unable to enable CLK_POUT: %d\n",
247 ret);
248 }
249
250 return ret;
251}
252
2dac9217
MB
253static struct snd_soc_card zylonite = {
254 .name = "Zylonite",
2c782f59
MB
255 .probe = &zylonite_probe,
256 .remove = &zylonite_remove,
257 .suspend_post = &zylonite_suspend_post,
258 .resume_pre = &zylonite_resume_pre,
2dac9217
MB
259 .dai_link = zylonite_dai,
260 .num_links = ARRAY_SIZE(zylonite_dai),
f0fba2ad 261 .owner = THIS_MODULE,
2dac9217
MB
262};
263
264static struct platform_device *zylonite_snd_ac97_device;
265
266static int __init zylonite_init(void)
267{
268 int ret;
269
270 zylonite_snd_ac97_device = platform_device_alloc("soc-audio", -1);
271 if (!zylonite_snd_ac97_device)
272 return -ENOMEM;
273
f0fba2ad 274 platform_set_drvdata(zylonite_snd_ac97_device, &zylonite);
2dac9217
MB
275
276 ret = platform_device_add(zylonite_snd_ac97_device);
277 if (ret != 0)
278 platform_device_put(zylonite_snd_ac97_device);
279
280 return ret;
281}
282
283static void __exit zylonite_exit(void)
284{
285 platform_device_unregister(zylonite_snd_ac97_device);
286}
287
288module_init(zylonite_init);
289module_exit(zylonite_exit);
290
291MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
292MODULE_DESCRIPTION("ALSA SoC WM9713 Zylonite");
293MODULE_LICENSE("GPL");
This page took 0.246685 seconds and 5 git commands to generate.