Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/sound/soc/samsung/goni_wm8994.c
10817 views
1
/*
2
* goni_wm8994.c
3
*
4
* Copyright (C) 2010 Samsung Electronics Co.Ltd
5
* Author: Chanwoo Choi <[email protected]>
6
*
7
* This program is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU General Public License as published by the
9
* Free Software Foundation; either version 2 of the License, or (at your
10
* option) any later version.
11
*
12
*/
13
14
#include <sound/soc.h>
15
#include <sound/jack.h>
16
17
#include <asm/mach-types.h>
18
#include <mach/gpio.h>
19
20
#include "../codecs/wm8994.h"
21
22
#define MACHINE_NAME 0
23
#define CPU_VOICE_DAI 1
24
25
static const char *aquila_str[] = {
26
[MACHINE_NAME] = "aquila",
27
[CPU_VOICE_DAI] = "aquila-voice-dai",
28
};
29
30
static struct snd_soc_card goni;
31
static struct platform_device *goni_snd_device;
32
33
/* 3.5 pie jack */
34
static struct snd_soc_jack jack;
35
36
/* 3.5 pie jack detection DAPM pins */
37
static struct snd_soc_jack_pin jack_pins[] = {
38
{
39
.pin = "Headset Mic",
40
.mask = SND_JACK_MICROPHONE,
41
}, {
42
.pin = "Headset Stereophone",
43
.mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL |
44
SND_JACK_AVOUT,
45
},
46
};
47
48
/* 3.5 pie jack detection gpios */
49
static struct snd_soc_jack_gpio jack_gpios[] = {
50
{
51
.gpio = S5PV210_GPH0(6),
52
.name = "DET_3.5",
53
.report = SND_JACK_HEADSET | SND_JACK_MECHANICAL |
54
SND_JACK_AVOUT,
55
.debounce_time = 200,
56
},
57
};
58
59
static const struct snd_soc_dapm_widget goni_dapm_widgets[] = {
60
SND_SOC_DAPM_SPK("Ext Left Spk", NULL),
61
SND_SOC_DAPM_SPK("Ext Right Spk", NULL),
62
SND_SOC_DAPM_SPK("Ext Rcv", NULL),
63
SND_SOC_DAPM_HP("Headset Stereophone", NULL),
64
SND_SOC_DAPM_MIC("Headset Mic", NULL),
65
SND_SOC_DAPM_MIC("Main Mic", NULL),
66
SND_SOC_DAPM_MIC("2nd Mic", NULL),
67
SND_SOC_DAPM_LINE("Radio In", NULL),
68
};
69
70
static const struct snd_soc_dapm_route goni_dapm_routes[] = {
71
{"Ext Left Spk", NULL, "SPKOUTLP"},
72
{"Ext Left Spk", NULL, "SPKOUTLN"},
73
74
{"Ext Right Spk", NULL, "SPKOUTRP"},
75
{"Ext Right Spk", NULL, "SPKOUTRN"},
76
77
{"Ext Rcv", NULL, "HPOUT2N"},
78
{"Ext Rcv", NULL, "HPOUT2P"},
79
80
{"Headset Stereophone", NULL, "HPOUT1L"},
81
{"Headset Stereophone", NULL, "HPOUT1R"},
82
83
{"IN1RN", NULL, "Headset Mic"},
84
{"IN1RP", NULL, "Headset Mic"},
85
86
{"IN1RN", NULL, "2nd Mic"},
87
{"IN1RP", NULL, "2nd Mic"},
88
89
{"IN1LN", NULL, "Main Mic"},
90
{"IN1LP", NULL, "Main Mic"},
91
92
{"IN2LN", NULL, "Radio In"},
93
{"IN2RN", NULL, "Radio In"},
94
};
95
96
static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd)
97
{
98
struct snd_soc_codec *codec = rtd->codec;
99
struct snd_soc_dapm_context *dapm = &codec->dapm;
100
int ret;
101
102
/* add goni specific widgets */
103
snd_soc_dapm_new_controls(dapm, goni_dapm_widgets,
104
ARRAY_SIZE(goni_dapm_widgets));
105
106
/* set up goni specific audio routes */
107
snd_soc_dapm_add_routes(dapm, goni_dapm_routes,
108
ARRAY_SIZE(goni_dapm_routes));
109
110
/* set endpoints to not connected */
111
snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
112
snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
113
snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
114
snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
115
snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
116
snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
117
118
if (machine_is_aquila()) {
119
snd_soc_dapm_nc_pin(dapm, "SPKOUTRN");
120
snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
121
}
122
123
snd_soc_dapm_sync(dapm);
124
125
/* Headset jack detection */
126
ret = snd_soc_jack_new(codec, "Headset Jack",
127
SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
128
&jack);
129
if (ret)
130
return ret;
131
132
ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins);
133
if (ret)
134
return ret;
135
136
ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios);
137
if (ret)
138
return ret;
139
140
return 0;
141
}
142
143
static int goni_hifi_hw_params(struct snd_pcm_substream *substream,
144
struct snd_pcm_hw_params *params)
145
{
146
struct snd_soc_pcm_runtime *rtd = substream->private_data;
147
struct snd_soc_dai *codec_dai = rtd->codec_dai;
148
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
149
unsigned int pll_out = 24000000;
150
int ret = 0;
151
152
/* set the cpu DAI configuration */
153
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
154
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
155
if (ret < 0)
156
return ret;
157
158
/* set codec DAI configuration */
159
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
160
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
161
if (ret < 0)
162
return ret;
163
164
/* set the codec FLL */
165
ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out,
166
params_rate(params) * 256);
167
if (ret < 0)
168
return ret;
169
170
/* set the codec system clock */
171
ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
172
params_rate(params) * 256, SND_SOC_CLOCK_IN);
173
if (ret < 0)
174
return ret;
175
176
return 0;
177
}
178
179
static struct snd_soc_ops goni_hifi_ops = {
180
.hw_params = goni_hifi_hw_params,
181
};
182
183
static int goni_voice_hw_params(struct snd_pcm_substream *substream,
184
struct snd_pcm_hw_params *params)
185
{
186
struct snd_soc_pcm_runtime *rtd = substream->private_data;
187
struct snd_soc_dai *codec_dai = rtd->codec_dai;
188
unsigned int pll_out = 24000000;
189
int ret = 0;
190
191
if (params_rate(params) != 8000)
192
return -EINVAL;
193
194
/* set codec DAI configuration */
195
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
196
SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
197
if (ret < 0)
198
return ret;
199
200
/* set the codec FLL */
201
ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out,
202
params_rate(params) * 256);
203
if (ret < 0)
204
return ret;
205
206
/* set the codec system clock */
207
ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
208
params_rate(params) * 256, SND_SOC_CLOCK_IN);
209
if (ret < 0)
210
return ret;
211
212
return 0;
213
}
214
215
static struct snd_soc_dai_driver voice_dai = {
216
.name = "goni-voice-dai",
217
.id = 0,
218
.playback = {
219
.channels_min = 1,
220
.channels_max = 2,
221
.rates = SNDRV_PCM_RATE_8000,
222
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
223
.capture = {
224
.channels_min = 1,
225
.channels_max = 2,
226
.rates = SNDRV_PCM_RATE_8000,
227
.formats = SNDRV_PCM_FMTBIT_S16_LE,},
228
};
229
230
static struct snd_soc_ops goni_voice_ops = {
231
.hw_params = goni_voice_hw_params,
232
};
233
234
static struct snd_soc_dai_link goni_dai[] = {
235
{
236
.name = "WM8994",
237
.stream_name = "WM8994 HiFi",
238
.cpu_dai_name = "samsung-i2s.0",
239
.codec_dai_name = "wm8994-aif1",
240
.platform_name = "samsung-audio",
241
.codec_name = "wm8994-codec.0-001a",
242
.init = goni_wm8994_init,
243
.ops = &goni_hifi_ops,
244
}, {
245
.name = "WM8994 Voice",
246
.stream_name = "Voice",
247
.cpu_dai_name = "goni-voice-dai",
248
.codec_dai_name = "wm8994-aif2",
249
.codec_name = "wm8994-codec.0-001a",
250
.ops = &goni_voice_ops,
251
},
252
};
253
254
static struct snd_soc_card goni = {
255
.name = "goni",
256
.dai_link = goni_dai,
257
.num_links = ARRAY_SIZE(goni_dai),
258
};
259
260
static int __init goni_init(void)
261
{
262
int ret;
263
264
if (machine_is_aquila()) {
265
voice_dai.name = aquila_str[CPU_VOICE_DAI];
266
goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI];
267
goni.name = aquila_str[MACHINE_NAME];
268
} else if (!machine_is_goni())
269
return -ENODEV;
270
271
goni_snd_device = platform_device_alloc("soc-audio", -1);
272
if (!goni_snd_device)
273
return -ENOMEM;
274
275
/* register voice DAI here */
276
ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai);
277
if (ret) {
278
platform_device_put(goni_snd_device);
279
return ret;
280
}
281
282
platform_set_drvdata(goni_snd_device, &goni);
283
ret = platform_device_add(goni_snd_device);
284
285
if (ret) {
286
snd_soc_unregister_dai(&goni_snd_device->dev);
287
platform_device_put(goni_snd_device);
288
}
289
290
return ret;
291
}
292
293
static void __exit goni_exit(void)
294
{
295
snd_soc_unregister_dai(&goni_snd_device->dev);
296
platform_device_unregister(goni_snd_device);
297
}
298
299
module_init(goni_init);
300
module_exit(goni_exit);
301
302
/* Module information */
303
MODULE_DESCRIPTION("ALSA SoC WM8994 GONI(S5PV210)");
304
MODULE_AUTHOR("Chanwoo Choi <[email protected]>");
305
MODULE_LICENSE("GPL");
306
307