aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorFrank Mandarino <fmandarino@endrelia.com>2006-10-06 12:31:09 -0400
committerJaroslav Kysela <perex@suse.cz>2007-02-09 03:00:16 -0500
commitdb2a416556af0313db028147e4a22fef6f214f2f (patch)
treed5b05b3ad7af4b6023237eee4eac2c6375248dce /sound
parent808db4a4512bedd45b62de255f7eedb5d5b788b9 (diff)
[ALSA] ASoC: core code
This patch is the core of ASoC functionality. The ASoC core is designed to provide the following features :- o Codec independence. Allows reuse of codec drivers on other platforms and machines. o Platform driver code reuse. Reuse of platform specific audio DMA and DAI drivers on different machines. o Easy I2S/PCM digital audio interface configuration between codec and SoC. Each SoC interface and codec registers their audio interface capabilities with the core at initialisation. The capabilities are subsequently matched and configured at run time for best power and performance when the application hw params are known. o Machine specific controls/operations: Allow machines to add controls and operations to the audio subsystem. e.g. volume control for speaker amp. To achieve all this, ASoC splits an embedded audio system into 3 components :- 1. Codec driver: The codec driver is platform independent and contains audio controls, audio interface capabilities, codec dapm and codec IO functions. 2. Platform driver: The platform driver contains the audio dma engine and audio interface drivers (e.g. I2S, AC97, PCM) for that platform. 3. Machine driver: The machine driver handles any machine specific controls and audio events. i.e. turning on an amp at start of playback. Signed-off-by: Frank Mandarino <fmandarino@endrelia.com> Signed-off-by: Richard Purdie <rpurdie@rpsys.net> Signed-off-by: Liam Girdwood <liam.Girdwood@wolfsonmicro.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/soc-core.c1920
1 files changed, 1920 insertions, 0 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
new file mode 100644
index 000000000000..e841ad46c759
--- /dev/null
+++ b/sound/soc/soc-core.c
@@ -0,0 +1,1920 @@
1/*
2 * soc-core.c -- ALSA SoC Audio Layer
3 *
4 * Copyright 2005 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood
6 * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * Revision history
14 * 12th Aug 2005 Initial version.
15 * 25th Oct 2005 Working Codec, Interface and Platform registration.
16 *
17 * TODO:
18 * o Add hw rules to enforce rates, etc.
19 * o More testing with other codecs/machines.
20 * o Add more codecs and platforms to ensure good API coverage.
21 * o Support TDM on PCM and I2S
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <linux/pm.h>
29#include <linux/bitops.h>
30#include <linux/platform_device.h>
31#include <sound/driver.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/soc.h>
36#include <sound/soc-dapm.h>
37#include <sound/initval.h>
38
39/* debug */
40#define SOC_DEBUG 0
41#if SOC_DEBUG
42#define dbg(format, arg...) printk(format, ## arg)
43#else
44#define dbg(format, arg...)
45#endif
46/* debug DAI capabilities matching */
47#define SOC_DEBUG_DAI 0
48#if SOC_DEBUG_DAI
49#define dbgc(format, arg...) printk(format, ## arg)
50#else
51#define dbgc(format, arg...)
52#endif
53
54static DEFINE_MUTEX(pcm_mutex);
55static DEFINE_MUTEX(io_mutex);
56static struct workqueue_struct *soc_workq;
57static struct work_struct soc_stream_work;
58static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
59
60/* supported sample rates */
61/* ATTENTION: these values depend on the definition in pcm.h! */
62static const unsigned int rates[] = {
63 5512, 8000, 11025, 16000, 22050, 32000, 44100,
64 48000, 64000, 88200, 96000, 176400, 192000
65};
66
67/*
68 * This is a timeout to do a DAPM powerdown after a stream is closed().
69 * It can be used to eliminate pops between different playback streams, e.g.
70 * between two audio tracks.
71 */
72static int pmdown_time = 5000;
73module_param(pmdown_time, int, 0);
74MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
75
76#ifdef CONFIG_SND_SOC_AC97_BUS
77/* unregister ac97 codec */
78static int soc_ac97_dev_unregister(struct snd_soc_codec *codec)
79{
80 if (codec->ac97->dev.bus)
81 device_unregister(&codec->ac97->dev);
82 return 0;
83}
84
85/* stop no dev release warning */
86static void soc_ac97_device_release(struct device *dev){}
87
88/* register ac97 codec to bus */
89static int soc_ac97_dev_register(struct snd_soc_codec *codec)
90{
91 int err;
92
93 codec->ac97->dev.bus = &ac97_bus_type;
94 codec->ac97->dev.parent = NULL;
95 codec->ac97->dev.release = soc_ac97_device_release;
96
97 snprintf(codec->ac97->dev.bus_id, BUS_ID_SIZE, "%d-%d:%s",
98 codec->card->number, 0, codec->name);
99 err = device_register(&codec->ac97->dev);
100 if (err < 0) {
101 snd_printk(KERN_ERR "Can't register ac97 bus\n");
102 codec->ac97->dev.bus = NULL;
103 return err;
104 }
105 return 0;
106}
107#endif
108
109static inline const char* get_dai_name(int type)
110{
111 switch(type) {
112 case SND_SOC_DAI_AC97:
113 return "AC97";
114 case SND_SOC_DAI_I2S:
115 return "I2S";
116 case SND_SOC_DAI_PCM:
117 return "PCM";
118 }
119 return NULL;
120}
121
122/* get rate format from rate */
123static inline int soc_get_rate_format(int rate)
124{
125 int i;
126
127 for (i = 0; i < ARRAY_SIZE(rates); i++) {
128 if (rates[i] == rate)
129 return 1 << i;
130 }
131 return 0;
132}
133
134/* gets the audio system mclk/sysclk for the given parameters */
135static unsigned inline int soc_get_mclk(struct snd_soc_pcm_runtime *rtd,
136 struct snd_soc_clock_info *info)
137{
138 struct snd_soc_device *socdev = rtd->socdev;
139 struct snd_soc_machine *machine = socdev->machine;
140 int i;
141
142 /* find the matching machine config and get it's mclk for the given
143 * sample rate and hardware format */
144 for(i = 0; i < machine->num_links; i++) {
145 if (machine->dai_link[i].cpu_dai == rtd->cpu_dai &&
146 machine->dai_link[i].config_sysclk)
147 return machine->dai_link[i].config_sysclk(rtd, info);
148 }
149 return 0;
150}
151
152/* changes a bitclk multiplier mask to a divider mask */
153static u16 soc_bfs_mult_to_div(u16 bfs, int rate, unsigned int mclk,
154 unsigned int pcmfmt, unsigned int chn)
155{
156 int i, j;
157 u16 bfs_ = 0;
158 int size = snd_pcm_format_physical_width(pcmfmt), min = 0;
159
160 if (size <= 0)
161 return 0;
162
163 /* the minimum bit clock that has enough bandwidth */
164 min = size * rate * chn;
165 dbgc("mult --> div min bclk %d with mclk %d\n", min, mclk);
166
167 for (i = 0; i < 16; i++) {
168 if ((bfs >> i) & 0x1) {
169 j = rate * SND_SOC_FSB_REAL(1<<i);
170
171 if (j >= min) {
172 bfs_ |= SND_SOC_FSBD(mclk/j);
173 dbgc("mult --> div support mult %d\n",
174 SND_SOC_FSB_REAL(1<<i));
175 }
176 }
177 }
178
179 return bfs_;
180}
181
182/* changes a bitclk divider mask to a multiplier mask */
183static u16 soc_bfs_div_to_mult(u16 bfs, int rate, unsigned int mclk,
184 unsigned int pcmfmt, unsigned int chn)
185{
186 int i, j;
187 u16 bfs_ = 0;
188
189 int size = snd_pcm_format_physical_width(pcmfmt), min = 0;
190
191 if (size <= 0)
192 return 0;
193
194 /* the minimum bit clock that has enough bandwidth */
195 min = size * rate * chn;
196 dbgc("div to mult min bclk %d with mclk %d\n", min, mclk);
197
198 for (i = 0; i < 16; i++) {
199 if ((bfs >> i) & 0x1) {
200 j = mclk / (SND_SOC_FSBD_REAL(1<<i));
201 if (j >= min) {
202 bfs_ |= SND_SOC_FSB(j/rate);
203 dbgc("div --> mult support div %d\n",
204 SND_SOC_FSBD_REAL(1<<i));
205 }
206 }
207 }
208
209 return bfs_;
210}
211
212/* Matches codec DAI and SoC CPU DAI hardware parameters */
213static int soc_hw_match_params(struct snd_pcm_substream *substream,
214 struct snd_pcm_hw_params *params)
215{
216 struct snd_soc_pcm_runtime *rtd = substream->private_data;
217 struct snd_soc_dai_mode *codec_dai_mode = NULL;
218 struct snd_soc_dai_mode *cpu_dai_mode = NULL;
219 struct snd_soc_clock_info clk_info;
220 unsigned int fs, mclk, codec_bfs, cpu_bfs, rate = params_rate(params),
221 chn, j, k, cpu_bclk, codec_bclk, pcmrate;
222 u16 fmt = 0;
223
224 dbg("asoc: match version %s\n", SND_SOC_VERSION);
225 clk_info.rate = rate;
226 pcmrate = soc_get_rate_format(rate);
227
228 /* try and find a match from the codec and cpu DAI capabilities */
229 for (j = 0; j < rtd->codec_dai->caps.num_modes; j++) {
230 for (k = 0; k < rtd->cpu_dai->caps.num_modes; k++) {
231 codec_dai_mode = &rtd->codec_dai->caps.mode[j];
232 cpu_dai_mode = &rtd->cpu_dai->caps.mode[k];
233
234 if (!(codec_dai_mode->pcmrate & cpu_dai_mode->pcmrate &
235 pcmrate)) {
236 dbgc("asoc: DAI[%d:%d] failed to match rate\n", j, k);
237 continue;
238 }
239
240 fmt = codec_dai_mode->fmt & cpu_dai_mode->fmt;
241 if (!(fmt & SND_SOC_DAIFMT_FORMAT_MASK)) {
242 dbgc("asoc: DAI[%d:%d] failed to match format\n", j, k);
243 continue;
244 }
245
246 if (!(fmt & SND_SOC_DAIFMT_CLOCK_MASK)) {
247 dbgc("asoc: DAI[%d:%d] failed to match clock masters\n",
248 j, k);
249 continue;
250 }
251
252 if (!(fmt & SND_SOC_DAIFMT_INV_MASK)) {
253 dbgc("asoc: DAI[%d:%d] failed to match invert\n", j, k);
254 continue;
255 }
256
257 if (!(codec_dai_mode->pcmfmt & cpu_dai_mode->pcmfmt)) {
258 dbgc("asoc: DAI[%d:%d] failed to match pcm format\n", j, k);
259 continue;
260 }
261
262 if (!(codec_dai_mode->pcmdir & cpu_dai_mode->pcmdir)) {
263 dbgc("asoc: DAI[%d:%d] failed to match direction\n", j, k);
264 continue;
265 }
266
267 /* todo - still need to add tdm selection */
268 rtd->cpu_dai->dai_runtime.fmt =
269 rtd->codec_dai->dai_runtime.fmt =
270 1 << (ffs(fmt & SND_SOC_DAIFMT_FORMAT_MASK) -1) |
271 1 << (ffs(fmt & SND_SOC_DAIFMT_CLOCK_MASK) - 1) |
272 1 << (ffs(fmt & SND_SOC_DAIFMT_INV_MASK) - 1);
273 clk_info.bclk_master =
274 rtd->cpu_dai->dai_runtime.fmt & SND_SOC_DAIFMT_CLOCK_MASK;
275
276 /* make sure the ratio between rate and master
277 * clock is acceptable*/
278 fs = (cpu_dai_mode->fs & codec_dai_mode->fs);
279 if (fs == 0) {
280 dbgc("asoc: DAI[%d:%d] failed to match FS\n", j, k);
281 continue;
282 }
283 clk_info.fs = rtd->cpu_dai->dai_runtime.fs =
284 rtd->codec_dai->dai_runtime.fs = fs;
285
286 /* calculate audio system clocking using slowest clocks possible*/
287 mclk = soc_get_mclk(rtd, &clk_info);
288 if (mclk == 0) {
289 dbgc("asoc: DAI[%d:%d] configuration not clockable\n", j, k);
290 dbgc("asoc: rate %d fs %d master %x\n", rate, fs,
291 clk_info.bclk_master);
292 continue;
293 }
294
295 /* calculate word size (per channel) and frame size */
296 rtd->codec_dai->dai_runtime.pcmfmt =
297 rtd->cpu_dai->dai_runtime.pcmfmt =
298 1 << params_format(params);
299
300 chn = params_channels(params);
301 /* i2s always has left and right */
302 if (params_channels(params) == 1 &&
303 rtd->cpu_dai->dai_runtime.fmt & (SND_SOC_DAIFMT_I2S |
304 SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_LEFT_J))
305 chn <<= 1;
306
307 /* Calculate bfs - the ratio between bitclock and the sample rate
308 * We must take into consideration the dividers and multipliers
309 * used in the codec and cpu DAI modes. We always choose the
310 * lowest possible clocks to reduce power.
311 */
312 if (codec_dai_mode->flags & cpu_dai_mode->flags &
313 SND_SOC_DAI_BFS_DIV) {
314 /* cpu & codec bfs dividers */
315 rtd->cpu_dai->dai_runtime.bfs =
316 rtd->codec_dai->dai_runtime.bfs =
317 1 << (fls(codec_dai_mode->bfs & cpu_dai_mode->bfs) - 1);
318 } else if (codec_dai_mode->flags & SND_SOC_DAI_BFS_DIV) {
319 /* normalise bfs codec divider & cpu mult */
320 codec_bfs = soc_bfs_div_to_mult(codec_dai_mode->bfs, rate,
321 mclk, rtd->codec_dai->dai_runtime.pcmfmt, chn);
322 rtd->cpu_dai->dai_runtime.bfs =
323 1 << (ffs(codec_bfs & cpu_dai_mode->bfs) - 1);
324 cpu_bfs = soc_bfs_mult_to_div(cpu_dai_mode->bfs, rate, mclk,
325 rtd->codec_dai->dai_runtime.pcmfmt, chn);
326 rtd->codec_dai->dai_runtime.bfs =
327 1 << (fls(codec_dai_mode->bfs & cpu_bfs) - 1);
328 } else if (cpu_dai_mode->flags & SND_SOC_DAI_BFS_DIV) {
329 /* normalise bfs codec mult & cpu divider */
330 codec_bfs = soc_bfs_mult_to_div(codec_dai_mode->bfs, rate,
331 mclk, rtd->codec_dai->dai_runtime.pcmfmt, chn);
332 rtd->cpu_dai->dai_runtime.bfs =
333 1 << (fls(codec_bfs & cpu_dai_mode->bfs) -1);
334 cpu_bfs = soc_bfs_div_to_mult(cpu_dai_mode->bfs, rate, mclk,
335 rtd->codec_dai->dai_runtime.pcmfmt, chn);
336 rtd->codec_dai->dai_runtime.bfs =
337 1 << (ffs(codec_dai_mode->bfs & cpu_bfs) -1);
338 } else {
339 /* codec & cpu bfs rate multipliers */
340 rtd->cpu_dai->dai_runtime.bfs =
341 rtd->codec_dai->dai_runtime.bfs =
342 1 << (ffs(codec_dai_mode->bfs & cpu_dai_mode->bfs) -1);
343 }
344
345 /* make sure the bit clock speed is acceptable */
346 if (!rtd->cpu_dai->dai_runtime.bfs ||
347 !rtd->codec_dai->dai_runtime.bfs) {
348 dbgc("asoc: DAI[%d:%d] failed to match BFS\n", j, k);
349 dbgc("asoc: cpu_dai %x codec %x\n",
350 rtd->cpu_dai->dai_runtime.bfs,
351 rtd->codec_dai->dai_runtime.bfs);
352 dbgc("asoc: mclk %d hwfmt %x\n", mclk, fmt);
353 continue;
354 }
355
356 goto found;
357 }
358 }
359 printk(KERN_ERR "asoc: no matching DAI found between codec and CPU\n");
360 return -EINVAL;
361
362found:
363 /* we have matching DAI's, so complete the runtime info */
364 rtd->codec_dai->dai_runtime.pcmrate =
365 rtd->cpu_dai->dai_runtime.pcmrate =
366 soc_get_rate_format(rate);
367
368 rtd->codec_dai->dai_runtime.priv = codec_dai_mode->priv;
369 rtd->cpu_dai->dai_runtime.priv = cpu_dai_mode->priv;
370 rtd->codec_dai->dai_runtime.flags = codec_dai_mode->flags;
371 rtd->cpu_dai->dai_runtime.flags = cpu_dai_mode->flags;
372
373 /* for debug atm */
374 dbg("asoc: DAI[%d:%d] Match OK\n", j, k);
375 if (rtd->codec_dai->dai_runtime.flags == SND_SOC_DAI_BFS_DIV) {
376 codec_bclk = (rtd->codec_dai->dai_runtime.fs * params_rate(params)) /
377 SND_SOC_FSBD_REAL(rtd->codec_dai->dai_runtime.bfs);
378 dbg("asoc: codec fs %d mclk %d bfs div %d bclk %d\n",
379 rtd->codec_dai->dai_runtime.fs, mclk,
380 SND_SOC_FSBD_REAL(rtd->codec_dai->dai_runtime.bfs), codec_bclk);
381 } else {
382 codec_bclk = params_rate(params) *
383 SND_SOC_FSB_REAL(rtd->codec_dai->dai_runtime.bfs);
384 dbg("asoc: codec fs %d mclk %d bfs mult %d bclk %d\n",
385 rtd->codec_dai->dai_runtime.fs, mclk,
386 SND_SOC_FSB_REAL(rtd->codec_dai->dai_runtime.bfs), codec_bclk);
387 }
388 if (rtd->cpu_dai->dai_runtime.flags == SND_SOC_DAI_BFS_DIV) {
389 cpu_bclk = (rtd->cpu_dai->dai_runtime.fs * params_rate(params)) /
390 SND_SOC_FSBD_REAL(rtd->cpu_dai->dai_runtime.bfs);
391 dbg("asoc: cpu fs %d mclk %d bfs div %d bclk %d\n",
392 rtd->cpu_dai->dai_runtime.fs, mclk,
393 SND_SOC_FSBD_REAL(rtd->cpu_dai->dai_runtime.bfs), cpu_bclk);
394 } else {
395 cpu_bclk = params_rate(params) *
396 SND_SOC_FSB_REAL(rtd->cpu_dai->dai_runtime.bfs);
397 dbg("asoc: cpu fs %d mclk %d bfs mult %d bclk %d\n",
398 rtd->cpu_dai->dai_runtime.fs, mclk,
399 SND_SOC_FSB_REAL(rtd->cpu_dai->dai_runtime.bfs), cpu_bclk);
400 }
401
402 /*
403 * Check we have matching bitclocks. If we don't then it means the
404 * sysclock returned by either the codec or cpu DAI (selected by the
405 * machine sysclock function) is wrong compared with the supported DAI
406 * modes for the codec or cpu DAI.
407 */
408 if (cpu_bclk != codec_bclk){
409 printk(KERN_ERR
410 "asoc: codec and cpu bitclocks differ, audio may be wrong speed\n"
411 );
412 printk(KERN_ERR "asoc: codec %d != cpu %d\n", codec_bclk, cpu_bclk);
413 }
414
415 switch(rtd->cpu_dai->dai_runtime.fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
416 case SND_SOC_DAIFMT_CBM_CFM:
417 dbg("asoc: DAI codec BCLK master, LRC master\n");
418 break;
419 case SND_SOC_DAIFMT_CBS_CFM:
420 dbg("asoc: DAI codec BCLK slave, LRC master\n");
421 break;
422 case SND_SOC_DAIFMT_CBM_CFS:
423 dbg("asoc: DAI codec BCLK master, LRC slave\n");
424 break;
425 case SND_SOC_DAIFMT_CBS_CFS:
426 dbg("asoc: DAI codec BCLK slave, LRC slave\n");
427 break;
428 }
429 dbg("asoc: mode %x, invert %x\n",
430 rtd->cpu_dai->dai_runtime.fmt & SND_SOC_DAIFMT_FORMAT_MASK,
431 rtd->cpu_dai->dai_runtime.fmt & SND_SOC_DAIFMT_INV_MASK);
432 dbg("asoc: audio rate %d chn %d fmt %x\n", params_rate(params),
433 params_channels(params), params_format(params));
434
435 return 0;
436}
437
438static inline u32 get_rates(struct snd_soc_dai_mode *modes, int nmodes)
439{
440 int i;
441 u32 rates = 0;
442
443 for(i = 0; i < nmodes; i++)
444 rates |= modes[i].pcmrate;
445
446 return rates;
447}
448
449static inline u64 get_formats(struct snd_soc_dai_mode *modes, int nmodes)
450{
451 int i;
452 u64 formats = 0;
453
454 for(i = 0; i < nmodes; i++)
455 formats |= modes[i].pcmfmt;
456
457 return formats;
458}
459
460/*
461 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
462 * then initialized and any private data can be allocated. This also calls
463 * startup for the cpu DAI, platform, machine and codec DAI.
464 */
465static int soc_pcm_open(struct snd_pcm_substream *substream)
466{
467 struct snd_soc_pcm_runtime *rtd = substream->private_data;
468 struct snd_soc_device *socdev = rtd->socdev;
469 struct snd_pcm_runtime *runtime = substream->runtime;
470 struct snd_soc_machine *machine = socdev->machine;
471 struct snd_soc_platform *platform = socdev->platform;
472 struct snd_soc_codec_dai *codec_dai = rtd->codec_dai;
473 struct snd_soc_cpu_dai *cpu_dai = rtd->cpu_dai;
474 int ret = 0;
475
476 mutex_lock(&pcm_mutex);
477
478 /* startup the audio subsystem */
479 if (rtd->cpu_dai->ops.startup) {
480 ret = rtd->cpu_dai->ops.startup(substream);
481 if (ret < 0) {
482 printk(KERN_ERR "asoc: can't open interface %s\n",
483 rtd->cpu_dai->name);
484 goto out;
485 }
486 }
487
488 if (platform->pcm_ops->open) {
489 ret = platform->pcm_ops->open(substream);
490 if (ret < 0) {
491 printk(KERN_ERR "asoc: can't open platform %s\n", platform->name);
492 goto platform_err;
493 }
494 }
495
496 if (machine->ops && machine->ops->startup) {
497 ret = machine->ops->startup(substream);
498 if (ret < 0) {
499 printk(KERN_ERR "asoc: %s startup failed\n", machine->name);
500 goto machine_err;
501 }
502 }
503
504 if (rtd->codec_dai->ops.startup) {
505 ret = rtd->codec_dai->ops.startup(substream);
506 if (ret < 0) {
507 printk(KERN_ERR "asoc: can't open codec %s\n",
508 rtd->codec_dai->name);
509 goto codec_dai_err;
510 }
511 }
512
513 /* create runtime params from DMA, codec and cpu DAI */
514 if (runtime->hw.rates)
515 runtime->hw.rates &=
516 get_rates(codec_dai->caps.mode, codec_dai->caps.num_modes) &
517 get_rates(cpu_dai->caps.mode, cpu_dai->caps.num_modes);
518 else
519 runtime->hw.rates =
520 get_rates(codec_dai->caps.mode, codec_dai->caps.num_modes) &
521 get_rates(cpu_dai->caps.mode, cpu_dai->caps.num_modes);
522 if (runtime->hw.formats)
523 runtime->hw.formats &=
524 get_formats(codec_dai->caps.mode, codec_dai->caps.num_modes) &
525 get_formats(cpu_dai->caps.mode, cpu_dai->caps.num_modes);
526 else
527 runtime->hw.formats =
528 get_formats(codec_dai->caps.mode, codec_dai->caps.num_modes) &
529 get_formats(cpu_dai->caps.mode, cpu_dai->caps.num_modes);
530
531 /* Check that the codec and cpu DAI's are compatible */
532 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
533 runtime->hw.rate_min =
534 max(rtd->codec_dai->playback.rate_min,
535 rtd->cpu_dai->playback.rate_min);
536 runtime->hw.rate_max =
537 min(rtd->codec_dai->playback.rate_max,
538 rtd->cpu_dai->playback.rate_max);
539 runtime->hw.channels_min =
540 max(rtd->codec_dai->playback.channels_min,
541 rtd->cpu_dai->playback.channels_min);
542 runtime->hw.channels_max =
543 min(rtd->codec_dai->playback.channels_max,
544 rtd->cpu_dai->playback.channels_max);
545 } else {
546 runtime->hw.rate_min =
547 max(rtd->codec_dai->capture.rate_min,
548 rtd->cpu_dai->capture.rate_min);
549 runtime->hw.rate_max =
550 min(rtd->codec_dai->capture.rate_max,
551 rtd->cpu_dai->capture.rate_max);
552 runtime->hw.channels_min =
553 max(rtd->codec_dai->capture.channels_min,
554 rtd->cpu_dai->capture.channels_min);
555 runtime->hw.channels_max =
556 min(rtd->codec_dai->capture.channels_max,
557 rtd->cpu_dai->capture.channels_max);
558 }
559
560 snd_pcm_limit_hw_rates(runtime);
561 if (!runtime->hw.rates) {
562 printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
563 rtd->codec_dai->name, rtd->cpu_dai->name);
564 goto codec_dai_err;
565 }
566 if (!runtime->hw.formats) {
567 printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
568 rtd->codec_dai->name, rtd->cpu_dai->name);
569 goto codec_dai_err;
570 }
571 if (!runtime->hw.channels_min || !runtime->hw.channels_max) {
572 printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
573 rtd->codec_dai->name, rtd->cpu_dai->name);
574 goto codec_dai_err;
575 }
576
577 dbg("asoc: %s <-> %s info:\n", rtd->codec_dai->name, rtd->cpu_dai->name);
578 dbg("asoc: rate mask 0x%x \nasoc: min ch %d max ch %d\n
579 asoc: min rate %d max rate %d\n",
580 runtime->hw.rates, runtime->hw.channels_min,
581 runtime->hw.channels_max, runtime->hw.rate_min, runtime->hw.rate_max);
582
583
584 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
585 rtd->cpu_dai->playback.active = rtd->codec_dai->playback.active = 1;
586 else
587 rtd->cpu_dai->capture.active = rtd->codec_dai->capture.active = 1;
588 rtd->cpu_dai->active = rtd->codec_dai->active = 1;
589 rtd->cpu_dai->runtime = runtime;
590 socdev->codec->active++;
591 mutex_unlock(&pcm_mutex);
592 return 0;
593
594codec_dai_err:
595 if (machine->ops && machine->ops->shutdown)
596 machine->ops->shutdown(substream);
597
598machine_err:
599 if (platform->pcm_ops->close)
600 platform->pcm_ops->close(substream);
601
602platform_err:
603 if (rtd->cpu_dai->ops.shutdown)
604 rtd->cpu_dai->ops.shutdown(substream);
605out:
606 mutex_unlock(&pcm_mutex);
607 return ret;
608}
609
610/*
611 * Power down the audio subsytem pmdown_time msecs after close is called.
612 * This is to ensure there are no pops or clicks in between any music tracks
613 * due to DAPM power cycling.
614 */
615static void close_delayed_work(void *data)
616{
617 struct snd_soc_device *socdev = data;
618 struct snd_soc_codec *codec = socdev->codec;
619 struct snd_soc_codec_dai *codec_dai;
620 int i;
621
622 mutex_lock(&pcm_mutex);
623 for(i = 0; i < codec->num_dai; i++) {
624 codec_dai = &codec->dai[i];
625
626 dbg("pop wq checking: %s status: %s waiting: %s\n",
627 codec_dai->playback.stream_name,
628 codec_dai->playback.active ? "active" : "inactive",
629 codec_dai->pop_wait ? "yes" : "no");
630
631 /* are we waiting on this codec DAI stream */
632 if (codec_dai->pop_wait == 1) {
633
634 codec_dai->pop_wait = 0;
635 snd_soc_dapm_stream_event(codec, codec_dai->playback.stream_name,
636 SND_SOC_DAPM_STREAM_STOP);
637
638 /* power down the codec power domain if no longer active */
639 if (codec->active == 0) {
640 dbg("pop wq D3 %s %s\n", codec->name,
641 codec_dai->playback.stream_name);
642 if (codec->dapm_event)
643 codec->dapm_event(codec, SNDRV_CTL_POWER_D3hot);
644 }
645 }
646 }
647 mutex_unlock(&pcm_mutex);
648}
649
650/*
651 * Called by ALSA when a PCM substream is closed. Private data can be
652 * freed here. The cpu DAI, codec DAI, machine and platform are also
653 * shutdown.
654 */
655static int soc_codec_close(struct snd_pcm_substream *substream)
656{
657 struct snd_soc_pcm_runtime *rtd = substream->private_data;
658 struct snd_soc_device *socdev = rtd->socdev;
659 struct snd_soc_machine *machine = socdev->machine;
660 struct snd_soc_platform *platform = socdev->platform;
661 struct snd_soc_codec *codec = socdev->codec;
662
663 mutex_lock(&pcm_mutex);
664
665 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
666 rtd->cpu_dai->playback.active = rtd->codec_dai->playback.active = 0;
667 else
668 rtd->cpu_dai->capture.active = rtd->codec_dai->capture.active = 0;
669
670 if (rtd->codec_dai->playback.active == 0 &&
671 rtd->codec_dai->capture.active == 0) {
672 rtd->cpu_dai->active = rtd->codec_dai->active = 0;
673 }
674 codec->active--;
675
676 if (rtd->cpu_dai->ops.shutdown)
677 rtd->cpu_dai->ops.shutdown(substream);
678
679 if (rtd->codec_dai->ops.shutdown)
680 rtd->codec_dai->ops.shutdown(substream);
681
682 if (machine->ops && machine->ops->shutdown)
683 machine->ops->shutdown(substream);
684
685 if (platform->pcm_ops->close)
686 platform->pcm_ops->close(substream);
687 rtd->cpu_dai->runtime = NULL;
688
689 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
690 /* start delayed pop wq here for playback streams */
691 rtd->codec_dai->pop_wait = 1;
692 queue_delayed_work(soc_workq, &soc_stream_work,
693 msecs_to_jiffies(pmdown_time));
694 } else {
695 /* capture streams can be powered down now */
696 snd_soc_dapm_stream_event(codec, rtd->codec_dai->capture.stream_name,
697 SND_SOC_DAPM_STREAM_STOP);
698
699 if (codec->active == 0 && rtd->codec_dai->pop_wait == 0){
700 if (codec->dapm_event)
701 codec->dapm_event(codec, SNDRV_CTL_POWER_D3hot);
702 }
703 }
704
705 mutex_unlock(&pcm_mutex);
706 return 0;
707}
708
709/*
710 * Called by ALSA when the PCM substream is prepared, can set format, sample
711 * rate, etc. This function is non atomic and can be called multiple times,
712 * it can refer to the runtime info.
713 */
714static int soc_pcm_prepare(struct snd_pcm_substream *substream)
715{
716 struct snd_soc_pcm_runtime *rtd = substream->private_data;
717 struct snd_soc_device *socdev = rtd->socdev;
718 struct snd_soc_platform *platform = socdev->platform;
719 struct snd_soc_codec *codec = socdev->codec;
720 int ret = 0;
721
722 mutex_lock(&pcm_mutex);
723 if (platform->pcm_ops->prepare) {
724 ret = platform->pcm_ops->prepare(substream);
725 if (ret < 0)
726 goto out;
727 }
728
729 if (rtd->codec_dai->ops.prepare) {
730 ret = rtd->codec_dai->ops.prepare(substream);
731 if (ret < 0)
732 goto out;
733 }
734
735 if (rtd->cpu_dai->ops.prepare)
736 ret = rtd->cpu_dai->ops.prepare(substream);
737
738 /* we only want to start a DAPM playback stream if we are not waiting
739 * on an existing one stopping */
740 if (rtd->codec_dai->pop_wait) {
741 /* we are waiting for the delayed work to start */
742 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
743 snd_soc_dapm_stream_event(codec,
744 rtd->codec_dai->capture.stream_name,
745 SND_SOC_DAPM_STREAM_START);
746 else {
747 rtd->codec_dai->pop_wait = 0;
748 cancel_delayed_work(&soc_stream_work);
749 if (rtd->codec_dai->digital_mute)
750 rtd->codec_dai->digital_mute(codec, rtd->codec_dai, 0);
751 }
752 } else {
753 /* no delayed work - do we need to power up codec */
754 if (codec->dapm_state != SNDRV_CTL_POWER_D0) {
755
756 if (codec->dapm_event)
757 codec->dapm_event(codec, SNDRV_CTL_POWER_D1);
758
759 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
760 snd_soc_dapm_stream_event(codec,
761 rtd->codec_dai->playback.stream_name,
762 SND_SOC_DAPM_STREAM_START);
763 else
764 snd_soc_dapm_stream_event(codec,
765 rtd->codec_dai->capture.stream_name,
766 SND_SOC_DAPM_STREAM_START);
767
768 if (codec->dapm_event)
769 codec->dapm_event(codec, SNDRV_CTL_POWER_D0);
770 if (rtd->codec_dai->digital_mute)
771 rtd->codec_dai->digital_mute(codec, rtd->codec_dai, 0);
772
773 } else {
774 /* codec already powered - power on widgets */
775 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
776 snd_soc_dapm_stream_event(codec,
777 rtd->codec_dai->playback.stream_name,
778 SND_SOC_DAPM_STREAM_START);
779 else
780 snd_soc_dapm_stream_event(codec,
781 rtd->codec_dai->capture.stream_name,
782 SND_SOC_DAPM_STREAM_START);
783 if (rtd->codec_dai->digital_mute)
784 rtd->codec_dai->digital_mute(codec, rtd->codec_dai, 0);
785 }
786 }
787
788out:
789 mutex_unlock(&pcm_mutex);
790 return ret;
791}
792
793/*
794 * Called by ALSA when the hardware params are set by application. This
795 * function can also be called multiple times and can allocate buffers
796 * (using snd_pcm_lib_* ). It's non-atomic.
797 */
798static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
799 struct snd_pcm_hw_params *params)
800{
801 struct snd_soc_pcm_runtime *rtd = substream->private_data;
802 struct snd_soc_device *socdev = rtd->socdev;
803 struct snd_soc_platform *platform = socdev->platform;
804 struct snd_soc_machine *machine = socdev->machine;
805 int ret = 0;
806
807 mutex_lock(&pcm_mutex);
808
809 /* we don't need to match any AC97 params */
810 if (rtd->cpu_dai->type != SND_SOC_DAI_AC97) {
811 ret = soc_hw_match_params(substream, params);
812 if (ret < 0)
813 goto out;
814 } else {
815 struct snd_soc_clock_info clk_info;
816 clk_info.rate = params_rate(params);
817 ret = soc_get_mclk(rtd, &clk_info);
818 if (ret < 0)
819 goto out;
820 }
821
822 if (rtd->codec_dai->ops.hw_params) {
823 ret = rtd->codec_dai->ops.hw_params(substream, params);
824 if (ret < 0) {
825 printk(KERN_ERR "asoc: can't set codec %s hw params\n",
826 rtd->codec_dai->name);
827 goto out;
828 }
829 }
830
831 if (rtd->cpu_dai->ops.hw_params) {
832 ret = rtd->cpu_dai->ops.hw_params(substream, params);
833 if (ret < 0) {
834 printk(KERN_ERR "asoc: can't set interface %s hw params\n",
835 rtd->cpu_dai->name);
836 goto interface_err;
837 }
838 }
839
840 if (platform->pcm_ops->hw_params) {
841 ret = platform->pcm_ops->hw_params(substream, params);
842 if (ret < 0) {
843 printk(KERN_ERR "asoc: can't set platform %s hw params\n",
844 platform->name);
845 goto platform_err;
846 }
847 }
848
849 if (machine->ops && machine->ops->hw_params) {
850 ret = machine->ops->hw_params(substream, params);
851 if (ret < 0) {
852 printk(KERN_ERR "asoc: machine hw_params failed\n");
853 goto machine_err;
854 }
855 }
856
857out:
858 mutex_unlock(&pcm_mutex);
859 return ret;
860
861machine_err:
862 if (platform->pcm_ops->hw_free)
863 platform->pcm_ops->hw_free(substream);
864
865platform_err:
866 if (rtd->cpu_dai->ops.hw_free)
867 rtd->cpu_dai->ops.hw_free(substream);
868
869interface_err:
870 if (rtd->codec_dai->ops.hw_free)
871 rtd->codec_dai->ops.hw_free(substream);
872
873 mutex_unlock(&pcm_mutex);
874 return ret;
875}
876
877/*
878 * Free's resources allocated by hw_params, can be called multiple times
879 */
880static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
881{
882 struct snd_soc_pcm_runtime *rtd = substream->private_data;
883 struct snd_soc_device *socdev = rtd->socdev;
884 struct snd_soc_platform *platform = socdev->platform;
885 struct snd_soc_codec *codec = socdev->codec;
886 struct snd_soc_machine *machine = socdev->machine;
887
888 mutex_lock(&pcm_mutex);
889
890 /* apply codec digital mute */
891 if (!codec->active && rtd->codec_dai->digital_mute)
892 rtd->codec_dai->digital_mute(codec, rtd->codec_dai, 1);
893
894 /* free any machine hw params */
895 if (machine->ops && machine->ops->hw_free)
896 machine->ops->hw_free(substream);
897
898 /* free any DMA resources */
899 if (platform->pcm_ops->hw_free)
900 platform->pcm_ops->hw_free(substream);
901
902 /* now free hw params for the DAI's */
903 if (rtd->codec_dai->ops.hw_free)
904 rtd->codec_dai->ops.hw_free(substream);
905
906 if (rtd->cpu_dai->ops.hw_free)
907 rtd->cpu_dai->ops.hw_free(substream);
908
909 mutex_unlock(&pcm_mutex);
910 return 0;
911}
912
913static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
914{
915 struct snd_soc_pcm_runtime *rtd = substream->private_data;
916 struct snd_soc_device *socdev = rtd->socdev;
917 struct snd_soc_platform *platform = socdev->platform;
918 int ret;
919
920 if (rtd->codec_dai->ops.trigger) {
921 ret = rtd->codec_dai->ops.trigger(substream, cmd);
922 if (ret < 0)
923 return ret;
924 }
925
926 if (platform->pcm_ops->trigger) {
927 ret = platform->pcm_ops->trigger(substream, cmd);
928 if (ret < 0)
929 return ret;
930 }
931
932 if (rtd->cpu_dai->ops.trigger) {
933 ret = rtd->cpu_dai->ops.trigger(substream, cmd);
934 if (ret < 0)
935 return ret;
936 }
937 return 0;
938}
939
940/* ASoC PCM operations */
941static struct snd_pcm_ops soc_pcm_ops = {
942 .open = soc_pcm_open,
943 .close = soc_codec_close,
944 .hw_params = soc_pcm_hw_params,
945 .hw_free = soc_pcm_hw_free,
946 .prepare = soc_pcm_prepare,
947 .trigger = soc_pcm_trigger,
948};
949
950#ifdef CONFIG_PM
951/* powers down audio subsystem for suspend */
952static int soc_suspend(struct platform_device *pdev, pm_message_t state)
953{
954 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
955 struct snd_soc_machine *machine = socdev->machine;
956 struct snd_soc_platform *platform = socdev->platform;
957 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
958 struct snd_soc_codec *codec = socdev->codec;
959 int i;
960
961 /* mute any active DAC's */
962 for(i = 0; i < machine->num_links; i++) {
963 struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai;
964 if (dai->digital_mute && dai->playback.active)
965 dai->digital_mute(codec, dai, 1);
966 }
967
968 if (machine->suspend_pre)
969 machine->suspend_pre(pdev, state);
970
971 for(i = 0; i < machine->num_links; i++) {
972 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai;
973 if (cpu_dai->suspend && cpu_dai->type != SND_SOC_DAI_AC97)
974 cpu_dai->suspend(pdev, cpu_dai);
975 if (platform->suspend)
976 platform->suspend(pdev, cpu_dai);
977 }
978
979 /* close any waiting streams and save state */
980 flush_workqueue(soc_workq);
981 codec->suspend_dapm_state = codec->dapm_state;
982
983 for(i = 0; i < codec->num_dai; i++) {
984 char *stream = codec->dai[i].playback.stream_name;
985 if (stream != NULL)
986 snd_soc_dapm_stream_event(codec, stream,
987 SND_SOC_DAPM_STREAM_SUSPEND);
988 stream = codec->dai[i].capture.stream_name;
989 if (stream != NULL)
990 snd_soc_dapm_stream_event(codec, stream,
991 SND_SOC_DAPM_STREAM_SUSPEND);
992 }
993
994 if (codec_dev->suspend)
995 codec_dev->suspend(pdev, state);
996
997 for(i = 0; i < machine->num_links; i++) {
998 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai;
999 if (cpu_dai->suspend && cpu_dai->type == SND_SOC_DAI_AC97)
1000 cpu_dai->suspend(pdev, cpu_dai);
1001 }
1002
1003 if (machine->suspend_post)
1004 machine->suspend_post(pdev, state);
1005
1006 return 0;
1007}
1008
1009/* powers up audio subsystem after a suspend */
1010static int soc_resume(struct platform_device *pdev)
1011{
1012 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1013 struct snd_soc_machine *machine = socdev->machine;
1014 struct snd_soc_platform *platform = socdev->platform;
1015 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
1016 struct snd_soc_codec *codec = socdev->codec;
1017 int i;
1018
1019 if (machine->resume_pre)
1020 machine->resume_pre(pdev);
1021
1022 for(i = 0; i < machine->num_links; i++) {
1023 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai;
1024 if (cpu_dai->resume && cpu_dai->type == SND_SOC_DAI_AC97)
1025 cpu_dai->resume(pdev, cpu_dai);
1026 }
1027
1028 if (codec_dev->resume)
1029 codec_dev->resume(pdev);
1030
1031 for(i = 0; i < codec->num_dai; i++) {
1032 char* stream = codec->dai[i].playback.stream_name;
1033 if (stream != NULL)
1034 snd_soc_dapm_stream_event(codec, stream,
1035 SND_SOC_DAPM_STREAM_RESUME);
1036 stream = codec->dai[i].capture.stream_name;
1037 if (stream != NULL)
1038 snd_soc_dapm_stream_event(codec, stream,
1039 SND_SOC_DAPM_STREAM_RESUME);
1040 }
1041
1042 /* unmute any active DAC's */
1043 for(i = 0; i < machine->num_links; i++) {
1044 struct snd_soc_codec_dai *dai = machine->dai_link[i].codec_dai;
1045 if (dai->digital_mute && dai->playback.active)
1046 dai->digital_mute(codec, dai, 0);
1047 }
1048
1049 for(i = 0; i < machine->num_links; i++) {
1050 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai;
1051 if (cpu_dai->resume && cpu_dai->type != SND_SOC_DAI_AC97)
1052 cpu_dai->resume(pdev, cpu_dai);
1053 if (platform->resume)
1054 platform->resume(pdev, cpu_dai);
1055 }
1056
1057 if (machine->resume_post)
1058 machine->resume_post(pdev);
1059
1060 return 0;
1061}
1062
1063#else
1064#define soc_suspend NULL
1065#define soc_resume NULL
1066#endif
1067
1068/* probes a new socdev */
1069static int soc_probe(struct platform_device *pdev)
1070{
1071 int ret = 0, i;
1072 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1073 struct snd_soc_machine *machine = socdev->machine;
1074 struct snd_soc_platform *platform = socdev->platform;
1075 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
1076
1077 if (machine->probe) {
1078 ret = machine->probe(pdev);
1079 if(ret < 0)
1080 return ret;
1081 }
1082
1083 for (i = 0; i < machine->num_links; i++) {
1084 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai;
1085 if (cpu_dai->probe) {
1086 ret = cpu_dai->probe(pdev);
1087 if(ret < 0)
1088 goto cpu_dai_err;
1089 }
1090 }
1091
1092 if (codec_dev->probe) {
1093 ret = codec_dev->probe(pdev);
1094 if(ret < 0)
1095 goto cpu_dai_err;
1096 }
1097
1098 if (platform->probe) {
1099 ret = platform->probe(pdev);
1100 if(ret < 0)
1101 goto platform_err;
1102 }
1103
1104 /* DAPM stream work */
1105 soc_workq = create_workqueue("kdapm");
1106 if (soc_workq == NULL)
1107 goto work_err;
1108 INIT_WORK(&soc_stream_work, close_delayed_work, socdev);
1109 return 0;
1110
1111work_err:
1112 if (platform->remove)
1113 platform->remove(pdev);
1114
1115platform_err:
1116 if (codec_dev->remove)
1117 codec_dev->remove(pdev);
1118
1119cpu_dai_err:
1120 for (i--; i > 0; i--) {
1121 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai;
1122 if (cpu_dai->remove)
1123 cpu_dai->remove(pdev);
1124 }
1125
1126 if (machine->remove)
1127 machine->remove(pdev);
1128
1129 return ret;
1130}
1131
1132/* removes a socdev */
1133static int soc_remove(struct platform_device *pdev)
1134{
1135 int i;
1136 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1137 struct snd_soc_machine *machine = socdev->machine;
1138 struct snd_soc_platform *platform = socdev->platform;
1139 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
1140
1141 if (soc_workq)
1142 destroy_workqueue(soc_workq);
1143
1144 if (platform->remove)
1145 platform->remove(pdev);
1146
1147 if (codec_dev->remove)
1148 codec_dev->remove(pdev);
1149
1150 for (i = 0; i < machine->num_links; i++) {
1151 struct snd_soc_cpu_dai *cpu_dai = machine->dai_link[i].cpu_dai;
1152 if (cpu_dai->remove)
1153 cpu_dai->remove(pdev);
1154 }
1155
1156 if (machine->remove)
1157 machine->remove(pdev);
1158
1159 return 0;
1160}
1161
1162/* ASoC platform driver */
1163static struct platform_driver soc_driver = {
1164 .driver = {
1165 .name = "soc-audio",
1166 },
1167 .probe = soc_probe,
1168 .remove = soc_remove,
1169 .suspend = soc_suspend,
1170 .resume = soc_resume,
1171};
1172
1173/* create a new pcm */
1174static int soc_new_pcm(struct snd_soc_device *socdev,
1175 struct snd_soc_dai_link *dai_link, int num)
1176{
1177 struct snd_soc_codec *codec = socdev->codec;
1178 struct snd_soc_codec_dai *codec_dai = dai_link->codec_dai;
1179 struct snd_soc_cpu_dai *cpu_dai = dai_link->cpu_dai;
1180 struct snd_soc_pcm_runtime *rtd;
1181 struct snd_pcm *pcm;
1182 char new_name[64];
1183 int ret = 0, playback = 0, capture = 0;
1184
1185 rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime), GFP_KERNEL);
1186 if (rtd == NULL)
1187 return -ENOMEM;
1188 rtd->cpu_dai = cpu_dai;
1189 rtd->codec_dai = codec_dai;
1190 rtd->socdev = socdev;
1191
1192 /* check client and interface hw capabilities */
1193 sprintf(new_name, "%s %s-%s-%d",dai_link->stream_name, codec_dai->name,
1194 get_dai_name(cpu_dai->type), num);
1195
1196 if (codec_dai->playback.channels_min)
1197 playback = 1;
1198 if (codec_dai->capture.channels_min)
1199 capture = 1;
1200
1201 ret = snd_pcm_new(codec->card, new_name, codec->pcm_devs++, playback,
1202 capture, &pcm);
1203 if (ret < 0) {
1204 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name);
1205 kfree(rtd);
1206 return ret;
1207 }
1208
1209 pcm->private_data = rtd;
1210 soc_pcm_ops.mmap = socdev->platform->pcm_ops->mmap;
1211 soc_pcm_ops.pointer = socdev->platform->pcm_ops->pointer;
1212 soc_pcm_ops.ioctl = socdev->platform->pcm_ops->ioctl;
1213 soc_pcm_ops.copy = socdev->platform->pcm_ops->copy;
1214 soc_pcm_ops.silence = socdev->platform->pcm_ops->silence;
1215 soc_pcm_ops.ack = socdev->platform->pcm_ops->ack;
1216 soc_pcm_ops.page = socdev->platform->pcm_ops->page;
1217
1218 if (playback)
1219 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
1220
1221 if (capture)
1222 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
1223
1224 ret = socdev->platform->pcm_new(codec->card, codec_dai, pcm);
1225 if (ret < 0) {
1226 printk(KERN_ERR "asoc: platform pcm constructor failed\n");
1227 kfree(rtd);
1228 return ret;
1229 }
1230
1231 pcm->private_free = socdev->platform->pcm_free;
1232 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
1233 cpu_dai->name);
1234 return ret;
1235}
1236
1237/* codec register dump */
1238static ssize_t codec_reg_show(struct device *dev,
1239 struct device_attribute *attr, char *buf)
1240{
1241 struct snd_soc_device *devdata = dev_get_drvdata(dev);
1242 struct snd_soc_codec *codec = devdata->codec;
1243 int i, step = 1, count = 0;
1244
1245 if (!codec->reg_cache_size)
1246 return 0;
1247
1248 if (codec->reg_cache_step)
1249 step = codec->reg_cache_step;
1250
1251 count += sprintf(buf, "%s registers\n", codec->name);
1252 for(i = 0; i < codec->reg_cache_size; i += step)
1253 count += sprintf(buf + count, "%2x: %4x\n", i, codec->read(codec, i));
1254
1255 return count;
1256}
1257static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
1258
1259/**
1260 * snd_soc_new_ac97_codec - initailise AC97 device
1261 * @codec: audio codec
1262 * @ops: AC97 bus operations
1263 * @num: AC97 codec number
1264 *
1265 * Initialises AC97 codec resources for use by ad-hoc devices only.
1266 */
1267int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
1268 struct snd_ac97_bus_ops *ops, int num)
1269{
1270 mutex_lock(&codec->mutex);
1271
1272 codec->ac97 = kzalloc(sizeof(struct snd_ac97), GFP_KERNEL);
1273 if (codec->ac97 == NULL) {
1274 mutex_unlock(&codec->mutex);
1275 return -ENOMEM;
1276 }
1277
1278 codec->ac97->bus = kzalloc(sizeof(struct snd_ac97_bus), GFP_KERNEL);
1279 if (codec->ac97->bus == NULL) {
1280 kfree(codec->ac97);
1281 codec->ac97 = NULL;
1282 mutex_unlock(&codec->mutex);
1283 return -ENOMEM;
1284 }
1285
1286 codec->ac97->bus->ops = ops;
1287 codec->ac97->num = num;
1288 mutex_unlock(&codec->mutex);
1289 return 0;
1290}
1291EXPORT_SYMBOL_GPL(snd_soc_new_ac97_codec);
1292
1293/**
1294 * snd_soc_free_ac97_codec - free AC97 codec device
1295 * @codec: audio codec
1296 *
1297 * Frees AC97 codec device resources.
1298 */
1299void snd_soc_free_ac97_codec(struct snd_soc_codec *codec)
1300{
1301 mutex_lock(&codec->mutex);
1302 kfree(codec->ac97->bus);
1303 kfree(codec->ac97);
1304 codec->ac97 = NULL;
1305 mutex_unlock(&codec->mutex);
1306}
1307EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
1308
1309/**
1310 * snd_soc_update_bits - update codec register bits
1311 * @codec: audio codec
1312 * @reg: codec register
1313 * @mask: register mask
1314 * @value: new value
1315 *
1316 * Writes new register value.
1317 *
1318 * Returns 1 for change else 0.
1319 */
1320int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
1321 unsigned short mask, unsigned short value)
1322{
1323 int change;
1324 unsigned short old, new;
1325
1326 mutex_lock(&io_mutex);
1327 old = snd_soc_read(codec, reg);
1328 new = (old & ~mask) | value;
1329 change = old != new;
1330 if (change)
1331 snd_soc_write(codec, reg, new);
1332
1333 mutex_unlock(&io_mutex);
1334 return change;
1335}
1336EXPORT_SYMBOL_GPL(snd_soc_update_bits);
1337
1338/**
1339 * snd_soc_test_bits - test register for change
1340 * @codec: audio codec
1341 * @reg: codec register
1342 * @mask: register mask
1343 * @value: new value
1344 *
1345 * Tests a register with a new value and checks if the new value is
1346 * different from the old value.
1347 *
1348 * Returns 1 for change else 0.
1349 */
1350int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
1351 unsigned short mask, unsigned short value)
1352{
1353 int change;
1354 unsigned short old, new;
1355
1356 mutex_lock(&io_mutex);
1357 old = snd_soc_read(codec, reg);
1358 new = (old & ~mask) | value;
1359 change = old != new;
1360 mutex_unlock(&io_mutex);
1361
1362 return change;
1363}
1364EXPORT_SYMBOL_GPL(snd_soc_test_bits);
1365
1366/**
1367 * snd_soc_get_rate - get int sample rate
1368 * @hwpcmrate: the hardware pcm rate
1369 *
1370 * Returns the audio rate integaer value, else 0.
1371 */
1372int snd_soc_get_rate(int hwpcmrate)
1373{
1374 int rate = ffs(hwpcmrate) - 1;
1375
1376 if (rate > ARRAY_SIZE(rates))
1377 return 0;
1378 return rates[rate];
1379}
1380EXPORT_SYMBOL_GPL(snd_soc_get_rate);
1381
1382/**
1383 * snd_soc_new_pcms - create new sound card and pcms
1384 * @socdev: the SoC audio device
1385 *
1386 * Create a new sound card based upon the codec and interface pcms.
1387 *
1388 * Returns 0 for success, else error.
1389 */
1390int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char * xid)
1391{
1392 struct snd_soc_codec *codec = socdev->codec;
1393 struct snd_soc_machine *machine = socdev->machine;
1394 int ret = 0, i;
1395
1396 mutex_lock(&codec->mutex);
1397
1398 /* register a sound card */
1399 codec->card = snd_card_new(idx, xid, codec->owner, 0);
1400 if (!codec->card) {
1401 printk(KERN_ERR "asoc: can't create sound card for codec %s\n",
1402 codec->name);
1403 mutex_unlock(&codec->mutex);
1404 return -ENODEV;
1405 }
1406
1407 codec->card->dev = socdev->dev;
1408 codec->card->private_data = codec;
1409 strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver));
1410
1411 /* create the pcms */
1412 for(i = 0; i < machine->num_links; i++) {
1413 ret = soc_new_pcm(socdev, &machine->dai_link[i], i);
1414 if (ret < 0) {
1415 printk(KERN_ERR "asoc: can't create pcm %s\n",
1416 machine->dai_link[i].stream_name);
1417 mutex_unlock(&codec->mutex);
1418 return ret;
1419 }
1420 }
1421
1422 mutex_unlock(&codec->mutex);
1423 return ret;
1424}
1425EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1426
1427/**
1428 * snd_soc_register_card - register sound card
1429 * @socdev: the SoC audio device
1430 *
1431 * Register a SoC sound card. Also registers an AC97 device if the
1432 * codec is AC97 for ad hoc devices.
1433 *
1434 * Returns 0 for success, else error.
1435 */
1436int snd_soc_register_card(struct snd_soc_device *socdev)
1437{
1438 struct snd_soc_codec *codec = socdev->codec;
1439 struct snd_soc_machine *machine = socdev->machine;
1440 int ret = 0, i, ac97 = 0;
1441
1442 mutex_lock(&codec->mutex);
1443 for(i = 0; i < machine->num_links; i++) {
1444 if (socdev->machine->dai_link[i].init)
1445 socdev->machine->dai_link[i].init(codec);
1446 if (socdev->machine->dai_link[i].cpu_dai->type == SND_SOC_DAI_AC97)
1447 ac97 = 1;
1448 }
1449 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1450 "%s", machine->name);
1451 snprintf(codec->card->longname, sizeof(codec->card->longname),
1452 "%s (%s)", machine->name, codec->name);
1453
1454 ret = snd_card_register(codec->card);
1455 if (ret < 0) {
1456 printk(KERN_ERR "asoc: failed to register soundcard for codec %s\n",
1457 codec->name);
1458 mutex_unlock(&codec->mutex);
1459 return ret;
1460 }
1461
1462#ifdef CONFIG_SND_SOC_AC97_BUS
1463 if (ac97)
1464 soc_ac97_dev_register(codec);
1465#endif
1466
1467 snd_soc_dapm_sys_add(socdev->dev);
1468 device_create_file(socdev->dev, &dev_attr_codec_reg);
1469 mutex_unlock(&codec->mutex);
1470 return ret;
1471}
1472EXPORT_SYMBOL_GPL(snd_soc_register_card);
1473
1474/**
1475 * snd_soc_free_pcms - free sound card and pcms
1476 * @socdev: the SoC audio device
1477 *
1478 * Frees sound card and pcms associated with the socdev.
1479 * Also unregister the codec if it is an AC97 device.
1480 */
1481void snd_soc_free_pcms(struct snd_soc_device *socdev)
1482{
1483 struct snd_soc_codec *codec = socdev->codec;
1484
1485 mutex_lock(&codec->mutex);
1486#ifdef CONFIG_SND_SOC_AC97_BUS
1487 if (codec->ac97)
1488 soc_ac97_dev_unregister(codec);
1489#endif
1490
1491 if (codec->card)
1492 snd_card_free(codec->card);
1493 device_remove_file(socdev->dev, &dev_attr_codec_reg);
1494 mutex_unlock(&codec->mutex);
1495}
1496EXPORT_SYMBOL_GPL(snd_soc_free_pcms);
1497
1498/**
1499 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
1500 * @substream: the pcm substream
1501 * @hw: the hardware parameters
1502 *
1503 * Sets the substream runtime hardware parameters.
1504 */
1505int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
1506 const struct snd_pcm_hardware *hw)
1507{
1508 struct snd_pcm_runtime *runtime = substream->runtime;
1509 runtime->hw.info = hw->info;
1510 runtime->hw.formats = hw->formats;
1511 runtime->hw.period_bytes_min = hw->period_bytes_min;
1512 runtime->hw.period_bytes_max = hw->period_bytes_max;
1513 runtime->hw.periods_min = hw->periods_min;
1514 runtime->hw.periods_max = hw->periods_max;
1515 runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
1516 runtime->hw.fifo_size = hw->fifo_size;
1517 return 0;
1518}
1519EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
1520
1521/**
1522 * snd_soc_cnew - create new control
1523 * @_template: control template
1524 * @data: control private data
1525 * @lnng_name: control long name
1526 *
1527 * Create a new mixer control from a template control.
1528 *
1529 * Returns 0 for success, else error.
1530 */
1531struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
1532 void *data, char *long_name)
1533{
1534 struct snd_kcontrol_new template;
1535
1536 memcpy(&template, _template, sizeof(template));
1537 if (long_name)
1538 template.name = long_name;
1539 template.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
1540 template.index = 0;
1541
1542 return snd_ctl_new1(&template, data);
1543}
1544EXPORT_SYMBOL_GPL(snd_soc_cnew);
1545
1546/**
1547 * snd_soc_info_enum_double - enumerated double mixer info callback
1548 * @kcontrol: mixer control
1549 * @uinfo: control element information
1550 *
1551 * Callback to provide information about a double enumerated
1552 * mixer control.
1553 *
1554 * Returns 0 for success.
1555 */
1556int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
1557 struct snd_ctl_elem_info *uinfo)
1558{
1559 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1560
1561 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1562 uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
1563 uinfo->value.enumerated.items = e->mask;
1564
1565 if (uinfo->value.enumerated.item > e->mask - 1)
1566 uinfo->value.enumerated.item = e->mask - 1;
1567 strcpy(uinfo->value.enumerated.name,
1568 e->texts[uinfo->value.enumerated.item]);
1569 return 0;
1570}
1571EXPORT_SYMBOL_GPL(snd_soc_info_enum_double);
1572
1573/**
1574 * snd_soc_get_enum_double - enumerated double mixer get callback
1575 * @kcontrol: mixer control
1576 * @uinfo: control element information
1577 *
1578 * Callback to get the value of a double enumerated mixer.
1579 *
1580 * Returns 0 for success.
1581 */
1582int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
1583 struct snd_ctl_elem_value *ucontrol)
1584{
1585 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1586 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1587 unsigned short val, bitmask;
1588
1589 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1)
1590 ;
1591 val = snd_soc_read(codec, e->reg);
1592 ucontrol->value.enumerated.item[0] = (val >> e->shift_l) & (bitmask - 1);
1593 if (e->shift_l != e->shift_r)
1594 ucontrol->value.enumerated.item[1] =
1595 (val >> e->shift_r) & (bitmask - 1);
1596
1597 return 0;
1598}
1599EXPORT_SYMBOL_GPL(snd_soc_get_enum_double);
1600
1601/**
1602 * snd_soc_put_enum_double - enumerated double mixer put callback
1603 * @kcontrol: mixer control
1604 * @uinfo: control element information
1605 *
1606 * Callback to set the value of a double enumerated mixer.
1607 *
1608 * Returns 0 for success.
1609 */
1610int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1611 struct snd_ctl_elem_value *ucontrol)
1612{
1613 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1614 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1615 unsigned short val;
1616 unsigned short mask, bitmask;
1617
1618 for (bitmask = 1; bitmask < e->mask; bitmask <<= 1)
1619 ;
1620 if (ucontrol->value.enumerated.item[0] > e->mask - 1)
1621 return -EINVAL;
1622 val = ucontrol->value.enumerated.item[0] << e->shift_l;
1623 mask = (bitmask - 1) << e->shift_l;
1624 if (e->shift_l != e->shift_r) {
1625 if (ucontrol->value.enumerated.item[1] > e->mask - 1)
1626 return -EINVAL;
1627 val |= ucontrol->value.enumerated.item[1] << e->shift_r;
1628 mask |= (bitmask - 1) << e->shift_r;
1629 }
1630
1631 return snd_soc_update_bits(codec, e->reg, mask, val);
1632}
1633EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
1634
1635/**
1636 * snd_soc_info_enum_ext - external enumerated single mixer info callback
1637 * @kcontrol: mixer control
1638 * @uinfo: control element information
1639 *
1640 * Callback to provide information about an external enumerated
1641 * single mixer.
1642 *
1643 * Returns 0 for success.
1644 */
1645int snd_soc_info_enum_ext(struct snd_kcontrol *kcontrol,
1646 struct snd_ctl_elem_info *uinfo)
1647{
1648 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1649
1650 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1651 uinfo->count = 1;
1652 uinfo->value.enumerated.items = e->mask;
1653
1654 if (uinfo->value.enumerated.item > e->mask - 1)
1655 uinfo->value.enumerated.item = e->mask - 1;
1656 strcpy(uinfo->value.enumerated.name,
1657 e->texts[uinfo->value.enumerated.item]);
1658 return 0;
1659}
1660EXPORT_SYMBOL_GPL(snd_soc_info_enum_ext);
1661
1662/**
1663 * snd_soc_info_volsw_ext - external single mixer info callback
1664 * @kcontrol: mixer control
1665 * @uinfo: control element information
1666 *
1667 * Callback to provide information about a single external mixer control.
1668 *
1669 * Returns 0 for success.
1670 */
1671int snd_soc_info_volsw_ext(struct snd_kcontrol *kcontrol,
1672 struct snd_ctl_elem_info *uinfo)
1673{
1674 int mask = kcontrol->private_value;
1675
1676 uinfo->type =
1677 mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1678 uinfo->count = 1;
1679 uinfo->value.integer.min = 0;
1680 uinfo->value.integer.max = mask;
1681 return 0;
1682}
1683EXPORT_SYMBOL_GPL(snd_soc_info_volsw_ext);
1684
1685/**
1686 * snd_soc_info_bool_ext - external single boolean mixer info callback
1687 * @kcontrol: mixer control
1688 * @uinfo: control element information
1689 *
1690 * Callback to provide information about a single boolean external mixer control.
1691 *
1692 * Returns 0 for success.
1693 */
1694int snd_soc_info_bool_ext(struct snd_kcontrol *kcontrol,
1695 struct snd_ctl_elem_info *uinfo)
1696{
1697 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1698 uinfo->count = 1;
1699 uinfo->value.integer.min = 0;
1700 uinfo->value.integer.max = 1;
1701 return 0;
1702}
1703EXPORT_SYMBOL_GPL(snd_soc_info_bool_ext);
1704
1705/**
1706 * snd_soc_info_volsw - single mixer info callback
1707 * @kcontrol: mixer control
1708 * @uinfo: control element information
1709 *
1710 * Callback to provide information about a single mixer control.
1711 *
1712 * Returns 0 for success.
1713 */
1714int snd_soc_info_volsw(struct snd_kcontrol *kcontrol,
1715 struct snd_ctl_elem_info *uinfo)
1716{
1717 int mask = (kcontrol->private_value >> 16) & 0xff;
1718 int shift = (kcontrol->private_value >> 8) & 0x0f;
1719 int rshift = (kcontrol->private_value >> 12) & 0x0f;
1720
1721 uinfo->type =
1722 mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1723 uinfo->count = shift == rshift ? 1 : 2;
1724 uinfo->value.integer.min = 0;
1725 uinfo->value.integer.max = mask;
1726 return 0;
1727}
1728EXPORT_SYMBOL_GPL(snd_soc_info_volsw);
1729
1730/**
1731 * snd_soc_get_volsw - single mixer get callback
1732 * @kcontrol: mixer control
1733 * @uinfo: control element information
1734 *
1735 * Callback to get the value of a single mixer control.
1736 *
1737 * Returns 0 for success.
1738 */
1739int snd_soc_get_volsw(struct snd_kcontrol *kcontrol,
1740 struct snd_ctl_elem_value *ucontrol)
1741{
1742 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1743 int reg = kcontrol->private_value & 0xff;
1744 int shift = (kcontrol->private_value >> 8) & 0x0f;
1745 int rshift = (kcontrol->private_value >> 12) & 0x0f;
1746 int mask = (kcontrol->private_value >> 16) & 0xff;
1747 int invert = (kcontrol->private_value >> 24) & 0x01;
1748
1749 ucontrol->value.integer.value[0] =
1750 (snd_soc_read(codec, reg) >> shift) & mask;
1751 if (shift != rshift)
1752 ucontrol->value.integer.value[1] =
1753 (snd_soc_read(codec, reg) >> rshift) & mask;
1754 if (invert) {
1755 ucontrol->value.integer.value[0] =
1756 mask - ucontrol->value.integer.value[0];
1757 if (shift != rshift)
1758 ucontrol->value.integer.value[1] =
1759 mask - ucontrol->value.integer.value[1];
1760 }
1761
1762 return 0;
1763}
1764EXPORT_SYMBOL_GPL(snd_soc_get_volsw);
1765
1766/**
1767 * snd_soc_put_volsw - single mixer put callback
1768 * @kcontrol: mixer control
1769 * @uinfo: control element information
1770 *
1771 * Callback to set the value of a single mixer control.
1772 *
1773 * Returns 0 for success.
1774 */
1775int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
1776 struct snd_ctl_elem_value *ucontrol)
1777{
1778 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1779 int reg = kcontrol->private_value & 0xff;
1780 int shift = (kcontrol->private_value >> 8) & 0x0f;
1781 int rshift = (kcontrol->private_value >> 12) & 0x0f;
1782 int mask = (kcontrol->private_value >> 16) & 0xff;
1783 int invert = (kcontrol->private_value >> 24) & 0x01;
1784 int err;
1785 unsigned short val, val2, val_mask;
1786
1787 val = (ucontrol->value.integer.value[0] & mask);
1788 if (invert)
1789 val = mask - val;
1790 val_mask = mask << shift;
1791 val = val << shift;
1792 if (shift != rshift) {
1793 val2 = (ucontrol->value.integer.value[1] & mask);
1794 if (invert)
1795 val2 = mask - val2;
1796 val_mask |= mask << rshift;
1797 val |= val2 << rshift;
1798 }
1799 err = snd_soc_update_bits(codec, reg, val_mask, val);
1800 return err;
1801}
1802EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
1803
1804/**
1805 * snd_soc_info_volsw_2r - double mixer info callback
1806 * @kcontrol: mixer control
1807 * @uinfo: control element information
1808 *
1809 * Callback to provide information about a double mixer control that
1810 * spans 2 codec registers.
1811 *
1812 * Returns 0 for success.
1813 */
1814int snd_soc_info_volsw_2r(struct snd_kcontrol *kcontrol,
1815 struct snd_ctl_elem_info *uinfo)
1816{
1817 int mask = (kcontrol->private_value >> 12) & 0xff;
1818
1819 uinfo->type =
1820 mask == 1 ? SNDRV_CTL_ELEM_TYPE_BOOLEAN : SNDRV_CTL_ELEM_TYPE_INTEGER;
1821 uinfo->count = 2;
1822 uinfo->value.integer.min = 0;
1823 uinfo->value.integer.max = mask;
1824 return 0;
1825}
1826EXPORT_SYMBOL_GPL(snd_soc_info_volsw_2r);
1827
1828/**
1829 * snd_soc_get_volsw_2r - double mixer get callback
1830 * @kcontrol: mixer control
1831 * @uinfo: control element information
1832 *
1833 * Callback to get the value of a double mixer control that spans 2 registers.
1834 *
1835 * Returns 0 for success.
1836 */
1837int snd_soc_get_volsw_2r(struct snd_kcontrol *kcontrol,
1838 struct snd_ctl_elem_value *ucontrol)
1839{
1840 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1841 int reg = kcontrol->private_value & 0xff;
1842 int reg2 = (kcontrol->private_value >> 24) & 0xff;
1843 int shift = (kcontrol->private_value >> 8) & 0x0f;
1844 int mask = (kcontrol->private_value >> 12) & 0xff;
1845 int invert = (kcontrol->private_value >> 20) & 0x01;
1846
1847 ucontrol->value.integer.value[0] =
1848 (snd_soc_read(codec, reg) >> shift) & mask;
1849 ucontrol->value.integer.value[1] =
1850 (snd_soc_read(codec, reg2) >> shift) & mask;
1851 if (invert) {
1852 ucontrol->value.integer.value[0] =
1853 mask - ucontrol->value.integer.value[0];
1854 ucontrol->value.integer.value[1] =
1855 mask - ucontrol->value.integer.value[1];
1856 }
1857
1858 return 0;
1859}
1860EXPORT_SYMBOL_GPL(snd_soc_get_volsw_2r);
1861
1862/**
1863 * snd_soc_put_volsw_2r - double mixer set callback
1864 * @kcontrol: mixer control
1865 * @uinfo: control element information
1866 *
1867 * Callback to set the value of a double mixer control that spans 2 registers.
1868 *
1869 * Returns 0 for success.
1870 */
1871int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
1872 struct snd_ctl_elem_value *ucontrol)
1873{
1874 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1875 int reg = kcontrol->private_value & 0xff;
1876 int reg2 = (kcontrol->private_value >> 24) & 0xff;
1877 int shift = (kcontrol->private_value >> 8) & 0x0f;
1878 int mask = (kcontrol->private_value >> 12) & 0xff;
1879 int invert = (kcontrol->private_value >> 20) & 0x01;
1880 int err;
1881 unsigned short val, val2, val_mask;
1882
1883 val_mask = mask << shift;
1884 val = (ucontrol->value.integer.value[0] & mask);
1885 val2 = (ucontrol->value.integer.value[1] & mask);
1886
1887 if (invert) {
1888 val = mask - val;
1889 val2 = mask - val2;
1890 }
1891
1892 val = val << shift;
1893 val2 = val2 << shift;
1894
1895 if ((err = snd_soc_update_bits(codec, reg, val_mask, val)) < 0)
1896 return err;
1897
1898 err = snd_soc_update_bits(codec, reg2, val_mask, val2);
1899 return err;
1900}
1901EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);
1902
1903static int __devinit snd_soc_init(void)
1904{
1905 printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION);
1906 return platform_driver_register(&soc_driver);
1907}
1908
1909static void snd_soc_exit(void)
1910{
1911 platform_driver_unregister(&soc_driver);
1912}
1913
1914module_init(snd_soc_init);
1915module_exit(snd_soc_exit);
1916
1917/* Module information */
1918MODULE_AUTHOR("Liam Girdwood, liam.girdwood@wolfsonmicro.com, www.wolfsonmicro.com");
1919MODULE_DESCRIPTION("ALSA SoC Core");
1920MODULE_LICENSE("GPL");