aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-12-21 05:21:15 -0500
committerTakashi Iwai <tiwai@suse.de>2009-12-21 05:21:15 -0500
commitde8853bc38ceab1fa7e7f723b21430d4aad60fea (patch)
tree5084ef51866fd1767324f8dc8eb36e97c55350f5 /sound
parentf5de24b06aa46427500d0fdbe8616b73a71d8c28 (diff)
parent440b004cf953bec2bc8cd91c64ae707fd7e25327 (diff)
Merge remote branch 'alsa/fixes' into fix/hda
Diffstat (limited to 'sound')
-rw-r--r--sound/Kconfig6
-rw-r--r--sound/arm/Makefile2
-rw-r--r--sound/arm/aaci.c39
-rw-r--r--sound/arm/devdma.c80
-rw-r--r--sound/arm/devdma.h3
-rw-r--r--sound/core/control.c9
-rw-r--r--sound/core/hrtimer.c15
-rw-r--r--sound/core/pcm.c6
-rw-r--r--sound/core/pcm_native.c83
-rw-r--r--sound/core/rawmidi.c61
-rw-r--r--sound/drivers/dummy.c2
-rw-r--r--sound/i2c/cs8427.c15
-rw-r--r--sound/i2c/other/tea575x-tuner.c2
-rw-r--r--sound/isa/cs423x/cs4236.c15
-rw-r--r--sound/isa/cs423x/cs4236_lib.c241
-rw-r--r--sound/isa/es18xx.c91
-rw-r--r--sound/isa/opti9xx/miro.c785
-rw-r--r--sound/isa/opti9xx/miro.h73
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c242
-rw-r--r--sound/isa/wss/wss_lib.c11
-rw-r--r--sound/oss/Kconfig2
-rw-r--r--sound/oss/audio.c2
-rw-r--r--sound/oss/dmasound/dmasound_core.c4
-rw-r--r--sound/oss/dmasound/dmasound_paula.c2
-rw-r--r--sound/oss/hex2hex.c2
-rw-r--r--sound/oss/midi_synth.c2
-rw-r--r--sound/oss/mpu401.c2
-rw-r--r--sound/oss/sb_common.c4
-rw-r--r--sound/oss/sb_ess.c2
-rw-r--r--sound/pci/Kconfig1
-rw-r--r--sound/pci/ac97/ac97_codec.c2
-rw-r--r--sound/pci/ca0106/ca0106_proc.c2
-rw-r--r--sound/pci/cs46xx/imgs/cwcdma.asp9
-rw-r--r--sound/pci/emu10k1/emu10k1x.c2
-rw-r--r--sound/pci/fm801.c40
-rw-r--r--sound/pci/hda/patch_cirrus.c2
-rw-r--r--sound/pci/hda/patch_cmedia.c2
-rw-r--r--sound/pci/hda/patch_realtek.c4
-rw-r--r--sound/pci/ice1712/aureon.c31
-rw-r--r--sound/pci/ice1712/ice1712.h4
-rw-r--r--sound/pci/ice1712/juli.c34
-rw-r--r--sound/pci/ice1712/prodigy_hifi.c2
-rw-r--r--sound/pci/intel8x0.c12
-rw-r--r--sound/pci/rme9652/hdspm.c4
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c27
-rw-r--r--sound/pcmcia/vx/vxpocket.c27
-rw-r--r--sound/ppc/Kconfig2
-rw-r--r--sound/sh/aica.c1
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c2
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c2
-rw-r--r--sound/soc/au1x/dbdma2.c115
-rw-r--r--sound/soc/au1x/psc-ac97.c243
-rw-r--r--sound/soc/au1x/psc-i2s.c189
-rw-r--r--sound/soc/au1x/psc.h7
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c7
-rw-r--r--sound/soc/blackfin/bf5xx-ad1938.c9
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c15
-rw-r--r--sound/soc/blackfin/bf5xx-tdm-pcm.c9
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.c45
-rw-r--r--sound/soc/blackfin/bf5xx-tdm.h11
-rw-r--r--sound/soc/codecs/Kconfig25
-rw-r--r--sound/soc/codecs/Makefile12
-rw-r--r--sound/soc/codecs/ac97.c3
-rw-r--r--sound/soc/codecs/ad1836.c12
-rw-r--r--sound/soc/codecs/ad1938.c12
-rw-r--r--sound/soc/codecs/ad1980.c5
-rw-r--r--sound/soc/codecs/ad73311.c8
-rw-r--r--sound/soc/codecs/ads117x.c123
-rw-r--r--sound/soc/codecs/ads117x.h13
-rw-r--r--sound/soc/codecs/ak4104.c8
-rw-r--r--sound/soc/codecs/ak4535.c9
-rw-r--r--sound/soc/codecs/ak4642.c9
-rw-r--r--sound/soc/codecs/ak4671.c815
-rw-r--r--sound/soc/codecs/ak4671.h156
-rw-r--r--sound/soc/codecs/cs4270.c28
-rw-r--r--sound/soc/codecs/cx20442.c12
-rw-r--r--sound/soc/codecs/pcm3008.c9
-rw-r--r--sound/soc/codecs/ssm2602.c9
-rw-r--r--sound/soc/codecs/stac9766.c3
-rw-r--r--sound/soc/codecs/tlv320aic23.c14
-rw-r--r--sound/soc/codecs/tlv320aic26.c11
-rw-r--r--sound/soc/codecs/tlv320aic3x.c11
-rw-r--r--sound/soc/codecs/tlv320dac33.c1229
-rw-r--r--sound/soc/codecs/tlv320dac33.h267
-rw-r--r--sound/soc/codecs/tpa6130a2.c463
-rw-r--r--sound/soc/codecs/tpa6130a2.h61
-rw-r--r--sound/soc/codecs/twl4030.c452
-rw-r--r--sound/soc/codecs/twl4030.h242
-rw-r--r--sound/soc/codecs/uda134x.c13
-rw-r--r--sound/soc/codecs/uda1380.c9
-rw-r--r--sound/soc/codecs/wm8350.c32
-rw-r--r--sound/soc/codecs/wm8400.c32
-rw-r--r--sound/soc/codecs/wm8510.c14
-rw-r--r--sound/soc/codecs/wm8523.c26
-rw-r--r--sound/soc/codecs/wm8580.c30
-rw-r--r--sound/soc/codecs/wm8711.c633
-rw-r--r--sound/soc/codecs/wm8711.h42
-rw-r--r--sound/soc/codecs/wm8727.c135
-rw-r--r--sound/soc/codecs/wm8727.h21
-rw-r--r--sound/soc/codecs/wm8728.c10
-rw-r--r--sound/soc/codecs/wm8731.c94
-rw-r--r--sound/soc/codecs/wm8750.c9
-rw-r--r--sound/soc/codecs/wm8753.c49
-rw-r--r--sound/soc/codecs/wm8776.c43
-rw-r--r--sound/soc/codecs/wm8900.c34
-rw-r--r--sound/soc/codecs/wm8903.c34
-rw-r--r--sound/soc/codecs/wm8940.c28
-rw-r--r--sound/soc/codecs/wm8960.c30
-rw-r--r--sound/soc/codecs/wm8961.c27
-rw-r--r--sound/soc/codecs/wm8971.c11
-rw-r--r--sound/soc/codecs/wm8974.c36
-rw-r--r--sound/soc/codecs/wm8988.c44
-rw-r--r--sound/soc/codecs/wm8990.c14
-rw-r--r--sound/soc/codecs/wm8993.c53
-rw-r--r--sound/soc/codecs/wm9081.c27
-rw-r--r--sound/soc/codecs/wm9705.c7
-rw-r--r--sound/soc/codecs/wm9712.c7
-rw-r--r--sound/soc/codecs/wm9713.c10
-rw-r--r--sound/soc/codecs/wm_hubs.c51
-rw-r--r--sound/soc/codecs/wm_hubs.h5
-rw-r--r--sound/soc/davinci/Kconfig4
-rw-r--r--sound/soc/davinci/davinci-evm.c7
-rw-r--r--sound/soc/davinci/davinci-i2s.c85
-rw-r--r--sound/soc/davinci/davinci-mcasp.c18
-rw-r--r--sound/soc/davinci/davinci-mcasp.h5
-rw-r--r--sound/soc/davinci/davinci-pcm.c571
-rw-r--r--sound/soc/davinci/davinci-pcm.h2
-rw-r--r--sound/soc/fsl/mpc5200_dma.c123
-rw-r--r--sound/soc/fsl/mpc5200_dma.h24
-rw-r--r--sound/soc/fsl/mpc5200_psc_ac97.c39
-rw-r--r--sound/soc/imx/mx1_mx2-pcm.c6
-rw-r--r--sound/soc/imx/mx27vis_wm8974.c2
-rw-r--r--sound/soc/omap/Kconfig36
-rw-r--r--sound/soc/omap/Makefile8
-rw-r--r--sound/soc/omap/am3517evm.c202
-rw-r--r--sound/soc/omap/ams-delta.c8
-rw-r--r--sound/soc/omap/igep0020.c148
-rw-r--r--sound/soc/omap/n810.c2
-rw-r--r--sound/soc/omap/omap-mcbsp.c69
-rw-r--r--sound/soc/omap/omap-pcm.c10
-rw-r--r--sound/soc/omap/omap2evm.c2
-rw-r--r--sound/soc/omap/omap3beagle.c2
-rw-r--r--sound/soc/omap/omap3evm.c11
-rw-r--r--sound/soc/omap/omap3pandora.c27
-rw-r--r--sound/soc/omap/osk5912.c2
-rw-r--r--sound/soc/omap/overo.c6
-rw-r--r--sound/soc/omap/sdp3430.c2
-rw-r--r--sound/soc/omap/zoom2.c2
-rw-r--r--sound/soc/pxa/Kconfig12
-rw-r--r--sound/soc/pxa/Makefile2
-rw-r--r--sound/soc/pxa/magician.c2
-rw-r--r--sound/soc/pxa/pxa-ssp.c20
-rw-r--r--sound/soc/pxa/raumfeld.c335
-rw-r--r--sound/soc/pxa/zylonite.c5
-rw-r--r--sound/soc/s3c24xx/Kconfig12
-rw-r--r--sound/soc/s3c24xx/Makefile6
-rw-r--r--sound/soc/s3c24xx/jive_wm8750.c2
-rw-r--r--sound/soc/s3c24xx/ln2440sbc_alc650.c2
-rw-r--r--sound/soc/s3c24xx/neo1973_gta02_wm8753.c10
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c11
-rw-r--r--sound/soc/s3c24xx/s3c-dma.c (renamed from sound/soc/s3c24xx/s3c24xx-pcm.c)99
-rw-r--r--sound/soc/s3c24xx/s3c-dma.h (renamed from sound/soc/s3c24xx/s3c24xx-pcm.h)8
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.c35
-rw-r--r--sound/soc/s3c24xx/s3c-i2s-v2.h4
-rw-r--r--sound/soc/s3c24xx/s3c-pcm.c552
-rw-r--r--sound/soc/s3c24xx/s3c-pcm.h123
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c7
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c13
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c14
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec.c4
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec_hermes.c2
-rw-r--r--sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c2
-rw-r--r--sound/soc/s3c24xx/s3c24xx_uda134x.c2
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c28
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h1
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c2
-rw-r--r--sound/soc/s3c24xx/smdk64xx_wm8580.c268
-rw-r--r--sound/soc/s6000/s6000-pcm.c6
-rw-r--r--sound/soc/sh/Kconfig1
-rw-r--r--sound/soc/sh/fsi.c271
-rw-r--r--sound/soc/soc-cache.c46
-rw-r--r--sound/soc/soc-core.c577
-rw-r--r--sound/soc/soc-dapm.c157
-rw-r--r--sound/soc/soc-jack.c6
-rw-r--r--sound/soc/soc-utils.c74
-rw-r--r--sound/sound_core.c2
-rw-r--r--sound/synth/emux/soundfont.c2
-rw-r--r--sound/usb/usbaudio.c38
-rw-r--r--sound/usb/usbaudio.h9
-rw-r--r--sound/usb/usbmidi.c208
-rw-r--r--sound/usb/usbmixer.c9
-rw-r--r--sound/usb/usbmixer_maps.c23
-rw-r--r--sound/usb/usbquirks.h23
-rw-r--r--sound/usb/usx2y/us122l.c108
-rw-r--r--sound/usb/usx2y/us122l.h6
-rw-r--r--sound/usb/usx2y/usX2Yhwdep.c8
-rw-r--r--sound/usb/usx2y/usbusx2y.c28
-rw-r--r--sound/usb/usx2y/usbusx2y.h6
-rw-r--r--sound/usb/usx2y/usbusx2yaudio.c34
-rw-r--r--sound/usb/usx2y/usx2yhwdeppcm.c8
201 files changed, 9545 insertions, 3409 deletions
diff --git a/sound/Kconfig b/sound/Kconfig
index 439e15c8faa3..fcad760f5691 100644
--- a/sound/Kconfig
+++ b/sound/Kconfig
@@ -1,6 +1,3 @@
1# sound/Config.in
2#
3
4menuconfig SOUND 1menuconfig SOUND
5 tristate "Sound card support" 2 tristate "Sound card support"
6 depends on HAS_IOMEM 3 depends on HAS_IOMEM
@@ -58,7 +55,7 @@ config SOUND_OSS_CORE_PRECLAIM
58 Please read Documentation/feature-removal-schedule.txt for 55 Please read Documentation/feature-removal-schedule.txt for
59 details. 56 details.
60 57
61 If unusre, say Y. 58 If unsure, say Y.
62 59
63source "sound/oss/dmasound/Kconfig" 60source "sound/oss/dmasound/Kconfig"
64 61
@@ -136,4 +133,3 @@ config AC97_BUS
136 sound subsystem and other function drivers completely unrelated to 133 sound subsystem and other function drivers completely unrelated to
137 sound although they're sharing the AC97 bus. Concerned drivers 134 sound although they're sharing the AC97 bus. Concerned drivers
138 should "select" this. 135 should "select" this.
139
diff --git a/sound/arm/Makefile b/sound/arm/Makefile
index 5a549ed6c8aa..8c0c851d4641 100644
--- a/sound/arm/Makefile
+++ b/sound/arm/Makefile
@@ -3,7 +3,7 @@
3# 3#
4 4
5obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o 5obj-$(CONFIG_SND_ARMAACI) += snd-aaci.o
6snd-aaci-objs := aaci.o devdma.o 6snd-aaci-objs := aaci.o
7 7
8obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o 8obj-$(CONFIG_SND_PXA2XX_PCM) += snd-pxa2xx-pcm.o
9snd-pxa2xx-pcm-objs := pxa2xx-pcm.o 9snd-pxa2xx-pcm-objs := pxa2xx-pcm.o
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 1f0f8213e2d5..1497dce1b04a 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -18,10 +18,7 @@
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/err.h> 19#include <linux/err.h>
20#include <linux/amba/bus.h> 20#include <linux/amba/bus.h>
21 21#include <linux/io.h>
22#include <asm/io.h>
23#include <asm/irq.h>
24#include <asm/sizes.h>
25 22
26#include <sound/core.h> 23#include <sound/core.h>
27#include <sound/initval.h> 24#include <sound/initval.h>
@@ -30,7 +27,6 @@
30#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
31 28
32#include "aaci.h" 29#include "aaci.h"
33#include "devdma.h"
34 30
35#define DRIVER_NAME "aaci-pl041" 31#define DRIVER_NAME "aaci-pl041"
36 32
@@ -492,7 +488,7 @@ static int aaci_pcm_hw_free(struct snd_pcm_substream *substream)
492 /* 488 /*
493 * Clear out the DMA and any allocated buffers. 489 * Clear out the DMA and any allocated buffers.
494 */ 490 */
495 devdma_hw_free(NULL, substream); 491 snd_pcm_lib_free_pages(substream);
496 492
497 return 0; 493 return 0;
498} 494}
@@ -504,21 +500,19 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
504 int err; 500 int err;
505 501
506 aaci_pcm_hw_free(substream); 502 aaci_pcm_hw_free(substream);
503 if (aacirun->pcm_open) {
504 snd_ac97_pcm_close(aacirun->pcm);
505 aacirun->pcm_open = 0;
506 }
507 507
508 err = devdma_hw_alloc(NULL, substream, 508 err = snd_pcm_lib_malloc_pages(substream,
509 params_buffer_bytes(params)); 509 params_buffer_bytes(params));
510 if (err < 0) 510 if (err < 0)
511 goto out; 511 goto out;
512 512
513 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 513 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
514 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), 514 params_channels(params),
515 params_channels(params), 515 aacirun->pcm->r[0].slots);
516 aacirun->pcm->r[0].slots);
517 else
518 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
519 params_channels(params),
520 aacirun->pcm->r[1].slots);
521
522 if (err) 516 if (err)
523 goto out; 517 goto out;
524 518
@@ -534,7 +528,7 @@ static int aaci_pcm_prepare(struct snd_pcm_substream *substream)
534 struct aaci_runtime *aacirun = runtime->private_data; 528 struct aaci_runtime *aacirun = runtime->private_data;
535 529
536 aacirun->start = (void *)runtime->dma_area; 530 aacirun->start = (void *)runtime->dma_area;
537 aacirun->end = aacirun->start + runtime->dma_bytes; 531 aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream);
538 aacirun->ptr = aacirun->start; 532 aacirun->ptr = aacirun->start;
539 aacirun->period = 533 aacirun->period =
540 aacirun->bytes = frames_to_bytes(runtime, runtime->period_size); 534 aacirun->bytes = frames_to_bytes(runtime, runtime->period_size);
@@ -551,11 +545,6 @@ static snd_pcm_uframes_t aaci_pcm_pointer(struct snd_pcm_substream *substream)
551 return bytes_to_frames(runtime, bytes); 545 return bytes_to_frames(runtime, bytes);
552} 546}
553 547
554static int aaci_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma)
555{
556 return devdma_mmap(NULL, substream, vma);
557}
558
559 548
560/* 549/*
561 * Playback specific ALSA stuff 550 * Playback specific ALSA stuff
@@ -722,7 +711,6 @@ static struct snd_pcm_ops aaci_playback_ops = {
722 .prepare = aaci_pcm_prepare, 711 .prepare = aaci_pcm_prepare,
723 .trigger = aaci_pcm_playback_trigger, 712 .trigger = aaci_pcm_playback_trigger,
724 .pointer = aaci_pcm_pointer, 713 .pointer = aaci_pcm_pointer,
725 .mmap = aaci_pcm_mmap,
726}; 714};
727 715
728static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream, 716static int aaci_pcm_capture_hw_params(struct snd_pcm_substream *substream,
@@ -850,7 +838,6 @@ static struct snd_pcm_ops aaci_capture_ops = {
850 .prepare = aaci_pcm_capture_prepare, 838 .prepare = aaci_pcm_capture_prepare,
851 .trigger = aaci_pcm_capture_trigger, 839 .trigger = aaci_pcm_capture_trigger,
852 .pointer = aaci_pcm_pointer, 840 .pointer = aaci_pcm_pointer,
853 .mmap = aaci_pcm_mmap,
854}; 841};
855 842
856/* 843/*
@@ -1040,6 +1027,8 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
1040 1027
1041 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); 1028 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
1042 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops); 1029 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
1030 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1031 NULL, 0, 64 * 104);
1043 } 1032 }
1044 1033
1045 return ret; 1034 return ret;
diff --git a/sound/arm/devdma.c b/sound/arm/devdma.c
deleted file mode 100644
index 9d1e6665b546..000000000000
--- a/sound/arm/devdma.c
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 * linux/sound/arm/devdma.c
3 *
4 * Copyright (C) 2003-2004 Russell King, All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * ARM DMA shim for ALSA.
11 */
12#include <linux/device.h>
13#include <linux/dma-mapping.h>
14
15#include <sound/core.h>
16#include <sound/pcm.h>
17
18#include "devdma.h"
19
20void devdma_hw_free(struct device *dev, struct snd_pcm_substream *substream)
21{
22 struct snd_pcm_runtime *runtime = substream->runtime;
23 struct snd_dma_buffer *buf = runtime->dma_buffer_p;
24
25 if (runtime->dma_area == NULL)
26 return;
27
28 if (buf != &substream->dma_buffer) {
29 dma_free_coherent(buf->dev.dev, buf->bytes, buf->area, buf->addr);
30 kfree(runtime->dma_buffer_p);
31 }
32
33 snd_pcm_set_runtime_buffer(substream, NULL);
34}
35
36int devdma_hw_alloc(struct device *dev, struct snd_pcm_substream *substream, size_t size)
37{
38 struct snd_pcm_runtime *runtime = substream->runtime;
39 struct snd_dma_buffer *buf = runtime->dma_buffer_p;
40 int ret = 0;
41
42 if (buf) {
43 if (buf->bytes >= size)
44 goto out;
45 devdma_hw_free(dev, substream);
46 }
47
48 if (substream->dma_buffer.area != NULL && substream->dma_buffer.bytes >= size) {
49 buf = &substream->dma_buffer;
50 } else {
51 buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
52 if (!buf)
53 goto nomem;
54
55 buf->dev.type = SNDRV_DMA_TYPE_DEV;
56 buf->dev.dev = dev;
57 buf->area = dma_alloc_coherent(dev, size, &buf->addr, GFP_KERNEL);
58 buf->bytes = size;
59 buf->private_data = NULL;
60
61 if (!buf->area)
62 goto free;
63 }
64 snd_pcm_set_runtime_buffer(substream, buf);
65 ret = 1;
66 out:
67 runtime->dma_bytes = size;
68 return ret;
69
70 free:
71 kfree(buf);
72 nomem:
73 return -ENOMEM;
74}
75
76int devdma_mmap(struct device *dev, struct snd_pcm_substream *substream, struct vm_area_struct *vma)
77{
78 struct snd_pcm_runtime *runtime = substream->runtime;
79 return dma_mmap_coherent(dev, vma, runtime->dma_area, runtime->dma_addr, runtime->dma_bytes);
80}
diff --git a/sound/arm/devdma.h b/sound/arm/devdma.h
deleted file mode 100644
index d025329c8a0f..000000000000
--- a/sound/arm/devdma.h
+++ /dev/null
@@ -1,3 +0,0 @@
1void devdma_hw_free(struct device *dev, struct snd_pcm_substream *substream);
2int devdma_hw_alloc(struct device *dev, struct snd_pcm_substream *substream, size_t size);
3int devdma_mmap(struct device *dev, struct snd_pcm_substream *substream, struct vm_area_struct *vma);
diff --git a/sound/core/control.c b/sound/core/control.c
index a8b7fabe645e..268ab7471224 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -75,7 +75,7 @@ static int snd_ctl_open(struct inode *inode, struct file *file)
75 ctl->card = card; 75 ctl->card = card;
76 ctl->prefer_pcm_subdevice = -1; 76 ctl->prefer_pcm_subdevice = -1;
77 ctl->prefer_rawmidi_subdevice = -1; 77 ctl->prefer_rawmidi_subdevice = -1;
78 ctl->pid = current->pid; 78 ctl->pid = get_pid(task_pid(current));
79 file->private_data = ctl; 79 file->private_data = ctl;
80 write_lock_irqsave(&card->ctl_files_rwlock, flags); 80 write_lock_irqsave(&card->ctl_files_rwlock, flags);
81 list_add_tail(&ctl->list, &card->ctl_files); 81 list_add_tail(&ctl->list, &card->ctl_files);
@@ -125,6 +125,7 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
125 control->vd[idx].owner = NULL; 125 control->vd[idx].owner = NULL;
126 up_write(&card->controls_rwsem); 126 up_write(&card->controls_rwsem);
127 snd_ctl_empty_read_queue(ctl); 127 snd_ctl_empty_read_queue(ctl);
128 put_pid(ctl->pid);
128 kfree(ctl); 129 kfree(ctl);
129 module_put(card->module); 130 module_put(card->module);
130 snd_card_file_remove(card, file); 131 snd_card_file_remove(card, file);
@@ -672,7 +673,7 @@ static int snd_ctl_elem_info(struct snd_ctl_file *ctl,
672 info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK; 673 info->access |= SNDRV_CTL_ELEM_ACCESS_LOCK;
673 if (vd->owner == ctl) 674 if (vd->owner == ctl)
674 info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER; 675 info->access |= SNDRV_CTL_ELEM_ACCESS_OWNER;
675 info->owner = vd->owner_pid; 676 info->owner = pid_vnr(vd->owner->pid);
676 } else { 677 } else {
677 info->owner = -1; 678 info->owner = -1;
678 } 679 }
@@ -827,7 +828,6 @@ static int snd_ctl_elem_lock(struct snd_ctl_file *file,
827 result = -EBUSY; 828 result = -EBUSY;
828 else { 829 else {
829 vd->owner = file; 830 vd->owner = file;
830 vd->owner_pid = current->pid;
831 result = 0; 831 result = 0;
832 } 832 }
833 } 833 }
@@ -858,7 +858,6 @@ static int snd_ctl_elem_unlock(struct snd_ctl_file *file,
858 result = -EPERM; 858 result = -EPERM;
859 else { 859 else {
860 vd->owner = NULL; 860 vd->owner = NULL;
861 vd->owner_pid = 0;
862 result = 0; 861 result = 0;
863 } 862 }
864 } 863 }
@@ -1120,7 +1119,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
1120 goto __kctl_end; 1119 goto __kctl_end;
1121 } 1120 }
1122 if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) { 1121 if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
1123 if (file && vd->owner != NULL && vd->owner != file) { 1122 if (vd->owner != NULL && vd->owner != file) {
1124 err = -EPERM; 1123 err = -EPERM;
1125 goto __kctl_end; 1124 goto __kctl_end;
1126 } 1125 }
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
index 34c7d48f5061..7f4d744ae40a 100644
--- a/sound/core/hrtimer.c
+++ b/sound/core/hrtimer.c
@@ -37,14 +37,22 @@ static unsigned int resolution;
37struct snd_hrtimer { 37struct snd_hrtimer {
38 struct snd_timer *timer; 38 struct snd_timer *timer;
39 struct hrtimer hrt; 39 struct hrtimer hrt;
40 atomic_t running;
40}; 41};
41 42
42static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) 43static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
43{ 44{
44 struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt); 45 struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
45 struct snd_timer *t = stime->timer; 46 struct snd_timer *t = stime->timer;
47
48 if (!atomic_read(&stime->running))
49 return HRTIMER_NORESTART;
50
46 hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution)); 51 hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
47 snd_timer_interrupt(stime->timer, t->sticks); 52 snd_timer_interrupt(stime->timer, t->sticks);
53
54 if (!atomic_read(&stime->running))
55 return HRTIMER_NORESTART;
48 return HRTIMER_RESTART; 56 return HRTIMER_RESTART;
49} 57}
50 58
@@ -58,6 +66,7 @@ static int snd_hrtimer_open(struct snd_timer *t)
58 hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 66 hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
59 stime->timer = t; 67 stime->timer = t;
60 stime->hrt.function = snd_hrtimer_callback; 68 stime->hrt.function = snd_hrtimer_callback;
69 atomic_set(&stime->running, 0);
61 t->private_data = stime; 70 t->private_data = stime;
62 return 0; 71 return 0;
63} 72}
@@ -78,16 +87,18 @@ static int snd_hrtimer_start(struct snd_timer *t)
78{ 87{
79 struct snd_hrtimer *stime = t->private_data; 88 struct snd_hrtimer *stime = t->private_data;
80 89
90 atomic_set(&stime->running, 0);
91 hrtimer_cancel(&stime->hrt);
81 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution), 92 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
82 HRTIMER_MODE_REL); 93 HRTIMER_MODE_REL);
94 atomic_set(&stime->running, 1);
83 return 0; 95 return 0;
84} 96}
85 97
86static int snd_hrtimer_stop(struct snd_timer *t) 98static int snd_hrtimer_stop(struct snd_timer *t)
87{ 99{
88 struct snd_hrtimer *stime = t->private_data; 100 struct snd_hrtimer *stime = t->private_data;
89 101 atomic_set(&stime->running, 0);
90 hrtimer_cancel(&stime->hrt);
91 return 0; 102 return 0;
92} 103}
93 104
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index c69c60b2a48a..6884ae031f6f 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -435,6 +435,7 @@ static void snd_pcm_substream_proc_status_read(struct snd_info_entry *entry,
435 return; 435 return;
436 } 436 }
437 snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state)); 437 snd_iprintf(buffer, "state: %s\n", snd_pcm_state_name(status.state));
438 snd_iprintf(buffer, "owner_pid : %d\n", pid_vnr(substream->pid));
438 snd_iprintf(buffer, "trigger_time: %ld.%09ld\n", 439 snd_iprintf(buffer, "trigger_time: %ld.%09ld\n",
439 status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec); 440 status.trigger_tstamp.tv_sec, status.trigger_tstamp.tv_nsec);
440 snd_iprintf(buffer, "tstamp : %ld.%09ld\n", 441 snd_iprintf(buffer, "tstamp : %ld.%09ld\n",
@@ -809,7 +810,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
809 card = pcm->card; 810 card = pcm->card;
810 read_lock(&card->ctl_files_rwlock); 811 read_lock(&card->ctl_files_rwlock);
811 list_for_each_entry(kctl, &card->ctl_files, list) { 812 list_for_each_entry(kctl, &card->ctl_files, list) {
812 if (kctl->pid == current->pid) { 813 if (kctl->pid == task_pid(current)) {
813 prefer_subdevice = kctl->prefer_pcm_subdevice; 814 prefer_subdevice = kctl->prefer_pcm_subdevice;
814 if (prefer_subdevice != -1) 815 if (prefer_subdevice != -1)
815 break; 816 break;
@@ -900,6 +901,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
900 substream->private_data = pcm->private_data; 901 substream->private_data = pcm->private_data;
901 substream->ref_count = 1; 902 substream->ref_count = 1;
902 substream->f_flags = file->f_flags; 903 substream->f_flags = file->f_flags;
904 substream->pid = get_pid(task_pid(current));
903 pstr->substream_opened++; 905 pstr->substream_opened++;
904 *rsubstream = substream; 906 *rsubstream = substream;
905 return 0; 907 return 0;
@@ -921,6 +923,8 @@ void snd_pcm_detach_substream(struct snd_pcm_substream *substream)
921 kfree(runtime->hw_constraints.rules); 923 kfree(runtime->hw_constraints.rules);
922 kfree(runtime); 924 kfree(runtime);
923 substream->runtime = NULL; 925 substream->runtime = NULL;
926 put_pid(substream->pid);
927 substream->pid = NULL;
924 substream->pstr->substream_opened--; 928 substream->pstr->substream_opened--;
925} 929}
926 930
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index ab73edf2c89a..29ab46a12e11 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -26,6 +26,7 @@
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/pm_qos_params.h> 27#include <linux/pm_qos_params.h>
28#include <linux/uio.h> 28#include <linux/uio.h>
29#include <linux/dma-mapping.h>
29#include <sound/core.h> 30#include <sound/core.h>
30#include <sound/control.h> 31#include <sound/control.h>
31#include <sound/info.h> 32#include <sound/info.h>
@@ -3061,6 +3062,27 @@ static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file
3061} 3062}
3062#endif /* coherent mmap */ 3063#endif /* coherent mmap */
3063 3064
3065static inline struct page *
3066snd_pcm_default_page_ops(struct snd_pcm_substream *substream, unsigned long ofs)
3067{
3068 void *vaddr = substream->runtime->dma_area + ofs;
3069#if defined(CONFIG_MIPS) && defined(CONFIG_DMA_NONCOHERENT)
3070 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3071 return virt_to_page(CAC_ADDR(vaddr));
3072#endif
3073#if defined(CONFIG_PPC32) && defined(CONFIG_NOT_COHERENT_CACHE)
3074 if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV) {
3075 dma_addr_t addr = substream->runtime->dma_addr + ofs;
3076 addr -= get_dma_offset(substream->dma_buffer.dev.dev);
3077 /* assume dma_handle set via pfn_to_phys() in
3078 * mm/dma-noncoherent.c
3079 */
3080 return pfn_to_page(addr >> PAGE_SHIFT);
3081 }
3082#endif
3083 return virt_to_page(vaddr);
3084}
3085
3064/* 3086/*
3065 * fault callback for mmapping a RAM page 3087 * fault callback for mmapping a RAM page
3066 */ 3088 */
@@ -3071,7 +3093,6 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
3071 struct snd_pcm_runtime *runtime; 3093 struct snd_pcm_runtime *runtime;
3072 unsigned long offset; 3094 unsigned long offset;
3073 struct page * page; 3095 struct page * page;
3074 void *vaddr;
3075 size_t dma_bytes; 3096 size_t dma_bytes;
3076 3097
3077 if (substream == NULL) 3098 if (substream == NULL)
@@ -3081,36 +3102,53 @@ static int snd_pcm_mmap_data_fault(struct vm_area_struct *area,
3081 dma_bytes = PAGE_ALIGN(runtime->dma_bytes); 3102 dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
3082 if (offset > dma_bytes - PAGE_SIZE) 3103 if (offset > dma_bytes - PAGE_SIZE)
3083 return VM_FAULT_SIGBUS; 3104 return VM_FAULT_SIGBUS;
3084 if (substream->ops->page) { 3105 if (substream->ops->page)
3085 page = substream->ops->page(substream, offset); 3106 page = substream->ops->page(substream, offset);
3086 if (!page) 3107 else
3087 return VM_FAULT_SIGBUS; 3108 page = snd_pcm_default_page_ops(substream, offset);
3088 } else { 3109 if (!page)
3089 vaddr = runtime->dma_area + offset; 3110 return VM_FAULT_SIGBUS;
3090 page = virt_to_page(vaddr);
3091 }
3092 get_page(page); 3111 get_page(page);
3093 vmf->page = page; 3112 vmf->page = page;
3094 return 0; 3113 return 0;
3095} 3114}
3096 3115
3097static const struct vm_operations_struct snd_pcm_vm_ops_data = 3116static const struct vm_operations_struct snd_pcm_vm_ops_data = {
3098{ 3117 .open = snd_pcm_mmap_data_open,
3118 .close = snd_pcm_mmap_data_close,
3119};
3120
3121static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
3099 .open = snd_pcm_mmap_data_open, 3122 .open = snd_pcm_mmap_data_open,
3100 .close = snd_pcm_mmap_data_close, 3123 .close = snd_pcm_mmap_data_close,
3101 .fault = snd_pcm_mmap_data_fault, 3124 .fault = snd_pcm_mmap_data_fault,
3102}; 3125};
3103 3126
3127#ifndef ARCH_HAS_DMA_MMAP_COHERENT
3128/* This should be defined / handled globally! */
3129#ifdef CONFIG_ARM
3130#define ARCH_HAS_DMA_MMAP_COHERENT
3131#endif
3132#endif
3133
3104/* 3134/*
3105 * mmap the DMA buffer on RAM 3135 * mmap the DMA buffer on RAM
3106 */ 3136 */
3107static int snd_pcm_default_mmap(struct snd_pcm_substream *substream, 3137static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3108 struct vm_area_struct *area) 3138 struct vm_area_struct *area)
3109{ 3139{
3110 area->vm_ops = &snd_pcm_vm_ops_data;
3111 area->vm_private_data = substream;
3112 area->vm_flags |= VM_RESERVED; 3140 area->vm_flags |= VM_RESERVED;
3113 atomic_inc(&substream->mmap_count); 3141#ifdef ARCH_HAS_DMA_MMAP_COHERENT
3142 if (!substream->ops->page &&
3143 substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV)
3144 return dma_mmap_coherent(substream->dma_buffer.dev.dev,
3145 area,
3146 substream->runtime->dma_area,
3147 substream->runtime->dma_addr,
3148 area->vm_end - area->vm_start);
3149#endif /* ARCH_HAS_DMA_MMAP_COHERENT */
3150 /* mmap with fault handler */
3151 area->vm_ops = &snd_pcm_vm_ops_data_fault;
3114 return 0; 3152 return 0;
3115} 3153}
3116 3154
@@ -3118,12 +3156,6 @@ static int snd_pcm_default_mmap(struct snd_pcm_substream *substream,
3118 * mmap the DMA buffer on I/O memory area 3156 * mmap the DMA buffer on I/O memory area
3119 */ 3157 */
3120#if SNDRV_PCM_INFO_MMAP_IOMEM 3158#if SNDRV_PCM_INFO_MMAP_IOMEM
3121static const struct vm_operations_struct snd_pcm_vm_ops_data_mmio =
3122{
3123 .open = snd_pcm_mmap_data_open,
3124 .close = snd_pcm_mmap_data_close,
3125};
3126
3127int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, 3159int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3128 struct vm_area_struct *area) 3160 struct vm_area_struct *area)
3129{ 3161{
@@ -3133,8 +3165,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3133#ifdef pgprot_noncached 3165#ifdef pgprot_noncached
3134 area->vm_page_prot = pgprot_noncached(area->vm_page_prot); 3166 area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
3135#endif 3167#endif
3136 area->vm_ops = &snd_pcm_vm_ops_data_mmio;
3137 area->vm_private_data = substream;
3138 area->vm_flags |= VM_IO; 3168 area->vm_flags |= VM_IO;
3139 size = area->vm_end - area->vm_start; 3169 size = area->vm_end - area->vm_start;
3140 offset = area->vm_pgoff << PAGE_SHIFT; 3170 offset = area->vm_pgoff << PAGE_SHIFT;
@@ -3142,7 +3172,6 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
3142 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT, 3172 (substream->runtime->dma_addr + offset) >> PAGE_SHIFT,
3143 size, area->vm_page_prot)) 3173 size, area->vm_page_prot))
3144 return -EAGAIN; 3174 return -EAGAIN;
3145 atomic_inc(&substream->mmap_count);
3146 return 0; 3175 return 0;
3147} 3176}
3148 3177
@@ -3159,6 +3188,7 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3159 long size; 3188 long size;
3160 unsigned long offset; 3189 unsigned long offset;
3161 size_t dma_bytes; 3190 size_t dma_bytes;
3191 int err;
3162 3192
3163 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 3193 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
3164 if (!(area->vm_flags & (VM_WRITE|VM_READ))) 3194 if (!(area->vm_flags & (VM_WRITE|VM_READ)))
@@ -3183,10 +3213,15 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
3183 if (offset > dma_bytes - size) 3213 if (offset > dma_bytes - size)
3184 return -EINVAL; 3214 return -EINVAL;
3185 3215
3216 area->vm_ops = &snd_pcm_vm_ops_data;
3217 area->vm_private_data = substream;
3186 if (substream->ops->mmap) 3218 if (substream->ops->mmap)
3187 return substream->ops->mmap(substream, area); 3219 err = substream->ops->mmap(substream, area);
3188 else 3220 else
3189 return snd_pcm_default_mmap(substream, area); 3221 err = snd_pcm_default_mmap(substream, area);
3222 if (!err)
3223 atomic_inc(&substream->mmap_count);
3224 return err;
3190} 3225}
3191 3226
3192EXPORT_SYMBOL(snd_pcm_mmap_data); 3227EXPORT_SYMBOL(snd_pcm_mmap_data);
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index c0adc14c91f0..0f5a194695d9 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -242,13 +242,12 @@ static int assign_substream(struct snd_rawmidi *rmidi, int subdevice,
242 return -ENXIO; 242 return -ENXIO;
243 if (subdevice >= 0 && subdevice >= s->substream_count) 243 if (subdevice >= 0 && subdevice >= s->substream_count)
244 return -ENODEV; 244 return -ENODEV;
245 if (s->substream_opened >= s->substream_count)
246 return -EAGAIN;
247 245
248 list_for_each_entry(substream, &s->substreams, list) { 246 list_for_each_entry(substream, &s->substreams, list) {
249 if (substream->opened) { 247 if (substream->opened) {
250 if (stream == SNDRV_RAWMIDI_STREAM_INPUT || 248 if (stream == SNDRV_RAWMIDI_STREAM_INPUT ||
251 !(mode & SNDRV_RAWMIDI_LFLG_APPEND)) 249 !(mode & SNDRV_RAWMIDI_LFLG_APPEND) ||
250 !substream->append)
252 continue; 251 continue;
253 } 252 }
254 if (subdevice < 0 || subdevice == substream->number) { 253 if (subdevice < 0 || subdevice == substream->number) {
@@ -266,18 +265,23 @@ static int open_substream(struct snd_rawmidi *rmidi,
266{ 265{
267 int err; 266 int err;
268 267
269 err = snd_rawmidi_runtime_create(substream); 268 if (substream->use_count == 0) {
270 if (err < 0) 269 err = snd_rawmidi_runtime_create(substream);
271 return err; 270 if (err < 0)
272 err = substream->ops->open(substream); 271 return err;
273 if (err < 0) 272 err = substream->ops->open(substream);
274 return err; 273 if (err < 0) {
275 substream->opened = 1; 274 snd_rawmidi_runtime_free(substream);
276 if (substream->use_count++ == 0) 275 return err;
276 }
277 substream->opened = 1;
277 substream->active_sensing = 0; 278 substream->active_sensing = 0;
278 if (mode & SNDRV_RAWMIDI_LFLG_APPEND) 279 if (mode & SNDRV_RAWMIDI_LFLG_APPEND)
279 substream->append = 1; 280 substream->append = 1;
280 rmidi->streams[substream->stream].substream_opened++; 281 substream->pid = get_pid(task_pid(current));
282 rmidi->streams[substream->stream].substream_opened++;
283 }
284 substream->use_count++;
281 return 0; 285 return 0;
282} 286}
283 287
@@ -297,27 +301,27 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
297 SNDRV_RAWMIDI_STREAM_INPUT, 301 SNDRV_RAWMIDI_STREAM_INPUT,
298 mode, &sinput); 302 mode, &sinput);
299 if (err < 0) 303 if (err < 0)
300 goto __error; 304 return err;
301 } 305 }
302 if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) { 306 if (mode & SNDRV_RAWMIDI_LFLG_OUTPUT) {
303 err = assign_substream(rmidi, subdevice, 307 err = assign_substream(rmidi, subdevice,
304 SNDRV_RAWMIDI_STREAM_OUTPUT, 308 SNDRV_RAWMIDI_STREAM_OUTPUT,
305 mode, &soutput); 309 mode, &soutput);
306 if (err < 0) 310 if (err < 0)
307 goto __error; 311 return err;
308 } 312 }
309 313
310 if (sinput) { 314 if (sinput) {
311 err = open_substream(rmidi, sinput, mode); 315 err = open_substream(rmidi, sinput, mode);
312 if (err < 0) 316 if (err < 0)
313 goto __error; 317 return err;
314 } 318 }
315 if (soutput) { 319 if (soutput) {
316 err = open_substream(rmidi, soutput, mode); 320 err = open_substream(rmidi, soutput, mode);
317 if (err < 0) { 321 if (err < 0) {
318 if (sinput) 322 if (sinput)
319 close_substream(rmidi, sinput, 0); 323 close_substream(rmidi, sinput, 0);
320 goto __error; 324 return err;
321 } 325 }
322 } 326 }
323 327
@@ -325,13 +329,6 @@ static int rawmidi_open_priv(struct snd_rawmidi *rmidi, int subdevice, int mode,
325 rfile->input = sinput; 329 rfile->input = sinput;
326 rfile->output = soutput; 330 rfile->output = soutput;
327 return 0; 331 return 0;
328
329 __error:
330 if (sinput && sinput->runtime)
331 snd_rawmidi_runtime_free(sinput);
332 if (soutput && soutput->runtime)
333 snd_rawmidi_runtime_free(soutput);
334 return err;
335} 332}
336 333
337/* called from sound/core/seq/seq_midi.c */ 334/* called from sound/core/seq/seq_midi.c */
@@ -415,7 +412,7 @@ static int snd_rawmidi_open(struct inode *inode, struct file *file)
415 subdevice = -1; 412 subdevice = -1;
416 read_lock(&card->ctl_files_rwlock); 413 read_lock(&card->ctl_files_rwlock);
417 list_for_each_entry(kctl, &card->ctl_files, list) { 414 list_for_each_entry(kctl, &card->ctl_files, list) {
418 if (kctl->pid == current->pid) { 415 if (kctl->pid == task_pid(current)) {
419 subdevice = kctl->prefer_rawmidi_subdevice; 416 subdevice = kctl->prefer_rawmidi_subdevice;
420 if (subdevice != -1) 417 if (subdevice != -1)
421 break; 418 break;
@@ -468,7 +465,6 @@ static void close_substream(struct snd_rawmidi *rmidi,
468 struct snd_rawmidi_substream *substream, 465 struct snd_rawmidi_substream *substream,
469 int cleanup) 466 int cleanup)
470{ 467{
471 rmidi->streams[substream->stream].substream_opened--;
472 if (--substream->use_count) 468 if (--substream->use_count)
473 return; 469 return;
474 470
@@ -493,6 +489,9 @@ static void close_substream(struct snd_rawmidi *rmidi,
493 snd_rawmidi_runtime_free(substream); 489 snd_rawmidi_runtime_free(substream);
494 substream->opened = 0; 490 substream->opened = 0;
495 substream->append = 0; 491 substream->append = 0;
492 put_pid(substream->pid);
493 substream->pid = NULL;
494 rmidi->streams[substream->stream].substream_opened--;
496} 495}
497 496
498static void rawmidi_release_priv(struct snd_rawmidi_file *rfile) 497static void rawmidi_release_priv(struct snd_rawmidi_file *rfile)
@@ -1258,7 +1257,7 @@ static ssize_t snd_rawmidi_write(struct file *file, const char __user *buf,
1258 break; 1257 break;
1259 count -= count1; 1258 count -= count1;
1260 } 1259 }
1261 if (file->f_flags & O_SYNC) { 1260 if (file->f_flags & O_DSYNC) {
1262 spin_lock_irq(&runtime->lock); 1261 spin_lock_irq(&runtime->lock);
1263 while (runtime->avail != runtime->buffer_size) { 1262 while (runtime->avail != runtime->buffer_size) {
1264 wait_queue_t wait; 1263 wait_queue_t wait;
@@ -1340,6 +1339,9 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
1340 substream->number, 1339 substream->number,
1341 (unsigned long) substream->bytes); 1340 (unsigned long) substream->bytes);
1342 if (substream->opened) { 1341 if (substream->opened) {
1342 snd_iprintf(buffer,
1343 " Owner PID : %d\n",
1344 pid_vnr(substream->pid));
1343 runtime = substream->runtime; 1345 runtime = substream->runtime;
1344 snd_iprintf(buffer, 1346 snd_iprintf(buffer,
1345 " Mode : %s\n" 1347 " Mode : %s\n"
@@ -1361,6 +1363,9 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
1361 substream->number, 1363 substream->number,
1362 (unsigned long) substream->bytes); 1364 (unsigned long) substream->bytes);
1363 if (substream->opened) { 1365 if (substream->opened) {
1366 snd_iprintf(buffer,
1367 " Owner PID : %d\n",
1368 pid_vnr(substream->pid));
1364 runtime = substream->runtime; 1369 runtime = substream->runtime;
1365 snd_iprintf(buffer, 1370 snd_iprintf(buffer,
1366 " Buffer size : %lu\n" 1371 " Buffer size : %lu\n"
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 146ef00f94a3..252e04ce602f 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -165,7 +165,7 @@ MODULE_PARM_DESC(enable, "Enable this dummy soundcard.");
165module_param_array(pcm_devs, int, NULL, 0444); 165module_param_array(pcm_devs, int, NULL, 0444);
166MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver."); 166MODULE_PARM_DESC(pcm_devs, "PCM devices # (0-4) for dummy driver.");
167module_param_array(pcm_substreams, int, NULL, 0444); 167module_param_array(pcm_substreams, int, NULL, 0444);
168MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-16) for dummy driver."); 168MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
169//module_param_array(midi_devs, int, NULL, 0444); 169//module_param_array(midi_devs, int, NULL, 0444);
170//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver."); 170//MODULE_PARM_DESC(midi_devs, "MIDI devices # (0-2) for dummy driver.");
171module_param(fake_buffer, bool, 0444); 171module_param(fake_buffer, bool, 0444);
diff --git a/sound/i2c/cs8427.c b/sound/i2c/cs8427.c
index 020a5d512472..04ae8704cdcd 100644
--- a/sound/i2c/cs8427.c
+++ b/sound/i2c/cs8427.c
@@ -23,6 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/bitrev.h>
26#include <asm/unaligned.h> 27#include <asm/unaligned.h>
27#include <sound/core.h> 28#include <sound/core.h>
28#include <sound/control.h> 29#include <sound/control.h>
@@ -55,18 +56,6 @@ struct cs8427 {
55 struct cs8427_stream capture; 56 struct cs8427_stream capture;
56}; 57};
57 58
58static unsigned char swapbits(unsigned char val)
59{
60 int bit;
61 unsigned char res = 0;
62 for (bit = 0; bit < 8; bit++) {
63 res <<= 1;
64 res |= val & 1;
65 val >>= 1;
66 }
67 return res;
68}
69
70int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg, 59int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
71 unsigned char val) 60 unsigned char val)
72{ 61{
@@ -149,7 +138,7 @@ static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
149 } 138 }
150 data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF; 139 data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF;
151 for (idx = 0; idx < count; idx++) 140 for (idx = 0; idx < count; idx++)
152 data[idx + 1] = swapbits(ndata[idx]); 141 data[idx + 1] = bitrev8(ndata[idx]);
153 if (snd_i2c_sendbytes(device, data, count + 1) != count + 1) 142 if (snd_i2c_sendbytes(device, data, count + 1) != count + 1)
154 return -EIO; 143 return -EIO;
155 return 1; 144 return 1;
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c
index d31c373e076d..c4c6ef73f9bf 100644
--- a/sound/i2c/other/tea575x-tuner.c
+++ b/sound/i2c/other/tea575x-tuner.c
@@ -225,7 +225,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
225 case V4L2_CID_AUDIO_MUTE: 225 case V4L2_CID_AUDIO_MUTE:
226 if (tea->ops->mute) { 226 if (tea->ops->mute) {
227 tea->ops->mute(tea, ctrl->value); 227 tea->ops->mute(tea, ctrl->value);
228 tea->mute = 1; 228 tea->mute = ctrl->value;
229 return 0; 229 return 0;
230 } 230 }
231 } 231 }
diff --git a/sound/isa/cs423x/cs4236.c b/sound/isa/cs423x/cs4236.c
index a076a6ce8071..cc15d1d65a22 100644
--- a/sound/isa/cs423x/cs4236.c
+++ b/sound/isa/cs423x/cs4236.c
@@ -177,7 +177,7 @@ static struct pnp_card_device_id snd_cs423x_pnpids[] = {
177 { .id = "CSC0437", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 177 { .id = "CSC0437", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
178 /* Digital PC 5000 Onboard - CS4236B */ 178 /* Digital PC 5000 Onboard - CS4236B */
179 { .id = "CSC0735", .devs = { { "CSC0000" }, { "CSC0010" } } }, 179 { .id = "CSC0735", .devs = { { "CSC0000" }, { "CSC0010" } } },
180 /* some uknown CS4236B */ 180 /* some unknown CS4236B */
181 { .id = "CSC0b35", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 181 { .id = "CSC0b35", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
182 /* Intel PR440FX Onboard sound */ 182 /* Intel PR440FX Onboard sound */
183 { .id = "CSC0b36", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } }, 183 { .id = "CSC0b36", .devs = { { "CSC0000" }, { "CSC0010" }, { "CSC0003" } } },
@@ -394,21 +394,15 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
394 return -EBUSY; 394 return -EBUSY;
395 } 395 }
396 396
397 err = snd_wss_create(card, port[dev], cport[dev], 397 err = snd_cs4236_create(card, port[dev], cport[dev],
398 irq[dev], 398 irq[dev],
399 dma1[dev], dma2[dev], 399 dma1[dev], dma2[dev],
400 WSS_HW_DETECT3, 0, &chip); 400 WSS_HW_DETECT3, 0, &chip);
401 if (err < 0) 401 if (err < 0)
402 return err; 402 return err;
403
404 acard->chip = chip;
403 if (chip->hardware & WSS_HW_CS4236B_MASK) { 405 if (chip->hardware & WSS_HW_CS4236B_MASK) {
404 snd_wss_free(chip);
405 err = snd_cs4236_create(card,
406 port[dev], cport[dev],
407 irq[dev], dma1[dev], dma2[dev],
408 WSS_HW_DETECT, 0, &chip);
409 if (err < 0)
410 return err;
411 acard->chip = chip;
412 406
413 err = snd_cs4236_pcm(chip, 0, &pcm); 407 err = snd_cs4236_pcm(chip, 0, &pcm);
414 if (err < 0) 408 if (err < 0)
@@ -418,7 +412,6 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
418 if (err < 0) 412 if (err < 0)
419 return err; 413 return err;
420 } else { 414 } else {
421 acard->chip = chip;
422 err = snd_wss_pcm(chip, 0, &pcm); 415 err = snd_wss_pcm(chip, 0, &pcm);
423 if (err < 0) 416 if (err < 0)
424 return err; 417 return err;
diff --git a/sound/isa/cs423x/cs4236_lib.c b/sound/isa/cs423x/cs4236_lib.c
index 38835f31298b..c5adca300632 100644
--- a/sound/isa/cs423x/cs4236_lib.c
+++ b/sound/isa/cs423x/cs4236_lib.c
@@ -87,6 +87,8 @@
87#include <sound/core.h> 87#include <sound/core.h>
88#include <sound/wss.h> 88#include <sound/wss.h>
89#include <sound/asoundef.h> 89#include <sound/asoundef.h>
90#include <sound/initval.h>
91#include <sound/tlv.h>
90 92
91/* 93/*
92 * 94 *
@@ -264,7 +266,10 @@ static void snd_cs4236_resume(struct snd_wss *chip)
264} 266}
265 267
266#endif /* CONFIG_PM */ 268#endif /* CONFIG_PM */
267 269/*
270 * This function does no fail if the chip is not CS4236B or compatible.
271 * It just an equivalent to the snd_wss_create() then.
272 */
268int snd_cs4236_create(struct snd_card *card, 273int snd_cs4236_create(struct snd_card *card,
269 unsigned long port, 274 unsigned long port,
270 unsigned long cport, 275 unsigned long cport,
@@ -281,21 +286,17 @@ int snd_cs4236_create(struct snd_card *card,
281 *rchip = NULL; 286 *rchip = NULL;
282 if (hardware == WSS_HW_DETECT) 287 if (hardware == WSS_HW_DETECT)
283 hardware = WSS_HW_DETECT3; 288 hardware = WSS_HW_DETECT3;
284 if (cport < 0x100) { 289
285 snd_printk(KERN_ERR "please, specify control port "
286 "for CS4236+ chips\n");
287 return -ENODEV;
288 }
289 err = snd_wss_create(card, port, cport, 290 err = snd_wss_create(card, port, cport,
290 irq, dma1, dma2, hardware, hwshare, &chip); 291 irq, dma1, dma2, hardware, hwshare, &chip);
291 if (err < 0) 292 if (err < 0)
292 return err; 293 return err;
293 294
294 if (!(chip->hardware & WSS_HW_CS4236B_MASK)) { 295 if ((chip->hardware & WSS_HW_CS4236B_MASK) == 0) {
295 snd_printk(KERN_ERR "CS4236+: MODE3 and extended registers " 296 snd_printd("chip is not CS4236+, hardware=0x%x\n",
296 "not available, hardware=0x%x\n", chip->hardware); 297 chip->hardware);
297 snd_device_free(card, chip); 298 *rchip = chip;
298 return -ENODEV; 299 return 0;
299 } 300 }
300#if 0 301#if 0
301 { 302 {
@@ -308,9 +309,16 @@ int snd_cs4236_create(struct snd_card *card,
308 idx, snd_cs4236_ctrl_in(chip, idx)); 309 idx, snd_cs4236_ctrl_in(chip, idx));
309 } 310 }
310#endif 311#endif
312 if (cport < 0x100 || cport == SNDRV_AUTO_PORT) {
313 snd_printk(KERN_ERR "please, specify control port "
314 "for CS4236+ chips\n");
315 snd_device_free(card, chip);
316 return -ENODEV;
317 }
311 ver1 = snd_cs4236_ctrl_in(chip, 1); 318 ver1 = snd_cs4236_ctrl_in(chip, 1);
312 ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION); 319 ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
313 snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2); 320 snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n",
321 cport, ver1, ver2);
314 if (ver1 != ver2) { 322 if (ver1 != ver2) {
315 snd_printk(KERN_ERR "CS4236+ chip detected, but " 323 snd_printk(KERN_ERR "CS4236+ chip detected, but "
316 "control port 0x%lx is not valid\n", cport); 324 "control port 0x%lx is not valid\n", cport);
@@ -321,13 +329,17 @@ int snd_cs4236_create(struct snd_card *card,
321 snd_cs4236_ctrl_out(chip, 2, 0xff); 329 snd_cs4236_ctrl_out(chip, 2, 0xff);
322 snd_cs4236_ctrl_out(chip, 3, 0x00); 330 snd_cs4236_ctrl_out(chip, 3, 0x00);
323 snd_cs4236_ctrl_out(chip, 4, 0x80); 331 snd_cs4236_ctrl_out(chip, 4, 0x80);
324 snd_cs4236_ctrl_out(chip, 5, ((IEC958_AES1_CON_PCM_CODER & 3) << 6) | IEC958_AES0_CON_EMPHASIS_NONE); 332 reg = ((IEC958_AES1_CON_PCM_CODER & 3) << 6) |
333 IEC958_AES0_CON_EMPHASIS_NONE;
334 snd_cs4236_ctrl_out(chip, 5, reg);
325 snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2); 335 snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2);
326 snd_cs4236_ctrl_out(chip, 7, 0x00); 336 snd_cs4236_ctrl_out(chip, 7, 0x00);
327 /* 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958 output */ 337 /*
328 /* is working with this setup, other hardware should have */ 338 * 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958
329 /* different signal paths and this value should be selectable */ 339 * output is working with this setup, other hardware should
330 /* in the future */ 340 * have different signal paths and this value should be
341 * selectable in the future
342 */
331 snd_cs4236_ctrl_out(chip, 8, 0x8c); 343 snd_cs4236_ctrl_out(chip, 8, 0x8c);
332 chip->rate_constraint = snd_cs4236_xrate; 344 chip->rate_constraint = snd_cs4236_xrate;
333 chip->set_playback_format = snd_cs4236_playback_format; 345 chip->set_playback_format = snd_cs4236_playback_format;
@@ -339,9 +351,10 @@ int snd_cs4236_create(struct snd_card *card,
339 351
340 /* initialize extended registers */ 352 /* initialize extended registers */
341 for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++) 353 for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++)
342 snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), snd_cs4236_ext_map[reg]); 354 snd_cs4236_ext_out(chip, CS4236_I23VAL(reg),
355 snd_cs4236_ext_map[reg]);
343 356
344 /* initialize compatible but more featured registers */ 357 /* initialize compatible but more featured registers */
345 snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40); 358 snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40);
346 snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40); 359 snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40);
347 snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff); 360 snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff);
@@ -387,6 +400,14 @@ int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
387 .get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \ 400 .get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
388 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) } 401 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
389 402
403#define CS4236_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
404{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
405 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
406 .info = snd_cs4236_info_single, \
407 .get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
408 .private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
409 .tlv = { .p = (xtlv) } }
410
390static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 411static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
391{ 412{
392 int mask = (kcontrol->private_value >> 16) & 0xff; 413 int mask = (kcontrol->private_value >> 16) & 0xff;
@@ -490,6 +511,16 @@ static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_
490 .get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \ 511 .get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
491 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } 512 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
492 513
514#define CS4236_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, \
515 shift_right, mask, invert, xtlv) \
516{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
517 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
518 .info = snd_cs4236_info_double, \
519 .get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
520 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
521 (shift_right << 19) | (mask << 24) | (invert << 22), \
522 .tlv = { .p = (xtlv) } }
523
493static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 524static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
494{ 525{
495 int mask = (kcontrol->private_value >> 24) & 0xff; 526 int mask = (kcontrol->private_value >> 24) & 0xff;
@@ -560,12 +591,23 @@ static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
560 return change; 591 return change;
561} 592}
562 593
563#define CS4236_DOUBLE1(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \ 594#define CS4236_DOUBLE1(xname, xindex, left_reg, right_reg, shift_left, \
595 shift_right, mask, invert) \
564{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 596{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
565 .info = snd_cs4236_info_double, \ 597 .info = snd_cs4236_info_double, \
566 .get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \ 598 .get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
567 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) } 599 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
568 600
601#define CS4236_DOUBLE1_TLV(xname, xindex, left_reg, right_reg, shift_left, \
602 shift_right, mask, invert, xtlv) \
603{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
604 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
605 .info = snd_cs4236_info_double, \
606 .get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
607 .private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
608 (shift_right << 19) | (mask << 24) | (invert << 22), \
609 .tlv = { .p = (xtlv) } }
610
569static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 611static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
570{ 612{
571 struct snd_wss *chip = snd_kcontrol_chip(kcontrol); 613 struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
@@ -619,16 +661,18 @@ static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_
619 return change; 661 return change;
620} 662}
621 663
622#define CS4236_MASTER_DIGITAL(xname, xindex) \ 664#define CS4236_MASTER_DIGITAL(xname, xindex, xtlv) \
623{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 665{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
666 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
624 .info = snd_cs4236_info_double, \ 667 .info = snd_cs4236_info_double, \
625 .get = snd_cs4236_get_master_digital, .put = snd_cs4236_put_master_digital, \ 668 .get = snd_cs4236_get_master_digital, .put = snd_cs4236_put_master_digital, \
626 .private_value = 71 << 24 } 669 .private_value = 71 << 24, \
670 .tlv = { .p = (xtlv) } }
627 671
628static inline int snd_cs4236_mixer_master_digital_invert_volume(int vol) 672static inline int snd_cs4236_mixer_master_digital_invert_volume(int vol)
629{ 673{
630 return (vol < 64) ? 63 - vol : 64 + (71 - vol); 674 return (vol < 64) ? 63 - vol : 64 + (71 - vol);
631} 675}
632 676
633static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 677static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
634{ 678{
@@ -661,11 +705,13 @@ static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct s
661 return change; 705 return change;
662} 706}
663 707
664#define CS4235_OUTPUT_ACCU(xname, xindex) \ 708#define CS4235_OUTPUT_ACCU(xname, xindex, xtlv) \
665{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 709{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
710 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
666 .info = snd_cs4236_info_double, \ 711 .info = snd_cs4236_info_double, \
667 .get = snd_cs4235_get_output_accu, .put = snd_cs4235_put_output_accu, \ 712 .get = snd_cs4235_get_output_accu, .put = snd_cs4235_put_output_accu, \
668 .private_value = 3 << 24 } 713 .private_value = 3 << 24, \
714 .tlv = { .p = (xtlv) } }
669 715
670static inline int snd_cs4235_mixer_output_accu_get_volume(int vol) 716static inline int snd_cs4235_mixer_output_accu_get_volume(int vol)
671{ 717{
@@ -720,41 +766,56 @@ static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_
720 return change; 766 return change;
721} 767}
722 768
769static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -9450, 150, 0);
770static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
771static const DECLARE_TLV_DB_SCALE(db_scale_6bit_12db_max, -8250, 150, 0);
772static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
773static const DECLARE_TLV_DB_SCALE(db_scale_5bit_22db_max, -2400, 150, 0);
774static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
775static const DECLARE_TLV_DB_SCALE(db_scale_2bit, -1800, 600, 0);
776static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
777
723static struct snd_kcontrol_new snd_cs4236_controls[] = { 778static struct snd_kcontrol_new snd_cs4236_controls[] = {
724 779
725CS4236_DOUBLE("Master Digital Playback Switch", 0, 780CS4236_DOUBLE("Master Digital Playback Switch", 0,
726 CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1), 781 CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
727CS4236_DOUBLE("Master Digital Capture Switch", 0, 782CS4236_DOUBLE("Master Digital Capture Switch", 0,
728 CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1), 783 CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
729CS4236_MASTER_DIGITAL("Master Digital Volume", 0), 784CS4236_MASTER_DIGITAL("Master Digital Volume", 0, db_scale_7bit),
730 785
731CS4236_DOUBLE("Capture Boost Volume", 0, 786CS4236_DOUBLE_TLV("Capture Boost Volume", 0,
732 CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1), 787 CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1,
788 db_scale_2bit),
733 789
734WSS_DOUBLE("PCM Playback Switch", 0, 790WSS_DOUBLE("PCM Playback Switch", 0,
735 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), 791 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
736WSS_DOUBLE("PCM Playback Volume", 0, 792WSS_DOUBLE_TLV("PCM Playback Volume", 0,
737 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), 793 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
794 db_scale_6bit),
738 795
739CS4236_DOUBLE("DSP Playback Switch", 0, 796CS4236_DOUBLE("DSP Playback Switch", 0,
740 CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1), 797 CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
741CS4236_DOUBLE("DSP Playback Volume", 0, 798CS4236_DOUBLE_TLV("DSP Playback Volume", 0,
742 CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1), 799 CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1,
800 db_scale_6bit),
743 801
744CS4236_DOUBLE("FM Playback Switch", 0, 802CS4236_DOUBLE("FM Playback Switch", 0,
745 CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1), 803 CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1),
746CS4236_DOUBLE("FM Playback Volume", 0, 804CS4236_DOUBLE_TLV("FM Playback Volume", 0,
747 CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1), 805 CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1,
806 db_scale_6bit),
748 807
749CS4236_DOUBLE("Wavetable Playback Switch", 0, 808CS4236_DOUBLE("Wavetable Playback Switch", 0,
750 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1), 809 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1),
751CS4236_DOUBLE("Wavetable Playback Volume", 0, 810CS4236_DOUBLE_TLV("Wavetable Playback Volume", 0,
752 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1), 811 CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1,
812 db_scale_6bit_12db_max),
753 813
754WSS_DOUBLE("Synth Playback Switch", 0, 814WSS_DOUBLE("Synth Playback Switch", 0,
755 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), 815 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
756WSS_DOUBLE("Synth Volume", 0, 816WSS_DOUBLE_TLV("Synth Volume", 0,
757 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), 817 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
818 db_scale_5bit_12db_max),
758WSS_DOUBLE("Synth Capture Switch", 0, 819WSS_DOUBLE("Synth Capture Switch", 0,
759 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1), 820 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
760WSS_DOUBLE("Synth Capture Bypass", 0, 821WSS_DOUBLE("Synth Capture Bypass", 0,
@@ -764,14 +825,16 @@ CS4236_DOUBLE("Mic Playback Switch", 0,
764 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1), 825 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
765CS4236_DOUBLE("Mic Capture Switch", 0, 826CS4236_DOUBLE("Mic Capture Switch", 0,
766 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1), 827 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
767CS4236_DOUBLE("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 0, 0, 31, 1), 828CS4236_DOUBLE_TLV("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC,
768CS4236_DOUBLE("Mic Playback Boost", 0, 829 0, 0, 31, 1, db_scale_5bit_22db_max),
830CS4236_DOUBLE("Mic Playback Boost (+20dB)", 0,
769 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0), 831 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0),
770 832
771WSS_DOUBLE("Line Playback Switch", 0, 833WSS_DOUBLE("Line Playback Switch", 0,
772 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), 834 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
773WSS_DOUBLE("Line Volume", 0, 835WSS_DOUBLE_TLV("Line Volume", 0,
774 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), 836 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
837 db_scale_5bit_12db_max),
775WSS_DOUBLE("Line Capture Switch", 0, 838WSS_DOUBLE("Line Capture Switch", 0,
776 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1), 839 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
777WSS_DOUBLE("Line Capture Bypass", 0, 840WSS_DOUBLE("Line Capture Bypass", 0,
@@ -779,57 +842,63 @@ WSS_DOUBLE("Line Capture Bypass", 0,
779 842
780WSS_DOUBLE("CD Playback Switch", 0, 843WSS_DOUBLE("CD Playback Switch", 0,
781 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), 844 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
782WSS_DOUBLE("CD Volume", 0, 845WSS_DOUBLE_TLV("CD Volume", 0,
783 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), 846 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
847 db_scale_5bit_12db_max),
784WSS_DOUBLE("CD Capture Switch", 0, 848WSS_DOUBLE("CD Capture Switch", 0,
785 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1), 849 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
786 850
787CS4236_DOUBLE1("Mono Output Playback Switch", 0, 851CS4236_DOUBLE1("Mono Output Playback Switch", 0,
788 CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1), 852 CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
789CS4236_DOUBLE1("Mono Playback Switch", 0, 853CS4236_DOUBLE1("Beep Playback Switch", 0,
790 CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1), 854 CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
791WSS_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), 855WSS_SINGLE_TLV("Beep Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1,
792WSS_SINGLE("Mono Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0), 856 db_scale_4bit),
857WSS_SINGLE("Beep Bypass Playback Switch", 0, CS4231_MONO_CTRL, 5, 1, 0),
793 858
794WSS_DOUBLE("Capture Volume", 0, 859WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
795 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0), 860 0, 0, 15, 0, db_scale_rec_gain),
796WSS_DOUBLE("Analog Loopback Capture Switch", 0, 861WSS_DOUBLE("Analog Loopback Capture Switch", 0,
797 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0), 862 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
798 863
799WSS_SINGLE("Digital Loopback Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0), 864WSS_SINGLE("Loopback Digital Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
800CS4236_DOUBLE1("Digital Loopback Playback Volume", 0, 865CS4236_DOUBLE1_TLV("Loopback Digital Playback Volume", 0,
801 CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1) 866 CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1,
867 db_scale_6bit),
802}; 868};
803 869
870static const DECLARE_TLV_DB_SCALE(db_scale_5bit_6db_max, -5600, 200, 0);
871static const DECLARE_TLV_DB_SCALE(db_scale_2bit_16db_max, -2400, 800, 0);
872
804static struct snd_kcontrol_new snd_cs4235_controls[] = { 873static struct snd_kcontrol_new snd_cs4235_controls[] = {
805 874
806WSS_DOUBLE("Master Switch", 0, 875WSS_DOUBLE("Master Playback Switch", 0,
807 CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1), 876 CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1),
808WSS_DOUBLE("Master Volume", 0, 877WSS_DOUBLE_TLV("Master Playback Volume", 0,
809 CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1), 878 CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1,
810 879 db_scale_5bit_6db_max),
811CS4235_OUTPUT_ACCU("Playback Volume", 0),
812 880
813CS4236_DOUBLE("Master Digital Playback Switch", 0, 881CS4235_OUTPUT_ACCU("Playback Volume", 0, db_scale_2bit_16db_max),
814 CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
815CS4236_DOUBLE("Master Digital Capture Switch", 0,
816 CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
817CS4236_MASTER_DIGITAL("Master Digital Volume", 0),
818 882
819WSS_DOUBLE("Master Digital Playback Switch", 1, 883WSS_DOUBLE("Synth Playback Switch", 1,
820 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1), 884 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
821WSS_DOUBLE("Master Digital Capture Switch", 1, 885WSS_DOUBLE("Synth Capture Switch", 1,
822 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1), 886 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
823WSS_DOUBLE("Master Digital Volume", 1, 887WSS_DOUBLE_TLV("Synth Volume", 1,
824 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1), 888 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
889 db_scale_5bit_12db_max),
825 890
826CS4236_DOUBLE("Capture Volume", 0, 891CS4236_DOUBLE_TLV("Capture Volume", 0,
827 CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1), 892 CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1,
893 db_scale_2bit),
828 894
829WSS_DOUBLE("PCM Switch", 0, 895WSS_DOUBLE("PCM Playback Switch", 0,
830 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1), 896 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
831WSS_DOUBLE("PCM Volume", 0, 897WSS_DOUBLE("PCM Capture Switch", 0,
832 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1), 898 CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
899WSS_DOUBLE_TLV("PCM Volume", 0,
900 CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
901 db_scale_6bit),
833 902
834CS4236_DOUBLE("DSP Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1), 903CS4236_DOUBLE("DSP Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
835 904
@@ -842,29 +911,29 @@ CS4236_DOUBLE("Mic Capture Switch", 0,
842 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1), 911 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
843CS4236_DOUBLE("Mic Playback Switch", 0, 912CS4236_DOUBLE("Mic Playback Switch", 0,
844 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1), 913 CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
845CS4236_SINGLE("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1), 914CS4236_SINGLE_TLV("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1,
846CS4236_SINGLE("Mic Playback Boost", 0, CS4236_LEFT_MIC, 5, 1, 0), 915 db_scale_5bit_22db_max),
916CS4236_SINGLE("Mic Boost (+20dB)", 0, CS4236_LEFT_MIC, 5, 1, 0),
847 917
848WSS_DOUBLE("Aux Playback Switch", 0, 918WSS_DOUBLE("Line Playback Switch", 0,
849 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1), 919 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
850WSS_DOUBLE("Aux Capture Switch", 0, 920WSS_DOUBLE("Line Capture Switch", 0,
851 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1), 921 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
852WSS_DOUBLE("Aux Volume", 0, 922WSS_DOUBLE_TLV("Line Volume", 0,
853 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1), 923 CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
924 db_scale_5bit_12db_max),
854 925
855WSS_DOUBLE("Aux Playback Switch", 1, 926WSS_DOUBLE("CD Playback Switch", 1,
856 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1), 927 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
857WSS_DOUBLE("Aux Capture Switch", 1, 928WSS_DOUBLE("CD Capture Switch", 1,
858 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1), 929 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
859WSS_DOUBLE("Aux Volume", 1, 930WSS_DOUBLE_TLV("CD Volume", 1,
860 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1), 931 CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
861 932 db_scale_5bit_12db_max),
862CS4236_DOUBLE1("Master Mono Switch", 0,
863 CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
864 933
865CS4236_DOUBLE1("Mono Switch", 0, 934CS4236_DOUBLE1("Beep Playback Switch", 0,
866 CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1), 935 CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
867WSS_SINGLE("Mono Volume", 0, CS4231_MONO_CTRL, 0, 15, 1), 936WSS_SINGLE("Beep Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
868 937
869WSS_DOUBLE("Analog Loopback Switch", 0, 938WSS_DOUBLE("Analog Loopback Switch", 0,
870 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0), 939 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index e5bf3355d2ca..9a43baae7250 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -102,8 +102,6 @@
102 102
103struct snd_es18xx { 103struct snd_es18xx {
104 unsigned long port; /* port of ESS chip */ 104 unsigned long port; /* port of ESS chip */
105 unsigned long mpu_port; /* MPU-401 port of ESS chip */
106 unsigned long fm_port; /* FM port */
107 unsigned long ctrl_port; /* Control port of ESS chip */ 105 unsigned long ctrl_port; /* Control port of ESS chip */
108 struct resource *res_port; 106 struct resource *res_port;
109 struct resource *res_mpu_port; 107 struct resource *res_mpu_port;
@@ -116,8 +114,6 @@ struct snd_es18xx {
116 unsigned short audio2_vol; /* volume level of audio2 */ 114 unsigned short audio2_vol; /* volume level of audio2 */
117 115
118 unsigned short active; /* active channel mask */ 116 unsigned short active; /* active channel mask */
119 unsigned int dma1_size;
120 unsigned int dma2_size;
121 unsigned int dma1_shift; 117 unsigned int dma1_shift;
122 unsigned int dma2_shift; 118 unsigned int dma2_shift;
123 119
@@ -135,7 +131,6 @@ struct snd_es18xx {
135 131
136 spinlock_t reg_lock; 132 spinlock_t reg_lock;
137 spinlock_t mixer_lock; 133 spinlock_t mixer_lock;
138 spinlock_t ctrl_lock;
139#ifdef CONFIG_PM 134#ifdef CONFIG_PM
140 unsigned char pm_reg; 135 unsigned char pm_reg;
141#endif 136#endif
@@ -354,7 +349,7 @@ static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned ch
354} 349}
355 350
356 351
357static int snd_es18xx_reset(struct snd_es18xx *chip) 352static int __devinit snd_es18xx_reset(struct snd_es18xx *chip)
358{ 353{
359 int i; 354 int i;
360 outb(0x03, chip->port + 0x06); 355 outb(0x03, chip->port + 0x06);
@@ -490,8 +485,6 @@ static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip,
490 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 485 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
491 unsigned int count = snd_pcm_lib_period_bytes(substream); 486 unsigned int count = snd_pcm_lib_period_bytes(substream);
492 487
493 chip->dma2_size = size;
494
495 snd_es18xx_rate_set(chip, substream, DAC2); 488 snd_es18xx_rate_set(chip, substream, DAC2);
496 489
497 /* Transfer Count Reload */ 490 /* Transfer Count Reload */
@@ -591,8 +584,6 @@ static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream)
591 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 584 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
592 unsigned int count = snd_pcm_lib_period_bytes(substream); 585 unsigned int count = snd_pcm_lib_period_bytes(substream);
593 586
594 chip->dma1_size = size;
595
596 snd_es18xx_reset_fifo(chip); 587 snd_es18xx_reset_fifo(chip);
597 588
598 /* Set stereo/mono */ 589 /* Set stereo/mono */
@@ -659,8 +650,6 @@ static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip,
659 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 650 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
660 unsigned int count = snd_pcm_lib_period_bytes(substream); 651 unsigned int count = snd_pcm_lib_period_bytes(substream);
661 652
662 chip->dma1_size = size;
663
664 snd_es18xx_reset_fifo(chip); 653 snd_es18xx_reset_fifo(chip);
665 654
666 /* Set stereo/mono */ 655 /* Set stereo/mono */
@@ -821,17 +810,18 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
821static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream) 810static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream)
822{ 811{
823 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); 812 struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
813 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
824 int pos; 814 int pos;
825 815
826 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { 816 if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
827 if (!(chip->active & DAC2)) 817 if (!(chip->active & DAC2))
828 return 0; 818 return 0;
829 pos = snd_dma_pointer(chip->dma2, chip->dma2_size); 819 pos = snd_dma_pointer(chip->dma2, size);
830 return pos >> chip->dma2_shift; 820 return pos >> chip->dma2_shift;
831 } else { 821 } else {
832 if (!(chip->active & DAC1)) 822 if (!(chip->active & DAC1))
833 return 0; 823 return 0;
834 pos = snd_dma_pointer(chip->dma1, chip->dma1_size); 824 pos = snd_dma_pointer(chip->dma1, size);
835 return pos >> chip->dma1_shift; 825 return pos >> chip->dma1_shift;
836 } 826 }
837} 827}
@@ -839,11 +829,12 @@ static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *s
839static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream) 829static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream)
840{ 830{
841 struct snd_es18xx *chip = snd_pcm_substream_chip(substream); 831 struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
832 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
842 int pos; 833 int pos;
843 834
844 if (!(chip->active & ADC1)) 835 if (!(chip->active & ADC1))
845 return 0; 836 return 0;
846 pos = snd_dma_pointer(chip->dma1, chip->dma1_size); 837 pos = snd_dma_pointer(chip->dma1, size);
847 return pos >> chip->dma1_shift; 838 return pos >> chip->dma1_shift;
848} 839}
849 840
@@ -974,9 +965,6 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream)
974 965
975static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 966static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
976{ 967{
977 static char *texts4Source[4] = {
978 "Mic", "CD", "Line", "Master"
979 };
980 static char *texts5Source[5] = { 968 static char *texts5Source[5] = {
981 "Mic", "CD", "Line", "Master", "Mix" 969 "Mic", "CD", "Line", "Master", "Mix"
982 }; 970 };
@@ -994,7 +982,8 @@ static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
994 uinfo->value.enumerated.items = 4; 982 uinfo->value.enumerated.items = 4;
995 if (uinfo->value.enumerated.item > 3) 983 if (uinfo->value.enumerated.item > 3)
996 uinfo->value.enumerated.item = 3; 984 uinfo->value.enumerated.item = 3;
997 strcpy(uinfo->value.enumerated.name, texts4Source[uinfo->value.enumerated.item]); 985 strcpy(uinfo->value.enumerated.name,
986 texts5Source[uinfo->value.enumerated.item]);
998 break; 987 break;
999 case 0x1887: 988 case 0x1887:
1000 case 0x1888: 989 case 0x1888:
@@ -1378,11 +1367,9 @@ ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0),
1378static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) 1367static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
1379{ 1368{
1380 int data; 1369 int data;
1381 unsigned long flags; 1370
1382 spin_lock_irqsave(&chip->ctrl_lock, flags);
1383 outb(reg, chip->ctrl_port); 1371 outb(reg, chip->ctrl_port);
1384 data = inb(chip->ctrl_port + 1); 1372 data = inb(chip->ctrl_port + 1);
1385 spin_unlock_irqrestore(&chip->ctrl_lock, flags);
1386 return data; 1373 return data;
1387} 1374}
1388 1375
@@ -1398,7 +1385,9 @@ static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip,
1398#endif 1385#endif
1399} 1386}
1400 1387
1401static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip) 1388static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip,
1389 unsigned long mpu_port,
1390 unsigned long fm_port)
1402{ 1391{
1403 int mask = 0; 1392 int mask = 0;
1404 1393
@@ -1412,15 +1401,15 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
1412 if (chip->caps & ES18XX_CONTROL) { 1401 if (chip->caps & ES18XX_CONTROL) {
1413 /* Hardware volume IRQ */ 1402 /* Hardware volume IRQ */
1414 snd_es18xx_config_write(chip, 0x27, chip->irq); 1403 snd_es18xx_config_write(chip, 0x27, chip->irq);
1415 if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) { 1404 if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
1416 /* FM I/O */ 1405 /* FM I/O */
1417 snd_es18xx_config_write(chip, 0x62, chip->fm_port >> 8); 1406 snd_es18xx_config_write(chip, 0x62, fm_port >> 8);
1418 snd_es18xx_config_write(chip, 0x63, chip->fm_port & 0xff); 1407 snd_es18xx_config_write(chip, 0x63, fm_port & 0xff);
1419 } 1408 }
1420 if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) { 1409 if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
1421 /* MPU-401 I/O */ 1410 /* MPU-401 I/O */
1422 snd_es18xx_config_write(chip, 0x64, chip->mpu_port >> 8); 1411 snd_es18xx_config_write(chip, 0x64, mpu_port >> 8);
1423 snd_es18xx_config_write(chip, 0x65, chip->mpu_port & 0xff); 1412 snd_es18xx_config_write(chip, 0x65, mpu_port & 0xff);
1424 /* MPU-401 IRQ */ 1413 /* MPU-401 IRQ */
1425 snd_es18xx_config_write(chip, 0x28, chip->irq); 1414 snd_es18xx_config_write(chip, 0x28, chip->irq);
1426 } 1415 }
@@ -1507,11 +1496,12 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
1507 snd_es18xx_mixer_write(chip, 0x7A, 0x68); 1496 snd_es18xx_mixer_write(chip, 0x7A, 0x68);
1508 /* Enable and set hardware volume interrupt */ 1497 /* Enable and set hardware volume interrupt */
1509 snd_es18xx_mixer_write(chip, 0x64, 0x06); 1498 snd_es18xx_mixer_write(chip, 0x64, 0x06);
1510 if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) { 1499 if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
1511 /* MPU401 share irq with audio 1500 /* MPU401 share irq with audio
1512 Joystick enabled 1501 Joystick enabled
1513 FM enabled */ 1502 FM enabled */
1514 snd_es18xx_mixer_write(chip, 0x40, 0x43 | (chip->mpu_port & 0xf0) >> 1); 1503 snd_es18xx_mixer_write(chip, 0x40,
1504 0x43 | (mpu_port & 0xf0) >> 1);
1515 } 1505 }
1516 snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01); 1506 snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01);
1517 } 1507 }
@@ -1629,7 +1619,9 @@ static int __devinit snd_es18xx_identify(struct snd_es18xx *chip)
1629 return 0; 1619 return 0;
1630} 1620}
1631 1621
1632static int __devinit snd_es18xx_probe(struct snd_es18xx *chip) 1622static int __devinit snd_es18xx_probe(struct snd_es18xx *chip,
1623 unsigned long mpu_port,
1624 unsigned long fm_port)
1633{ 1625{
1634 if (snd_es18xx_identify(chip) < 0) { 1626 if (snd_es18xx_identify(chip) < 0) {
1635 snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port); 1627 snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port);
@@ -1650,8 +1642,6 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
1650 chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV; 1642 chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV;
1651 break; 1643 break;
1652 case 0x1887: 1644 case 0x1887:
1653 chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
1654 break;
1655 case 0x1888: 1645 case 0x1888:
1656 chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; 1646 chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
1657 break; 1647 break;
@@ -1666,7 +1656,7 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
1666 if (chip->dma1 == chip->dma2) 1656 if (chip->dma1 == chip->dma2)
1667 chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME); 1657 chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME);
1668 1658
1669 return snd_es18xx_initialize(chip); 1659 return snd_es18xx_initialize(chip, mpu_port, fm_port);
1670} 1660}
1671 1661
1672static struct snd_pcm_ops snd_es18xx_playback_ops = { 1662static struct snd_pcm_ops snd_es18xx_playback_ops = {
@@ -1802,10 +1792,7 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card,
1802 1792
1803 spin_lock_init(&chip->reg_lock); 1793 spin_lock_init(&chip->reg_lock);
1804 spin_lock_init(&chip->mixer_lock); 1794 spin_lock_init(&chip->mixer_lock);
1805 spin_lock_init(&chip->ctrl_lock);
1806 chip->port = port; 1795 chip->port = port;
1807 chip->mpu_port = mpu_port;
1808 chip->fm_port = fm_port;
1809 chip->irq = -1; 1796 chip->irq = -1;
1810 chip->dma1 = -1; 1797 chip->dma1 = -1;
1811 chip->dma2 = -1; 1798 chip->dma2 = -1;
@@ -1841,11 +1828,11 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card,
1841 } 1828 }
1842 chip->dma2 = dma2; 1829 chip->dma2 = dma2;
1843 1830
1844 if (snd_es18xx_probe(chip) < 0) { 1831 if (snd_es18xx_probe(chip, mpu_port, fm_port) < 0) {
1845 snd_es18xx_free(card); 1832 snd_es18xx_free(card);
1846 return -ENODEV; 1833 return -ENODEV;
1847 } 1834 }
1848 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, NULL, &ops); 1835 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1849 if (err < 0) { 1836 if (err < 0) {
1850 snd_es18xx_free(card); 1837 snd_es18xx_free(card);
1851 return err; 1838 return err;
@@ -1980,7 +1967,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
1980static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 1967static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
1981static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ 1968static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
1982#ifdef CONFIG_PNP 1969#ifdef CONFIG_PNP
1983static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; 1970static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
1984#endif 1971#endif
1985static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */ 1972static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */
1986#ifndef CONFIG_PNP 1973#ifndef CONFIG_PNP
@@ -2160,19 +2147,23 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
2160 return err; 2147 return err;
2161 2148
2162 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { 2149 if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
2163 if (snd_opl3_create(card, chip->fm_port, chip->fm_port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) { 2150 if (snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
2164 snd_printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->fm_port); 2151 OPL3_HW_OPL3, 0, &opl3) < 0) {
2152 snd_printk(KERN_WARNING PFX
2153 "opl3 not detected at 0x%lx\n",
2154 fm_port[dev]);
2165 } else { 2155 } else {
2166 if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) 2156 err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
2157 if (err < 0)
2167 return err; 2158 return err;
2168 } 2159 }
2169 } 2160 }
2170 2161
2171 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { 2162 if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
2172 if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX, 2163 err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
2173 chip->mpu_port, 0, 2164 mpu_port[dev], 0,
2174 irq[dev], 0, 2165 irq[dev], 0, &chip->rmidi);
2175 &chip->rmidi)) < 0) 2166 if (err < 0)
2176 return err; 2167 return err;
2177 } 2168 }
2178 2169
diff --git a/sound/isa/opti9xx/miro.c b/sound/isa/opti9xx/miro.c
index 02e30d7c6a93..b865e45a8f9b 100644
--- a/sound/isa/opti9xx/miro.c
+++ b/sound/isa/opti9xx/miro.c
@@ -25,6 +25,7 @@
25#include <linux/init.h> 25#include <linux/init.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/isa.h> 27#include <linux/isa.h>
28#include <linux/pnp.h>
28#include <linux/delay.h> 29#include <linux/delay.h>
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/ioport.h> 31#include <linux/ioport.h>
@@ -40,7 +41,7 @@
40#define SNDRV_LEGACY_FIND_FREE_IRQ 41#define SNDRV_LEGACY_FIND_FREE_IRQ
41#define SNDRV_LEGACY_FIND_FREE_DMA 42#define SNDRV_LEGACY_FIND_FREE_DMA
42#include <sound/initval.h> 43#include <sound/initval.h>
43#include "miro.h" 44#include <sound/aci.h>
44 45
45MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>"); 46MODULE_AUTHOR("Martin Langer <martin-langer@gmx.de>");
46MODULE_LICENSE("GPL"); 47MODULE_LICENSE("GPL");
@@ -60,6 +61,9 @@ static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
60static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */ 61static int dma2 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
61static int wss; 62static int wss;
62static int ide; 63static int ide;
64#ifdef CONFIG_PNP
65static int isapnp = 1; /* Enable ISA PnP detection */
66#endif
63 67
64module_param(index, int, 0444); 68module_param(index, int, 0444);
65MODULE_PARM_DESC(index, "Index value for miro soundcard."); 69MODULE_PARM_DESC(index, "Index value for miro soundcard.");
@@ -83,6 +87,10 @@ module_param(wss, int, 0444);
83MODULE_PARM_DESC(wss, "wss mode"); 87MODULE_PARM_DESC(wss, "wss mode");
84module_param(ide, int, 0444); 88module_param(ide, int, 0444);
85MODULE_PARM_DESC(ide, "enable ide port"); 89MODULE_PARM_DESC(ide, "enable ide port");
90#ifdef CONFIG_PNP
91module_param(isapnp, bool, 0444);
92MODULE_PARM_DESC(isapnp, "Enable ISA PnP detection for specified soundcard.");
93#endif
86 94
87#define OPTi9XX_HW_DETECT 0 95#define OPTi9XX_HW_DETECT 0
88#define OPTi9XX_HW_82C928 1 96#define OPTi9XX_HW_82C928 1
@@ -96,7 +104,6 @@ MODULE_PARM_DESC(ide, "enable ide port");
96 104
97#define OPTi9XX_MC_REG(n) n 105#define OPTi9XX_MC_REG(n) n
98 106
99
100struct snd_miro { 107struct snd_miro {
101 unsigned short hardware; 108 unsigned short hardware;
102 unsigned char password; 109 unsigned char password;
@@ -110,7 +117,6 @@ struct snd_miro {
110 unsigned long pwd_reg; 117 unsigned long pwd_reg;
111 118
112 spinlock_t lock; 119 spinlock_t lock;
113 struct snd_card *card;
114 struct snd_pcm *pcm; 120 struct snd_pcm *pcm;
115 121
116 long wss_base; 122 long wss_base;
@@ -118,42 +124,48 @@ struct snd_miro {
118 int dma1; 124 int dma1;
119 int dma2; 125 int dma2;
120 126
121 long fm_port;
122
123 long mpu_port; 127 long mpu_port;
124 int mpu_irq; 128 int mpu_irq;
125 129
126 unsigned long aci_port; 130 struct snd_miro_aci *aci;
127 int aci_vendor;
128 int aci_product;
129 int aci_version;
130 int aci_amp;
131 int aci_preamp;
132 int aci_solomode;
133
134 struct mutex aci_mutex;
135}; 131};
136 132
137static void snd_miro_proc_init(struct snd_miro * miro); 133static struct snd_miro_aci aci_device;
138 134
139static char * snd_opti9xx_names[] = { 135static char * snd_opti9xx_names[] = {
140 "unkown", 136 "unknown",
141 "82C928", "82C929", 137 "82C928", "82C929",
142 "82C924", "82C925", 138 "82C924", "82C925",
143 "82C930", "82C931", "82C933" 139 "82C930", "82C931", "82C933"
144}; 140};
145 141
142static int snd_miro_pnp_is_probed;
143
144#ifdef CONFIG_PNP
145
146static struct pnp_card_device_id snd_miro_pnpids[] = {
147 /* PCM20 and PCM12 in PnP mode */
148 { .id = "MIR0924",
149 .devs = { { "MIR0000" }, { "MIR0002" }, { "MIR0005" } }, },
150 { .id = "" }
151};
152
153MODULE_DEVICE_TABLE(pnp_card, snd_miro_pnpids);
154
155#endif /* CONFIG_PNP */
156
146/* 157/*
147 * ACI control 158 * ACI control
148 */ 159 */
149 160
150static int aci_busy_wait(struct snd_miro * miro) 161static int aci_busy_wait(struct snd_miro_aci *aci)
151{ 162{
152 long timeout; 163 long timeout;
153 unsigned char byte; 164 unsigned char byte;
154 165
155 for (timeout = 1; timeout <= ACI_MINTIME+30; timeout++) { 166 for (timeout = 1; timeout <= ACI_MINTIME + 30; timeout++) {
156 if (((byte=inb(miro->aci_port + ACI_REG_BUSY)) & 1) == 0) { 167 byte = inb(aci->aci_port + ACI_REG_BUSY);
168 if ((byte & 1) == 0) {
157 if (timeout >= ACI_MINTIME) 169 if (timeout >= ACI_MINTIME)
158 snd_printd("aci ready in round %ld.\n", 170 snd_printd("aci ready in round %ld.\n",
159 timeout-ACI_MINTIME); 171 timeout-ACI_MINTIME);
@@ -179,10 +191,10 @@ static int aci_busy_wait(struct snd_miro * miro)
179 return -EBUSY; 191 return -EBUSY;
180} 192}
181 193
182static inline int aci_write(struct snd_miro * miro, unsigned char byte) 194static inline int aci_write(struct snd_miro_aci *aci, unsigned char byte)
183{ 195{
184 if (aci_busy_wait(miro) >= 0) { 196 if (aci_busy_wait(aci) >= 0) {
185 outb(byte, miro->aci_port + ACI_REG_COMMAND); 197 outb(byte, aci->aci_port + ACI_REG_COMMAND);
186 return 0; 198 return 0;
187 } else { 199 } else {
188 snd_printk(KERN_ERR "aci busy, aci_write(0x%x) stopped.\n", byte); 200 snd_printk(KERN_ERR "aci busy, aci_write(0x%x) stopped.\n", byte);
@@ -190,12 +202,12 @@ static inline int aci_write(struct snd_miro * miro, unsigned char byte)
190 } 202 }
191} 203}
192 204
193static inline int aci_read(struct snd_miro * miro) 205static inline int aci_read(struct snd_miro_aci *aci)
194{ 206{
195 unsigned char byte; 207 unsigned char byte;
196 208
197 if (aci_busy_wait(miro) >= 0) { 209 if (aci_busy_wait(aci) >= 0) {
198 byte=inb(miro->aci_port + ACI_REG_STATUS); 210 byte = inb(aci->aci_port + ACI_REG_STATUS);
199 return byte; 211 return byte;
200 } else { 212 } else {
201 snd_printk(KERN_ERR "aci busy, aci_read() stopped.\n"); 213 snd_printk(KERN_ERR "aci busy, aci_read() stopped.\n");
@@ -203,39 +215,49 @@ static inline int aci_read(struct snd_miro * miro)
203 } 215 }
204} 216}
205 217
206static int aci_cmd(struct snd_miro * miro, int write1, int write2, int write3) 218int snd_aci_cmd(struct snd_miro_aci *aci, int write1, int write2, int write3)
207{ 219{
208 int write[] = {write1, write2, write3}; 220 int write[] = {write1, write2, write3};
209 int value, i; 221 int value, i;
210 222
211 if (mutex_lock_interruptible(&miro->aci_mutex)) 223 if (mutex_lock_interruptible(&aci->aci_mutex))
212 return -EINTR; 224 return -EINTR;
213 225
214 for (i=0; i<3; i++) { 226 for (i=0; i<3; i++) {
215 if (write[i]< 0 || write[i] > 255) 227 if (write[i]< 0 || write[i] > 255)
216 break; 228 break;
217 else { 229 else {
218 value = aci_write(miro, write[i]); 230 value = aci_write(aci, write[i]);
219 if (value < 0) 231 if (value < 0)
220 goto out; 232 goto out;
221 } 233 }
222 } 234 }
223 235
224 value = aci_read(miro); 236 value = aci_read(aci);
225 237
226out: mutex_unlock(&miro->aci_mutex); 238out: mutex_unlock(&aci->aci_mutex);
227 return value; 239 return value;
228} 240}
241EXPORT_SYMBOL(snd_aci_cmd);
242
243static int aci_getvalue(struct snd_miro_aci *aci, unsigned char index)
244{
245 return snd_aci_cmd(aci, ACI_STATUS, index, -1);
246}
229 247
230static int aci_getvalue(struct snd_miro * miro, unsigned char index) 248static int aci_setvalue(struct snd_miro_aci *aci, unsigned char index,
249 int value)
231{ 250{
232 return aci_cmd(miro, ACI_STATUS, index, -1); 251 return snd_aci_cmd(aci, index, value, -1);
233} 252}
234 253
235static int aci_setvalue(struct snd_miro * miro, unsigned char index, int value) 254struct snd_miro_aci *snd_aci_get_aci(void)
236{ 255{
237 return aci_cmd(miro, index, value, -1); 256 if (aci_device.aci_port == 0)
257 return NULL;
258 return &aci_device;
238} 259}
260EXPORT_SYMBOL(snd_aci_get_aci);
239 261
240/* 262/*
241 * MIXER part 263 * MIXER part
@@ -249,8 +271,10 @@ static int snd_miro_get_capture(struct snd_kcontrol *kcontrol,
249 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 271 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
250 int value; 272 int value;
251 273
252 if ((value = aci_getvalue(miro, ACI_S_GENERAL)) < 0) { 274 value = aci_getvalue(miro->aci, ACI_S_GENERAL);
253 snd_printk(KERN_ERR "snd_miro_get_capture() failed: %d\n", value); 275 if (value < 0) {
276 snd_printk(KERN_ERR "snd_miro_get_capture() failed: %d\n",
277 value);
254 return value; 278 return value;
255 } 279 }
256 280
@@ -267,13 +291,15 @@ static int snd_miro_put_capture(struct snd_kcontrol *kcontrol,
267 291
268 value = !(ucontrol->value.integer.value[0]); 292 value = !(ucontrol->value.integer.value[0]);
269 293
270 if ((error = aci_setvalue(miro, ACI_SET_SOLOMODE, value)) < 0) { 294 error = aci_setvalue(miro->aci, ACI_SET_SOLOMODE, value);
271 snd_printk(KERN_ERR "snd_miro_put_capture() failed: %d\n", error); 295 if (error < 0) {
296 snd_printk(KERN_ERR "snd_miro_put_capture() failed: %d\n",
297 error);
272 return error; 298 return error;
273 } 299 }
274 300
275 change = (value != miro->aci_solomode); 301 change = (value != miro->aci->aci_solomode);
276 miro->aci_solomode = value; 302 miro->aci->aci_solomode = value;
277 303
278 return change; 304 return change;
279} 305}
@@ -295,7 +321,7 @@ static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
295 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 321 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
296 int value; 322 int value;
297 323
298 if (miro->aci_version <= 176) { 324 if (miro->aci->aci_version <= 176) {
299 325
300 /* 326 /*
301 OSS says it's not readable with versions < 176. 327 OSS says it's not readable with versions < 176.
@@ -303,12 +329,14 @@ static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
303 which is a PCM12 with aci_version = 176. 329 which is a PCM12 with aci_version = 176.
304 */ 330 */
305 331
306 ucontrol->value.integer.value[0] = miro->aci_preamp; 332 ucontrol->value.integer.value[0] = miro->aci->aci_preamp;
307 return 0; 333 return 0;
308 } 334 }
309 335
310 if ((value = aci_getvalue(miro, ACI_GET_PREAMP)) < 0) { 336 value = aci_getvalue(miro->aci, ACI_GET_PREAMP);
311 snd_printk(KERN_ERR "snd_miro_get_preamp() failed: %d\n", value); 337 if (value < 0) {
338 snd_printk(KERN_ERR "snd_miro_get_preamp() failed: %d\n",
339 value);
312 return value; 340 return value;
313 } 341 }
314 342
@@ -325,13 +353,15 @@ static int snd_miro_put_preamp(struct snd_kcontrol *kcontrol,
325 353
326 value = ucontrol->value.integer.value[0]; 354 value = ucontrol->value.integer.value[0];
327 355
328 if ((error = aci_setvalue(miro, ACI_SET_PREAMP, value)) < 0) { 356 error = aci_setvalue(miro->aci, ACI_SET_PREAMP, value);
329 snd_printk(KERN_ERR "snd_miro_put_preamp() failed: %d\n", error); 357 if (error < 0) {
358 snd_printk(KERN_ERR "snd_miro_put_preamp() failed: %d\n",
359 error);
330 return error; 360 return error;
331 } 361 }
332 362
333 change = (value != miro->aci_preamp); 363 change = (value != miro->aci->aci_preamp);
334 miro->aci_preamp = value; 364 miro->aci->aci_preamp = value;
335 365
336 return change; 366 return change;
337} 367}
@@ -342,7 +372,7 @@ static int snd_miro_get_amp(struct snd_kcontrol *kcontrol,
342 struct snd_ctl_elem_value *ucontrol) 372 struct snd_ctl_elem_value *ucontrol)
343{ 373{
344 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 374 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
345 ucontrol->value.integer.value[0] = miro->aci_amp; 375 ucontrol->value.integer.value[0] = miro->aci->aci_amp;
346 376
347 return 0; 377 return 0;
348} 378}
@@ -355,13 +385,14 @@ static int snd_miro_put_amp(struct snd_kcontrol *kcontrol,
355 385
356 value = ucontrol->value.integer.value[0]; 386 value = ucontrol->value.integer.value[0];
357 387
358 if ((error = aci_setvalue(miro, ACI_SET_POWERAMP, value)) < 0) { 388 error = aci_setvalue(miro->aci, ACI_SET_POWERAMP, value);
389 if (error < 0) {
359 snd_printk(KERN_ERR "snd_miro_put_amp() to %d failed: %d\n", value, error); 390 snd_printk(KERN_ERR "snd_miro_put_amp() to %d failed: %d\n", value, error);
360 return error; 391 return error;
361 } 392 }
362 393
363 change = (value != miro->aci_amp); 394 change = (value != miro->aci->aci_amp);
364 miro->aci_amp = value; 395 miro->aci->aci_amp = value;
365 396
366 return change; 397 return change;
367} 398}
@@ -410,12 +441,14 @@ static int snd_miro_get_double(struct snd_kcontrol *kcontrol,
410 int right_reg = kcontrol->private_value & 0xff; 441 int right_reg = kcontrol->private_value & 0xff;
411 int left_reg = right_reg + 1; 442 int left_reg = right_reg + 1;
412 443
413 if ((right_val = aci_getvalue(miro, right_reg)) < 0) { 444 right_val = aci_getvalue(miro->aci, right_reg);
445 if (right_val < 0) {
414 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", right_reg, right_val); 446 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", right_reg, right_val);
415 return right_val; 447 return right_val;
416 } 448 }
417 449
418 if ((left_val = aci_getvalue(miro, left_reg)) < 0) { 450 left_val = aci_getvalue(miro->aci, left_reg);
451 if (left_val < 0) {
419 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", left_reg, left_val); 452 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", left_reg, left_val);
420 return left_val; 453 return left_val;
421 } 454 }
@@ -451,6 +484,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
451 struct snd_ctl_elem_value *ucontrol) 484 struct snd_ctl_elem_value *ucontrol)
452{ 485{
453 struct snd_miro *miro = snd_kcontrol_chip(kcontrol); 486 struct snd_miro *miro = snd_kcontrol_chip(kcontrol);
487 struct snd_miro_aci *aci = miro->aci;
454 int left, right, left_old, right_old; 488 int left, right, left_old, right_old;
455 int setreg_left, setreg_right, getreg_left, getreg_right; 489 int setreg_left, setreg_right, getreg_left, getreg_right;
456 int change, error; 490 int change, error;
@@ -459,21 +493,21 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
459 right = ucontrol->value.integer.value[1]; 493 right = ucontrol->value.integer.value[1];
460 494
461 setreg_right = (kcontrol->private_value >> 8) & 0xff; 495 setreg_right = (kcontrol->private_value >> 8) & 0xff;
462 if (setreg_right == ACI_SET_MASTER) { 496 setreg_left = setreg_right + 8;
463 setreg_left = setreg_right + 1; 497 if (setreg_right == ACI_SET_MASTER)
464 } else { 498 setreg_left -= 7;
465 setreg_left = setreg_right + 8;
466 }
467 499
468 getreg_right = kcontrol->private_value & 0xff; 500 getreg_right = kcontrol->private_value & 0xff;
469 getreg_left = getreg_right + 1; 501 getreg_left = getreg_right + 1;
470 502
471 if ((left_old = aci_getvalue(miro, getreg_left)) < 0) { 503 left_old = aci_getvalue(aci, getreg_left);
504 if (left_old < 0) {
472 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_left, left_old); 505 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_left, left_old);
473 return left_old; 506 return left_old;
474 } 507 }
475 508
476 if ((right_old = aci_getvalue(miro, getreg_right)) < 0) { 509 right_old = aci_getvalue(aci, getreg_right);
510 if (right_old < 0) {
477 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_right, right_old); 511 snd_printk(KERN_ERR "aci_getvalue(%d) failed: %d\n", getreg_right, right_old);
478 return right_old; 512 return right_old;
479 } 513 }
@@ -492,13 +526,15 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
492 right_old = 0x80 - right_old; 526 right_old = 0x80 - right_old;
493 527
494 if (left >= 0) { 528 if (left >= 0) {
495 if ((error = aci_setvalue(miro, setreg_left, left)) < 0) { 529 error = aci_setvalue(aci, setreg_left, left);
530 if (error < 0) {
496 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 531 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
497 left, error); 532 left, error);
498 return error; 533 return error;
499 } 534 }
500 } else { 535 } else {
501 if ((error = aci_setvalue(miro, setreg_left, 0x80 - left)) < 0) { 536 error = aci_setvalue(aci, setreg_left, 0x80 - left);
537 if (error < 0) {
502 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 538 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
503 0x80 - left, error); 539 0x80 - left, error);
504 return error; 540 return error;
@@ -506,13 +542,15 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
506 } 542 }
507 543
508 if (right >= 0) { 544 if (right >= 0) {
509 if ((error = aci_setvalue(miro, setreg_right, right)) < 0) { 545 error = aci_setvalue(aci, setreg_right, right);
546 if (error < 0) {
510 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 547 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
511 right, error); 548 right, error);
512 return error; 549 return error;
513 } 550 }
514 } else { 551 } else {
515 if ((error = aci_setvalue(miro, setreg_right, 0x80 - right)) < 0) { 552 error = aci_setvalue(aci, setreg_right, 0x80 - right);
553 if (error < 0) {
516 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 554 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
517 0x80 - right, error); 555 0x80 - right, error);
518 return error; 556 return error;
@@ -530,12 +568,14 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
530 left_old = 0x20 - left_old; 568 left_old = 0x20 - left_old;
531 right_old = 0x20 - right_old; 569 right_old = 0x20 - right_old;
532 570
533 if ((error = aci_setvalue(miro, setreg_left, 0x20 - left)) < 0) { 571 error = aci_setvalue(aci, setreg_left, 0x20 - left);
572 if (error < 0) {
534 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 573 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
535 0x20 - left, error); 574 0x20 - left, error);
536 return error; 575 return error;
537 } 576 }
538 if ((error = aci_setvalue(miro, setreg_right, 0x20 - right)) < 0) { 577 error = aci_setvalue(aci, setreg_right, 0x20 - right);
578 if (error < 0) {
539 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 579 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
540 0x20 - right, error); 580 0x20 - right, error);
541 return error; 581 return error;
@@ -633,11 +673,13 @@ static unsigned char aci_init_values[][2] __devinitdata = {
633static int __devinit snd_set_aci_init_values(struct snd_miro *miro) 673static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
634{ 674{
635 int idx, error; 675 int idx, error;
676 struct snd_miro_aci *aci = miro->aci;
636 677
637 /* enable WSS on PCM1 */ 678 /* enable WSS on PCM1 */
638 679
639 if ((miro->aci_product == 'A') && wss) { 680 if ((aci->aci_product == 'A') && wss) {
640 if ((error = aci_setvalue(miro, ACI_SET_WSS, wss)) < 0) { 681 error = aci_setvalue(aci, ACI_SET_WSS, wss);
682 if (error < 0) {
641 snd_printk(KERN_ERR "enabling WSS mode failed\n"); 683 snd_printk(KERN_ERR "enabling WSS mode failed\n");
642 return error; 684 return error;
643 } 685 }
@@ -646,7 +688,8 @@ static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
646 /* enable IDE port */ 688 /* enable IDE port */
647 689
648 if (ide) { 690 if (ide) {
649 if ((error = aci_setvalue(miro, ACI_SET_IDE, ide)) < 0) { 691 error = aci_setvalue(aci, ACI_SET_IDE, ide);
692 if (error < 0) {
650 snd_printk(KERN_ERR "enabling IDE port failed\n"); 693 snd_printk(KERN_ERR "enabling IDE port failed\n");
651 return error; 694 return error;
652 } 695 }
@@ -654,32 +697,31 @@ static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
654 697
655 /* set common aci values */ 698 /* set common aci values */
656 699
657 for (idx = 0; idx < ARRAY_SIZE(aci_init_values); idx++) 700 for (idx = 0; idx < ARRAY_SIZE(aci_init_values); idx++) {
658 if ((error = aci_setvalue(miro, aci_init_values[idx][0], 701 error = aci_setvalue(aci, aci_init_values[idx][0],
659 aci_init_values[idx][1])) < 0) { 702 aci_init_values[idx][1]);
703 if (error < 0) {
660 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n", 704 snd_printk(KERN_ERR "aci_setvalue(%d) failed: %d\n",
661 aci_init_values[idx][0], error); 705 aci_init_values[idx][0], error);
662 return error; 706 return error;
663 } 707 }
664 708 }
665 miro->aci_amp = 0; 709 aci->aci_amp = 0;
666 miro->aci_preamp = 0; 710 aci->aci_preamp = 0;
667 miro->aci_solomode = 1; 711 aci->aci_solomode = 1;
668 712
669 return 0; 713 return 0;
670} 714}
671 715
672static int __devinit snd_miro_mixer(struct snd_miro *miro) 716static int __devinit snd_miro_mixer(struct snd_card *card,
717 struct snd_miro *miro)
673{ 718{
674 struct snd_card *card;
675 unsigned int idx; 719 unsigned int idx;
676 int err; 720 int err;
677 721
678 if (snd_BUG_ON(!miro || !miro->card)) 722 if (snd_BUG_ON(!miro || !card))
679 return -EINVAL; 723 return -EINVAL;
680 724
681 card = miro->card;
682
683 switch (miro->hardware) { 725 switch (miro->hardware) {
684 case OPTi9XX_HW_82C924: 726 case OPTi9XX_HW_82C924:
685 strcpy(card->mixername, "ACI & OPTi924"); 727 strcpy(card->mixername, "ACI & OPTi924");
@@ -697,7 +739,8 @@ static int __devinit snd_miro_mixer(struct snd_miro *miro)
697 return err; 739 return err;
698 } 740 }
699 741
700 if ((miro->aci_product == 'A') || (miro->aci_product == 'B')) { 742 if ((miro->aci->aci_product == 'A') ||
743 (miro->aci->aci_product == 'B')) {
701 /* PCM1/PCM12 with power-amp and Line 2 */ 744 /* PCM1/PCM12 with power-amp and Line 2 */
702 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0) 745 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_line_control[0], miro))) < 0)
703 return err; 746 return err;
@@ -705,16 +748,17 @@ static int __devinit snd_miro_mixer(struct snd_miro *miro)
705 return err; 748 return err;
706 } 749 }
707 750
708 if ((miro->aci_product == 'B') || (miro->aci_product == 'C')) { 751 if ((miro->aci->aci_product == 'B') ||
752 (miro->aci->aci_product == 'C')) {
709 /* PCM12/PCM20 with mic-preamp */ 753 /* PCM12/PCM20 with mic-preamp */
710 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0) 754 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_preamp_control[0], miro))) < 0)
711 return err; 755 return err;
712 if (miro->aci_version >= 176) 756 if (miro->aci->aci_version >= 176)
713 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0) 757 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_capture_control[0], miro))) < 0)
714 return err; 758 return err;
715 } 759 }
716 760
717 if (miro->aci_product == 'C') { 761 if (miro->aci->aci_product == 'C') {
718 /* PCM20 with radio and 7 band equalizer */ 762 /* PCM20 with radio and 7 band equalizer */
719 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0) 763 if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_miro_radio_control[0], miro))) < 0)
720 return err; 764 return err;
@@ -757,21 +801,26 @@ static int __devinit snd_miro_init(struct snd_miro *chip,
757 chip->irq = -1; 801 chip->irq = -1;
758 chip->dma1 = -1; 802 chip->dma1 = -1;
759 chip->dma2 = -1; 803 chip->dma2 = -1;
760 chip->fm_port = -1;
761 chip->mpu_port = -1; 804 chip->mpu_port = -1;
762 chip->mpu_irq = -1; 805 chip->mpu_irq = -1;
763 806
807 chip->pwd_reg = 3;
808
809#ifdef CONFIG_PNP
810 if (isapnp && chip->mc_base)
811 /* PnP resource gives the least 10 bits */
812 chip->mc_base |= 0xc00;
813 else
814#endif
815 chip->mc_base = 0xf8c;
816
764 switch (hardware) { 817 switch (hardware) {
765 case OPTi9XX_HW_82C929: 818 case OPTi9XX_HW_82C929:
766 chip->mc_base = 0xf8c;
767 chip->password = 0xe3; 819 chip->password = 0xe3;
768 chip->pwd_reg = 3;
769 break; 820 break;
770 821
771 case OPTi9XX_HW_82C924: 822 case OPTi9XX_HW_82C924:
772 chip->mc_base = 0xf8c;
773 chip->password = 0xe5; 823 chip->password = 0xe5;
774 chip->pwd_reg = 3;
775 break; 824 break;
776 825
777 default: 826 default:
@@ -853,14 +902,15 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
853 struct snd_info_buffer *buffer) 902 struct snd_info_buffer *buffer)
854{ 903{
855 struct snd_miro *miro = (struct snd_miro *) entry->private_data; 904 struct snd_miro *miro = (struct snd_miro *) entry->private_data;
905 struct snd_miro_aci *aci = miro->aci;
856 char* model = "unknown"; 906 char* model = "unknown";
857 907
858 /* miroSOUND PCM1 pro, early PCM12 */ 908 /* miroSOUND PCM1 pro, early PCM12 */
859 909
860 if ((miro->hardware == OPTi9XX_HW_82C929) && 910 if ((miro->hardware == OPTi9XX_HW_82C929) &&
861 (miro->aci_vendor == 'm') && 911 (aci->aci_vendor == 'm') &&
862 (miro->aci_product == 'A')) { 912 (aci->aci_product == 'A')) {
863 switch(miro->aci_version) { 913 switch (aci->aci_version) {
864 case 3: 914 case 3:
865 model = "miroSOUND PCM1 pro"; 915 model = "miroSOUND PCM1 pro";
866 break; 916 break;
@@ -873,9 +923,9 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
873 /* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */ 923 /* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */
874 924
875 if ((miro->hardware == OPTi9XX_HW_82C924) && 925 if ((miro->hardware == OPTi9XX_HW_82C924) &&
876 (miro->aci_vendor == 'm') && 926 (aci->aci_vendor == 'm') &&
877 (miro->aci_product == 'B')) { 927 (aci->aci_product == 'B')) {
878 switch(miro->aci_version) { 928 switch (aci->aci_version) {
879 case 4: 929 case 4:
880 model = "miroSOUND PCM12"; 930 model = "miroSOUND PCM12";
881 break; 931 break;
@@ -891,9 +941,9 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
891 /* miroSOUND PCM20 radio */ 941 /* miroSOUND PCM20 radio */
892 942
893 if ((miro->hardware == OPTi9XX_HW_82C924) && 943 if ((miro->hardware == OPTi9XX_HW_82C924) &&
894 (miro->aci_vendor == 'm') && 944 (aci->aci_vendor == 'm') &&
895 (miro->aci_product == 'C')) { 945 (aci->aci_product == 'C')) {
896 switch(miro->aci_version) { 946 switch (aci->aci_version) {
897 case 7: 947 case 7:
898 model = "miroSOUND PCM20 radio (Rev. E)"; 948 model = "miroSOUND PCM20 radio (Rev. E)";
899 break; 949 break;
@@ -917,17 +967,17 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
917 967
918 snd_iprintf(buffer, "ACI information:\n"); 968 snd_iprintf(buffer, "ACI information:\n");
919 snd_iprintf(buffer, " vendor : "); 969 snd_iprintf(buffer, " vendor : ");
920 switch(miro->aci_vendor) { 970 switch (aci->aci_vendor) {
921 case 'm': 971 case 'm':
922 snd_iprintf(buffer, "Miro\n"); 972 snd_iprintf(buffer, "Miro\n");
923 break; 973 break;
924 default: 974 default:
925 snd_iprintf(buffer, "unknown (0x%x)\n", miro->aci_vendor); 975 snd_iprintf(buffer, "unknown (0x%x)\n", aci->aci_vendor);
926 break; 976 break;
927 } 977 }
928 978
929 snd_iprintf(buffer, " product : "); 979 snd_iprintf(buffer, " product : ");
930 switch(miro->aci_product) { 980 switch (aci->aci_product) {
931 case 'A': 981 case 'A':
932 snd_iprintf(buffer, "miroSOUND PCM1 pro / (early) PCM12\n"); 982 snd_iprintf(buffer, "miroSOUND PCM1 pro / (early) PCM12\n");
933 break; 983 break;
@@ -938,26 +988,27 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
938 snd_iprintf(buffer, "miroSOUND PCM20 radio\n"); 988 snd_iprintf(buffer, "miroSOUND PCM20 radio\n");
939 break; 989 break;
940 default: 990 default:
941 snd_iprintf(buffer, "unknown (0x%x)\n", miro->aci_product); 991 snd_iprintf(buffer, "unknown (0x%x)\n", aci->aci_product);
942 break; 992 break;
943 } 993 }
944 994
945 snd_iprintf(buffer, " firmware: %d (0x%x)\n", 995 snd_iprintf(buffer, " firmware: %d (0x%x)\n",
946 miro->aci_version, miro->aci_version); 996 aci->aci_version, aci->aci_version);
947 snd_iprintf(buffer, " port : 0x%lx-0x%lx\n", 997 snd_iprintf(buffer, " port : 0x%lx-0x%lx\n",
948 miro->aci_port, miro->aci_port+2); 998 aci->aci_port, aci->aci_port+2);
949 snd_iprintf(buffer, " wss : 0x%x\n", wss); 999 snd_iprintf(buffer, " wss : 0x%x\n", wss);
950 snd_iprintf(buffer, " ide : 0x%x\n", ide); 1000 snd_iprintf(buffer, " ide : 0x%x\n", ide);
951 snd_iprintf(buffer, " solomode: 0x%x\n", miro->aci_solomode); 1001 snd_iprintf(buffer, " solomode: 0x%x\n", aci->aci_solomode);
952 snd_iprintf(buffer, " amp : 0x%x\n", miro->aci_amp); 1002 snd_iprintf(buffer, " amp : 0x%x\n", aci->aci_amp);
953 snd_iprintf(buffer, " preamp : 0x%x\n", miro->aci_preamp); 1003 snd_iprintf(buffer, " preamp : 0x%x\n", aci->aci_preamp);
954} 1004}
955 1005
956static void __devinit snd_miro_proc_init(struct snd_miro * miro) 1006static void __devinit snd_miro_proc_init(struct snd_card *card,
1007 struct snd_miro *miro)
957{ 1008{
958 struct snd_info_entry *entry; 1009 struct snd_info_entry *entry;
959 1010
960 if (! snd_card_proc_new(miro->card, "miro", &entry)) 1011 if (!snd_card_proc_new(card, "miro", &entry))
961 snd_info_set_text_ops(entry, miro, snd_miro_proc_read); 1012 snd_info_set_text_ops(entry, miro, snd_miro_proc_read);
962} 1013}
963 1014
@@ -974,37 +1025,40 @@ static int __devinit snd_miro_configure(struct snd_miro *chip)
974 unsigned char mpu_irq_bits; 1025 unsigned char mpu_irq_bits;
975 unsigned long flags; 1026 unsigned long flags;
976 1027
1028 snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
1029 snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
1030 snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
1031
977 switch (chip->hardware) { 1032 switch (chip->hardware) {
978 case OPTi9XX_HW_82C924: 1033 case OPTi9XX_HW_82C924:
979 snd_miro_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02); 1034 snd_miro_write_mask(chip, OPTi9XX_MC_REG(6), 0x02, 0x02);
980 snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
981 snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
982 snd_miro_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff); 1035 snd_miro_write_mask(chip, OPTi9XX_MC_REG(3), 0xf0, 0xff);
983 snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
984 break; 1036 break;
985 case OPTi9XX_HW_82C929: 1037 case OPTi9XX_HW_82C929:
986 /* untested init commands for OPTi929 */ 1038 /* untested init commands for OPTi929 */
987 snd_miro_write_mask(chip, OPTi9XX_MC_REG(1), 0x80, 0x80);
988 snd_miro_write_mask(chip, OPTi9XX_MC_REG(2), 0x20, 0x20); /* OPL4 */
989 snd_miro_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c); 1039 snd_miro_write_mask(chip, OPTi9XX_MC_REG(4), 0x00, 0x0c);
990 snd_miro_write_mask(chip, OPTi9XX_MC_REG(5), 0x02, 0x02);
991 break; 1040 break;
992 default: 1041 default:
993 snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware); 1042 snd_printk(KERN_ERR "chip %d not supported\n", chip->hardware);
994 return -EINVAL; 1043 return -EINVAL;
995 } 1044 }
996 1045
997 switch (chip->wss_base) { 1046 /* PnP resource says it decodes only 10 bits of address */
998 case 0x530: 1047 switch (chip->wss_base & 0x3ff) {
1048 case 0x130:
1049 chip->wss_base = 0x530;
999 wss_base_bits = 0x00; 1050 wss_base_bits = 0x00;
1000 break; 1051 break;
1001 case 0x604: 1052 case 0x204:
1053 chip->wss_base = 0x604;
1002 wss_base_bits = 0x03; 1054 wss_base_bits = 0x03;
1003 break; 1055 break;
1004 case 0xe80: 1056 case 0x280:
1057 chip->wss_base = 0xe80;
1005 wss_base_bits = 0x01; 1058 wss_base_bits = 0x01;
1006 break; 1059 break;
1007 case 0xf40: 1060 case 0x340:
1061 chip->wss_base = 0xf40;
1008 wss_base_bits = 0x02; 1062 wss_base_bits = 0x02;
1009 break; 1063 break;
1010 default: 1064 default:
@@ -1122,75 +1176,92 @@ __skip_mpu:
1122 return 0; 1176 return 0;
1123} 1177}
1124 1178
1179static int __devinit snd_miro_opti_check(struct snd_miro *chip)
1180{
1181 unsigned char value;
1182
1183 chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
1184 "OPTi9xx MC");
1185 if (chip->res_mc_base == NULL)
1186 return -ENOMEM;
1187
1188 value = snd_miro_read(chip, OPTi9XX_MC_REG(1));
1189 if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
1190 if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1)))
1191 return 0;
1192
1193 release_and_free_resource(chip->res_mc_base);
1194 chip->res_mc_base = NULL;
1195
1196 return -ENODEV;
1197}
1198
1125static int __devinit snd_card_miro_detect(struct snd_card *card, 1199static int __devinit snd_card_miro_detect(struct snd_card *card,
1126 struct snd_miro *chip) 1200 struct snd_miro *chip)
1127{ 1201{
1128 int i, err; 1202 int i, err;
1129 unsigned char value;
1130 1203
1131 for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) { 1204 for (i = OPTi9XX_HW_82C929; i <= OPTi9XX_HW_82C924; i++) {
1132 1205
1133 if ((err = snd_miro_init(chip, i)) < 0) 1206 if ((err = snd_miro_init(chip, i)) < 0)
1134 return err; 1207 return err;
1135 1208
1136 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) 1209 err = snd_miro_opti_check(chip);
1137 continue; 1210 if (err == 0)
1138 1211 return 1;
1139 value = snd_miro_read(chip, OPTi9XX_MC_REG(1));
1140 if ((value != 0xff) && (value != inb(chip->mc_base + 1)))
1141 if (value == snd_miro_read(chip, OPTi9XX_MC_REG(1)))
1142 return 1;
1143
1144 release_and_free_resource(chip->res_mc_base);
1145 chip->res_mc_base = NULL;
1146
1147 } 1212 }
1148 1213
1149 return -ENODEV; 1214 return -ENODEV;
1150} 1215}
1151 1216
1152static int __devinit snd_card_miro_aci_detect(struct snd_card *card, 1217static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
1153 struct snd_miro * miro) 1218 struct snd_miro *miro)
1154{ 1219{
1155 unsigned char regval; 1220 unsigned char regval;
1156 int i; 1221 int i;
1222 struct snd_miro_aci *aci = &aci_device;
1223
1224 miro->aci = aci;
1157 1225
1158 mutex_init(&miro->aci_mutex); 1226 mutex_init(&aci->aci_mutex);
1159 1227
1160 /* get ACI port from OPTi9xx MC 4 */ 1228 /* get ACI port from OPTi9xx MC 4 */
1161 1229
1162 miro->mc_base = 0xf8c;
1163 regval=inb(miro->mc_base + 4); 1230 regval=inb(miro->mc_base + 4);
1164 miro->aci_port = (regval & 0x10) ? 0x344: 0x354; 1231 aci->aci_port = (regval & 0x10) ? 0x344 : 0x354;
1165 1232
1166 if ((miro->res_aci_port = request_region(miro->aci_port, 3, "miro aci")) == NULL) { 1233 miro->res_aci_port = request_region(aci->aci_port, 3, "miro aci");
1234 if (miro->res_aci_port == NULL) {
1167 snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n", 1235 snd_printk(KERN_ERR "aci i/o area 0x%lx-0x%lx already used.\n",
1168 miro->aci_port, miro->aci_port+2); 1236 aci->aci_port, aci->aci_port+2);
1169 return -ENOMEM; 1237 return -ENOMEM;
1170 } 1238 }
1171 1239
1172 /* force ACI into a known state */ 1240 /* force ACI into a known state */
1173 for (i = 0; i < 3; i++) 1241 for (i = 0; i < 3; i++)
1174 if (aci_cmd(miro, ACI_ERROR_OP, -1, -1) < 0) { 1242 if (snd_aci_cmd(aci, ACI_ERROR_OP, -1, -1) < 0) {
1175 snd_printk(KERN_ERR "can't force aci into known state.\n"); 1243 snd_printk(KERN_ERR "can't force aci into known state.\n");
1176 return -ENXIO; 1244 return -ENXIO;
1177 } 1245 }
1178 1246
1179 if ((miro->aci_vendor=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0 || 1247 aci->aci_vendor = snd_aci_cmd(aci, ACI_READ_IDCODE, -1, -1);
1180 (miro->aci_product=aci_cmd(miro, ACI_READ_IDCODE, -1, -1)) < 0) { 1248 aci->aci_product = snd_aci_cmd(aci, ACI_READ_IDCODE, -1, -1);
1181 snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n", miro->aci_port); 1249 if (aci->aci_vendor < 0 || aci->aci_product < 0) {
1250 snd_printk(KERN_ERR "can't read aci id on 0x%lx.\n",
1251 aci->aci_port);
1182 return -ENXIO; 1252 return -ENXIO;
1183 } 1253 }
1184 1254
1185 if ((miro->aci_version=aci_cmd(miro, ACI_READ_VERSION, -1, -1)) < 0) { 1255 aci->aci_version = snd_aci_cmd(aci, ACI_READ_VERSION, -1, -1);
1256 if (aci->aci_version < 0) {
1186 snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n", 1257 snd_printk(KERN_ERR "can't read aci version on 0x%lx.\n",
1187 miro->aci_port); 1258 aci->aci_port);
1188 return -ENXIO; 1259 return -ENXIO;
1189 } 1260 }
1190 1261
1191 if (aci_cmd(miro, ACI_INIT, -1, -1) < 0 || 1262 if (snd_aci_cmd(aci, ACI_INIT, -1, -1) < 0 ||
1192 aci_cmd(miro, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0 || 1263 snd_aci_cmd(aci, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0 ||
1193 aci_cmd(miro, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0) { 1264 snd_aci_cmd(aci, ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP) < 0) {
1194 snd_printk(KERN_ERR "can't initialize aci.\n"); 1265 snd_printk(KERN_ERR "can't initialize aci.\n");
1195 return -ENXIO; 1266 return -ENXIO;
1196 } 1267 }
@@ -1201,157 +1272,80 @@ static int __devinit snd_card_miro_aci_detect(struct snd_card *card,
1201static void snd_card_miro_free(struct snd_card *card) 1272static void snd_card_miro_free(struct snd_card *card)
1202{ 1273{
1203 struct snd_miro *miro = card->private_data; 1274 struct snd_miro *miro = card->private_data;
1204 1275
1205 release_and_free_resource(miro->res_aci_port); 1276 release_and_free_resource(miro->res_aci_port);
1277 if (miro->aci)
1278 miro->aci->aci_port = 0;
1206 release_and_free_resource(miro->res_mc_base); 1279 release_and_free_resource(miro->res_mc_base);
1207} 1280}
1208 1281
1209static int __devinit snd_miro_match(struct device *devptr, unsigned int n) 1282static int __devinit snd_miro_probe(struct snd_card *card)
1210{
1211 return 1;
1212}
1213
1214static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1215{ 1283{
1216 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
1217 static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
1218 static int possible_irqs[] = {11, 9, 10, 7, -1};
1219 static int possible_mpu_irqs[] = {10, 5, 9, 7, -1};
1220 static int possible_dma1s[] = {3, 1, 0, -1};
1221 static int possible_dma2s[][2] = {{1,-1}, {0,-1}, {-1,-1}, {0,-1}};
1222
1223 int error; 1284 int error;
1224 struct snd_miro *miro; 1285 struct snd_miro *miro = card->private_data;
1225 struct snd_wss *codec; 1286 struct snd_wss *codec;
1226 struct snd_timer *timer; 1287 struct snd_timer *timer;
1227 struct snd_card *card;
1228 struct snd_pcm *pcm; 1288 struct snd_pcm *pcm;
1229 struct snd_rawmidi *rmidi; 1289 struct snd_rawmidi *rmidi;
1230 1290
1231 error = snd_card_create(index, id, THIS_MODULE, 1291 if (!miro->res_mc_base) {
1232 sizeof(struct snd_miro), &card); 1292 miro->res_mc_base = request_region(miro->mc_base,
1233 if (error < 0) 1293 miro->mc_base_size,
1234 return error; 1294 "miro (OPTi9xx MC)");
1235 1295 if (miro->res_mc_base == NULL) {
1236 card->private_free = snd_card_miro_free; 1296 snd_printk(KERN_ERR "request for OPTI9xx MC failed\n");
1237 miro = card->private_data; 1297 return -ENOMEM;
1238 miro->card = card; 1298 }
1239
1240 if ((error = snd_card_miro_aci_detect(card, miro)) < 0) {
1241 snd_card_free(card);
1242 snd_printk(KERN_ERR "unable to detect aci chip\n");
1243 return -ENODEV;
1244 } 1299 }
1245 1300
1246 /* init proc interface */ 1301 error = snd_card_miro_aci_detect(card, miro);
1247 snd_miro_proc_init(miro); 1302 if (error < 0) {
1248
1249 if ((error = snd_card_miro_detect(card, miro)) < 0) {
1250 snd_card_free(card); 1303 snd_card_free(card);
1251 snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n"); 1304 snd_printk(KERN_ERR "unable to detect aci chip\n");
1252 return -ENODEV; 1305 return -ENODEV;
1253 } 1306 }
1254 1307
1255 if (! miro->res_mc_base &&
1256 (miro->res_mc_base = request_region(miro->mc_base, miro->mc_base_size,
1257 "miro (OPTi9xx MC)")) == NULL) {
1258 snd_card_free(card);
1259 snd_printk(KERN_ERR "request for OPTI9xx MC failed\n");
1260 return -ENOMEM;
1261 }
1262
1263 miro->wss_base = port; 1308 miro->wss_base = port;
1264 miro->fm_port = fm_port;
1265 miro->mpu_port = mpu_port; 1309 miro->mpu_port = mpu_port;
1266 miro->irq = irq; 1310 miro->irq = irq;
1267 miro->mpu_irq = mpu_irq; 1311 miro->mpu_irq = mpu_irq;
1268 miro->dma1 = dma1; 1312 miro->dma1 = dma1;
1269 miro->dma2 = dma2; 1313 miro->dma2 = dma2;
1270 1314
1271 if (miro->wss_base == SNDRV_AUTO_PORT) { 1315 /* init proc interface */
1272 if ((miro->wss_base = snd_legacy_find_free_ioport(possible_ports, 4)) < 0) { 1316 snd_miro_proc_init(card, miro);
1273 snd_card_free(card);
1274 snd_printk(KERN_ERR "unable to find a free WSS port\n");
1275 return -EBUSY;
1276 }
1277 }
1278
1279 if (miro->mpu_port == SNDRV_AUTO_PORT) {
1280 if ((miro->mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2)) < 0) {
1281 snd_card_free(card);
1282 snd_printk(KERN_ERR "unable to find a free MPU401 port\n");
1283 return -EBUSY;
1284 }
1285 }
1286 if (miro->irq == SNDRV_AUTO_IRQ) {
1287 if ((miro->irq = snd_legacy_find_free_irq(possible_irqs)) < 0) {
1288 snd_card_free(card);
1289 snd_printk(KERN_ERR "unable to find a free IRQ\n");
1290 return -EBUSY;
1291 }
1292 }
1293 if (miro->mpu_irq == SNDRV_AUTO_IRQ) {
1294 if ((miro->mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs)) < 0) {
1295 snd_card_free(card);
1296 snd_printk(KERN_ERR "unable to find a free MPU401 IRQ\n");
1297 return -EBUSY;
1298 }
1299 }
1300 if (miro->dma1 == SNDRV_AUTO_DMA) {
1301 if ((miro->dma1 = snd_legacy_find_free_dma(possible_dma1s)) < 0) {
1302 snd_card_free(card);
1303 snd_printk(KERN_ERR "unable to find a free DMA1\n");
1304 return -EBUSY;
1305 }
1306 }
1307 if (miro->dma2 == SNDRV_AUTO_DMA) {
1308 if ((miro->dma2 = snd_legacy_find_free_dma(possible_dma2s[miro->dma1 % 4])) < 0) {
1309 snd_card_free(card);
1310 snd_printk(KERN_ERR "unable to find a free DMA2\n");
1311 return -EBUSY;
1312 }
1313 }
1314 1317
1315 error = snd_miro_configure(miro); 1318 error = snd_miro_configure(miro);
1316 if (error) { 1319 if (error)
1317 snd_card_free(card);
1318 return error; 1320 return error;
1319 }
1320 1321
1321 error = snd_wss_create(card, miro->wss_base + 4, -1, 1322 error = snd_wss_create(card, miro->wss_base + 4, -1,
1322 miro->irq, miro->dma1, miro->dma2, 1323 miro->irq, miro->dma1, miro->dma2,
1323 WSS_HW_AD1845, 0, &codec); 1324 WSS_HW_DETECT, 0, &codec);
1324 if (error < 0) { 1325 if (error < 0)
1325 snd_card_free(card);
1326 return error; 1326 return error;
1327 }
1328 1327
1329 error = snd_wss_pcm(codec, 0, &pcm); 1328 error = snd_wss_pcm(codec, 0, &pcm);
1330 if (error < 0) { 1329 if (error < 0)
1331 snd_card_free(card);
1332 return error; 1330 return error;
1333 } 1331
1334 error = snd_wss_mixer(codec); 1332 error = snd_wss_mixer(codec);
1335 if (error < 0) { 1333 if (error < 0)
1336 snd_card_free(card);
1337 return error; 1334 return error;
1338 } 1335
1339 error = snd_wss_timer(codec, 0, &timer); 1336 error = snd_wss_timer(codec, 0, &timer);
1340 if (error < 0) { 1337 if (error < 0)
1341 snd_card_free(card);
1342 return error; 1338 return error;
1343 }
1344 1339
1345 miro->pcm = pcm; 1340 miro->pcm = pcm;
1346 1341
1347 if ((error = snd_miro_mixer(miro)) < 0) { 1342 error = snd_miro_mixer(card, miro);
1348 snd_card_free(card); 1343 if (error < 0)
1349 return error; 1344 return error;
1350 }
1351 1345
1352 if (miro->aci_vendor == 'm') { 1346 if (miro->aci->aci_vendor == 'm') {
1353 /* It looks like a miro sound card. */ 1347 /* It looks like a miro sound card. */
1354 switch (miro->aci_product) { 1348 switch (miro->aci->aci_product) {
1355 case 'A': 1349 case 'A':
1356 sprintf(card->shortname, 1350 sprintf(card->shortname,
1357 "miroSOUND PCM1 pro / PCM12"); 1351 "miroSOUND PCM1 pro / PCM12");
@@ -1380,30 +1374,131 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1380 card->shortname, miro->name, pcm->name, miro->wss_base + 4, 1374 card->shortname, miro->name, pcm->name, miro->wss_base + 4,
1381 miro->irq, miro->dma1, miro->dma2); 1375 miro->irq, miro->dma1, miro->dma2);
1382 1376
1383 if (miro->mpu_port <= 0 || miro->mpu_port == SNDRV_AUTO_PORT) 1377 if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
1384 rmidi = NULL; 1378 rmidi = NULL;
1385 else 1379 else {
1386 if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 1380 error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
1387 miro->mpu_port, 0, miro->mpu_irq, IRQF_DISABLED, 1381 mpu_port, 0, miro->mpu_irq, IRQF_DISABLED,
1388 &rmidi))) 1382 &rmidi);
1389 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", miro->mpu_port); 1383 if (error < 0)
1384 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
1385 mpu_port);
1386 }
1390 1387
1391 if (miro->fm_port > 0 && miro->fm_port != SNDRV_AUTO_PORT) { 1388 if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
1392 struct snd_opl3 *opl3 = NULL; 1389 struct snd_opl3 *opl3 = NULL;
1393 struct snd_opl4 *opl4; 1390 struct snd_opl4 *opl4;
1394 if (snd_opl4_create(card, miro->fm_port, miro->fm_port - 8, 1391
1392 if (snd_opl4_create(card, fm_port, fm_port - 8,
1395 2, &opl3, &opl4) < 0) 1393 2, &opl3, &opl4) < 0)
1396 snd_printk(KERN_WARNING "no OPL4 device at 0x%lx\n", miro->fm_port); 1394 snd_printk(KERN_WARNING "no OPL4 device at 0x%lx\n",
1395 fm_port);
1397 } 1396 }
1398 1397
1399 if ((error = snd_set_aci_init_values(miro)) < 0) { 1398 error = snd_set_aci_init_values(miro);
1400 snd_card_free(card); 1399 if (error < 0)
1401 return error; 1400 return error;
1401
1402 return snd_card_register(card);
1403}
1404
1405static int __devinit snd_miro_isa_match(struct device *devptr, unsigned int n)
1406{
1407#ifdef CONFIG_PNP
1408 if (snd_miro_pnp_is_probed)
1409 return 0;
1410 if (isapnp)
1411 return 0;
1412#endif
1413 return 1;
1414}
1415
1416static int __devinit snd_miro_isa_probe(struct device *devptr, unsigned int n)
1417{
1418 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
1419 static long possible_mpu_ports[] = {0x330, 0x300, 0x310, 0x320, -1};
1420 static int possible_irqs[] = {11, 9, 10, 7, -1};
1421 static int possible_mpu_irqs[] = {10, 5, 9, 7, -1};
1422 static int possible_dma1s[] = {3, 1, 0, -1};
1423 static int possible_dma2s[][2] = { {1, -1}, {0, -1}, {-1, -1},
1424 {0, -1} };
1425
1426 int error;
1427 struct snd_miro *miro;
1428 struct snd_card *card;
1429
1430 error = snd_card_create(index, id, THIS_MODULE,
1431 sizeof(struct snd_miro), &card);
1432 if (error < 0)
1433 return error;
1434
1435 card->private_free = snd_card_miro_free;
1436 miro = card->private_data;
1437
1438 error = snd_card_miro_detect(card, miro);
1439 if (error < 0) {
1440 snd_card_free(card);
1441 snd_printk(KERN_ERR "unable to detect OPTi9xx chip\n");
1442 return -ENODEV;
1443 }
1444
1445 if (port == SNDRV_AUTO_PORT) {
1446 port = snd_legacy_find_free_ioport(possible_ports, 4);
1447 if (port < 0) {
1448 snd_card_free(card);
1449 snd_printk(KERN_ERR "unable to find a free WSS port\n");
1450 return -EBUSY;
1451 }
1452 }
1453
1454 if (mpu_port == SNDRV_AUTO_PORT) {
1455 mpu_port = snd_legacy_find_free_ioport(possible_mpu_ports, 2);
1456 if (mpu_port < 0) {
1457 snd_card_free(card);
1458 snd_printk(KERN_ERR
1459 "unable to find a free MPU401 port\n");
1460 return -EBUSY;
1461 }
1462 }
1463
1464 if (irq == SNDRV_AUTO_IRQ) {
1465 irq = snd_legacy_find_free_irq(possible_irqs);
1466 if (irq < 0) {
1467 snd_card_free(card);
1468 snd_printk(KERN_ERR "unable to find a free IRQ\n");
1469 return -EBUSY;
1470 }
1471 }
1472 if (mpu_irq == SNDRV_AUTO_IRQ) {
1473 mpu_irq = snd_legacy_find_free_irq(possible_mpu_irqs);
1474 if (mpu_irq < 0) {
1475 snd_card_free(card);
1476 snd_printk(KERN_ERR
1477 "unable to find a free MPU401 IRQ\n");
1478 return -EBUSY;
1479 }
1480 }
1481 if (dma1 == SNDRV_AUTO_DMA) {
1482 dma1 = snd_legacy_find_free_dma(possible_dma1s);
1483 if (dma1 < 0) {
1484 snd_card_free(card);
1485 snd_printk(KERN_ERR "unable to find a free DMA1\n");
1486 return -EBUSY;
1487 }
1488 }
1489 if (dma2 == SNDRV_AUTO_DMA) {
1490 dma2 = snd_legacy_find_free_dma(possible_dma2s[dma1 % 4]);
1491 if (dma2 < 0) {
1492 snd_card_free(card);
1493 snd_printk(KERN_ERR "unable to find a free DMA2\n");
1494 return -EBUSY;
1495 }
1402 } 1496 }
1403 1497
1404 snd_card_set_dev(card, devptr); 1498 snd_card_set_dev(card, devptr);
1405 1499
1406 if ((error = snd_card_register(card))) { 1500 error = snd_miro_probe(card);
1501 if (error < 0) {
1407 snd_card_free(card); 1502 snd_card_free(card);
1408 return error; 1503 return error;
1409 } 1504 }
@@ -1412,7 +1507,8 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
1412 return 0; 1507 return 0;
1413} 1508}
1414 1509
1415static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev) 1510static int __devexit snd_miro_isa_remove(struct device *devptr,
1511 unsigned int dev)
1416{ 1512{
1417 snd_card_free(dev_get_drvdata(devptr)); 1513 snd_card_free(dev_get_drvdata(devptr));
1418 dev_set_drvdata(devptr, NULL); 1514 dev_set_drvdata(devptr, NULL);
@@ -1422,23 +1518,164 @@ static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev)
1422#define DEV_NAME "miro" 1518#define DEV_NAME "miro"
1423 1519
1424static struct isa_driver snd_miro_driver = { 1520static struct isa_driver snd_miro_driver = {
1425 .match = snd_miro_match, 1521 .match = snd_miro_isa_match,
1426 .probe = snd_miro_probe, 1522 .probe = snd_miro_isa_probe,
1427 .remove = __devexit_p(snd_miro_remove), 1523 .remove = __devexit_p(snd_miro_isa_remove),
1428 /* FIXME: suspend/resume */ 1524 /* FIXME: suspend/resume */
1429 .driver = { 1525 .driver = {
1430 .name = DEV_NAME 1526 .name = DEV_NAME
1431 }, 1527 },
1432}; 1528};
1433 1529
1530#ifdef CONFIG_PNP
1531
1532static int __devinit snd_card_miro_pnp(struct snd_miro *chip,
1533 struct pnp_card_link *card,
1534 const struct pnp_card_device_id *pid)
1535{
1536 struct pnp_dev *pdev;
1537 int err;
1538 struct pnp_dev *devmpu;
1539 struct pnp_dev *devmc;
1540
1541 pdev = pnp_request_card_device(card, pid->devs[0].id, NULL);
1542 if (pdev == NULL)
1543 return -EBUSY;
1544
1545 devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
1546 if (devmpu == NULL)
1547 return -EBUSY;
1548
1549 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
1550 if (devmc == NULL)
1551 return -EBUSY;
1552
1553 err = pnp_activate_dev(pdev);
1554 if (err < 0) {
1555 snd_printk(KERN_ERR "AUDIO pnp configure failure: %d\n", err);
1556 return err;
1557 }
1558
1559 err = pnp_activate_dev(devmc);
1560 if (err < 0) {
1561 snd_printk(KERN_ERR "OPL syntg pnp configure failure: %d\n",
1562 err);
1563 return err;
1564 }
1565
1566 port = pnp_port_start(pdev, 1);
1567 fm_port = pnp_port_start(pdev, 2) + 8;
1568
1569 /*
1570 * The MC(0) is never accessed and the miroSOUND PCM20 card does not
1571 * include it in the PnP resource range. OPTI93x include it.
1572 */
1573 chip->mc_base = pnp_port_start(devmc, 0) - 1;
1574 chip->mc_base_size = pnp_port_len(devmc, 0) + 1;
1575
1576 irq = pnp_irq(pdev, 0);
1577 dma1 = pnp_dma(pdev, 0);
1578 dma2 = pnp_dma(pdev, 1);
1579
1580 if (mpu_port > 0) {
1581 err = pnp_activate_dev(devmpu);
1582 if (err < 0) {
1583 snd_printk(KERN_ERR "MPU401 pnp configure failure\n");
1584 mpu_port = -1;
1585 return err;
1586 }
1587 mpu_port = pnp_port_start(devmpu, 0);
1588 mpu_irq = pnp_irq(devmpu, 0);
1589 }
1590 return 0;
1591}
1592
1593static int __devinit snd_miro_pnp_probe(struct pnp_card_link *pcard,
1594 const struct pnp_card_device_id *pid)
1595{
1596 struct snd_card *card;
1597 int err;
1598 struct snd_miro *miro;
1599
1600 if (snd_miro_pnp_is_probed)
1601 return -EBUSY;
1602 if (!isapnp)
1603 return -ENODEV;
1604 err = snd_card_create(index, id, THIS_MODULE,
1605 sizeof(struct snd_miro), &card);
1606 if (err < 0)
1607 return err;
1608
1609 card->private_free = snd_card_miro_free;
1610 miro = card->private_data;
1611
1612 err = snd_card_miro_pnp(miro, pcard, pid);
1613 if (err) {
1614 snd_card_free(card);
1615 return err;
1616 }
1617
1618 /* only miroSOUND PCM20 and PCM12 == OPTi924 */
1619 err = snd_miro_init(miro, OPTi9XX_HW_82C924);
1620 if (err) {
1621 snd_card_free(card);
1622 return err;
1623 }
1624
1625 err = snd_miro_opti_check(miro);
1626 if (err) {
1627 snd_printk(KERN_ERR "OPTI chip not found\n");
1628 snd_card_free(card);
1629 return err;
1630 }
1631
1632 snd_card_set_dev(card, &pcard->card->dev);
1633 err = snd_miro_probe(card);
1634 if (err < 0) {
1635 snd_card_free(card);
1636 return err;
1637 }
1638 pnp_set_card_drvdata(pcard, card);
1639 snd_miro_pnp_is_probed = 1;
1640 return 0;
1641}
1642
1643static void __devexit snd_miro_pnp_remove(struct pnp_card_link * pcard)
1644{
1645 snd_card_free(pnp_get_card_drvdata(pcard));
1646 pnp_set_card_drvdata(pcard, NULL);
1647 snd_miro_pnp_is_probed = 0;
1648}
1649
1650static struct pnp_card_driver miro_pnpc_driver = {
1651 .flags = PNP_DRIVER_RES_DISABLE,
1652 .name = "miro",
1653 .id_table = snd_miro_pnpids,
1654 .probe = snd_miro_pnp_probe,
1655 .remove = __devexit_p(snd_miro_pnp_remove),
1656};
1657#endif
1658
1434static int __init alsa_card_miro_init(void) 1659static int __init alsa_card_miro_init(void)
1435{ 1660{
1661#ifdef CONFIG_PNP
1662 pnp_register_card_driver(&miro_pnpc_driver);
1663 if (snd_miro_pnp_is_probed)
1664 return 0;
1665 pnp_unregister_card_driver(&miro_pnpc_driver);
1666#endif
1436 return isa_register_driver(&snd_miro_driver, 1); 1667 return isa_register_driver(&snd_miro_driver, 1);
1437} 1668}
1438 1669
1439static void __exit alsa_card_miro_exit(void) 1670static void __exit alsa_card_miro_exit(void)
1440{ 1671{
1441 isa_unregister_driver(&snd_miro_driver); 1672 if (!snd_miro_pnp_is_probed) {
1673 isa_unregister_driver(&snd_miro_driver);
1674 return;
1675 }
1676#ifdef CONFIG_PNP
1677 pnp_unregister_card_driver(&miro_pnpc_driver);
1678#endif
1442} 1679}
1443 1680
1444module_init(alsa_card_miro_init) 1681module_init(alsa_card_miro_init)
diff --git a/sound/isa/opti9xx/miro.h b/sound/isa/opti9xx/miro.h
deleted file mode 100644
index 6e1385b8e07e..000000000000
--- a/sound/isa/opti9xx/miro.h
+++ /dev/null
@@ -1,73 +0,0 @@
1#ifndef _MIRO_H_
2#define _MIRO_H_
3
4#define ACI_REG_COMMAND 0 /* write register offset */
5#define ACI_REG_STATUS 1 /* read register offset */
6#define ACI_REG_BUSY 2 /* busy register offset */
7#define ACI_REG_RDS 2 /* PCM20: RDS register offset */
8#define ACI_MINTIME 500 /* ACI time out limit */
9
10#define ACI_SET_MUTE 0x0d
11#define ACI_SET_POWERAMP 0x0f
12#define ACI_SET_TUNERMUTE 0xa3
13#define ACI_SET_TUNERMONO 0xa4
14#define ACI_SET_IDE 0xd0
15#define ACI_SET_WSS 0xd1
16#define ACI_SET_SOLOMODE 0xd2
17#define ACI_SET_PREAMP 0x03
18#define ACI_GET_PREAMP 0x21
19#define ACI_WRITE_TUNE 0xa7
20#define ACI_READ_TUNERSTEREO 0xa8
21#define ACI_READ_TUNERSTATION 0xa9
22#define ACI_READ_VERSION 0xf1
23#define ACI_READ_IDCODE 0xf2
24#define ACI_INIT 0xff
25#define ACI_STATUS 0xf0
26#define ACI_S_GENERAL 0x00
27#define ACI_ERROR_OP 0xdf
28
29/* ACI Mixer */
30
31/* These are the values for the right channel GET registers.
32 Add an offset of 0x01 for the left channel register.
33 (left=right+0x01) */
34
35#define ACI_GET_MASTER 0x03
36#define ACI_GET_MIC 0x05
37#define ACI_GET_LINE 0x07
38#define ACI_GET_CD 0x09
39#define ACI_GET_SYNTH 0x0b
40#define ACI_GET_PCM 0x0d
41#define ACI_GET_LINE1 0x10 /* Radio on PCM20 */
42#define ACI_GET_LINE2 0x12
43
44#define ACI_GET_EQ1 0x22 /* from Bass ... */
45#define ACI_GET_EQ2 0x24
46#define ACI_GET_EQ3 0x26
47#define ACI_GET_EQ4 0x28
48#define ACI_GET_EQ5 0x2a
49#define ACI_GET_EQ6 0x2c
50#define ACI_GET_EQ7 0x2e /* ... to Treble */
51
52/* And these are the values for the right channel SET registers.
53 For left channel access you have to add an offset of 0x08.
54 MASTER is an exception, which needs an offset of 0x01 */
55
56#define ACI_SET_MASTER 0x00
57#define ACI_SET_MIC 0x30
58#define ACI_SET_LINE 0x31
59#define ACI_SET_CD 0x34
60#define ACI_SET_SYNTH 0x33
61#define ACI_SET_PCM 0x32
62#define ACI_SET_LINE1 0x35 /* Radio on PCM20 */
63#define ACI_SET_LINE2 0x36
64
65#define ACI_SET_EQ1 0x40 /* from Bass ... */
66#define ACI_SET_EQ2 0x41
67#define ACI_SET_EQ3 0x42
68#define ACI_SET_EQ4 0x43
69#define ACI_SET_EQ5 0x44
70#define ACI_SET_EQ6 0x45
71#define ACI_SET_EQ7 0x46 /* ... to Treble */
72
73#endif /* _MIRO_H_ */
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index 5cd555325b9d..c8a8da0d4036 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -135,21 +135,15 @@ struct snd_opti9xx {
135 unsigned long mc_base_size; 135 unsigned long mc_base_size;
136#ifdef OPTi93X 136#ifdef OPTi93X
137 unsigned long mc_indir_index; 137 unsigned long mc_indir_index;
138 unsigned long mc_indir_size;
139 struct resource *res_mc_indir;
138 struct snd_wss *codec; 140 struct snd_wss *codec;
139#endif /* OPTi93X */ 141#endif /* OPTi93X */
140 unsigned long pwd_reg; 142 unsigned long pwd_reg;
141 143
142 spinlock_t lock; 144 spinlock_t lock;
143 145
144 long wss_base;
145 int irq; 146 int irq;
146 int dma1;
147 int dma2;
148
149 long fm_port;
150
151 long mpu_port;
152 int mpu_irq;
153 147
154#ifdef CONFIG_PNP 148#ifdef CONFIG_PNP
155 struct pnp_dev *dev; 149 struct pnp_dev *dev;
@@ -185,7 +179,7 @@ MODULE_DEVICE_TABLE(pnp_card, snd_opti9xx_pnpids);
185#endif 179#endif
186 180
187static char * snd_opti9xx_names[] = { 181static char * snd_opti9xx_names[] = {
188 "unkown", 182 "unknown",
189 "82C928", "82C929", 183 "82C928", "82C929",
190 "82C924", "82C925", 184 "82C924", "82C925",
191 "82C930", "82C931", "82C933" 185 "82C930", "82C931", "82C933"
@@ -216,13 +210,7 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
216 210
217 spin_lock_init(&chip->lock); 211 spin_lock_init(&chip->lock);
218 212
219 chip->wss_base = -1;
220 chip->irq = -1; 213 chip->irq = -1;
221 chip->dma1 = -1;
222 chip->dma2 = -1;
223 chip->fm_port = -1;
224 chip->mpu_port = -1;
225 chip->mpu_irq = -1;
226 214
227 switch (hardware) { 215 switch (hardware) {
228#ifndef OPTi93X 216#ifndef OPTi93X
@@ -245,7 +233,10 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
245 case OPTi9XX_HW_82C931: 233 case OPTi9XX_HW_82C931:
246 case OPTi9XX_HW_82C933: 234 case OPTi9XX_HW_82C933:
247 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; 235 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
248 chip->mc_indir_index = 0xe0e; 236 if (!chip->mc_indir_index) {
237 chip->mc_indir_index = 0xe0e;
238 chip->mc_indir_size = 2;
239 }
249 chip->password = 0xe4; 240 chip->password = 0xe4;
250 chip->pwd_reg = 0; 241 chip->pwd_reg = 0;
251 break; 242 break;
@@ -348,7 +339,10 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
348 (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) 339 (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
349 340
350 341
351static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip) 342static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
343 long wss_base,
344 int irq, int dma1, int dma2,
345 long mpu_port, int mpu_irq)
352{ 346{
353 unsigned char wss_base_bits; 347 unsigned char wss_base_bits;
354 unsigned char irq_bits; 348 unsigned char irq_bits;
@@ -416,7 +410,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
416 return -EINVAL; 410 return -EINVAL;
417 } 411 }
418 412
419 switch (chip->wss_base) { 413 switch (wss_base) {
420 case 0x530: 414 case 0x530:
421 wss_base_bits = 0x00; 415 wss_base_bits = 0x00;
422 break; 416 break;
@@ -430,14 +424,13 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
430 wss_base_bits = 0x02; 424 wss_base_bits = 0x02;
431 break; 425 break;
432 default: 426 default:
433 snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", 427 snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base);
434 chip->wss_base);
435 goto __skip_base; 428 goto __skip_base;
436 } 429 }
437 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30); 430 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
438 431
439__skip_base: 432__skip_base:
440 switch (chip->irq) { 433 switch (irq) {
441//#ifdef OPTi93X 434//#ifdef OPTi93X
442 case 5: 435 case 5:
443 irq_bits = 0x05; 436 irq_bits = 0x05;
@@ -456,11 +449,11 @@ __skip_base:
456 irq_bits = 0x04; 449 irq_bits = 0x04;
457 break; 450 break;
458 default: 451 default:
459 snd_printk(KERN_WARNING "WSS irq # %d not valid\n", chip->irq); 452 snd_printk(KERN_WARNING "WSS irq # %d not valid\n", irq);
460 goto __skip_resources; 453 goto __skip_resources;
461 } 454 }
462 455
463 switch (chip->dma1) { 456 switch (dma1) {
464 case 0: 457 case 0:
465 dma_bits = 0x01; 458 dma_bits = 0x01;
466 break; 459 break;
@@ -471,38 +464,36 @@ __skip_base:
471 dma_bits = 0x03; 464 dma_bits = 0x03;
472 break; 465 break;
473 default: 466 default:
474 snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", 467 snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", dma1);
475 chip->dma1);
476 goto __skip_resources; 468 goto __skip_resources;
477 } 469 }
478 470
479#if defined(CS4231) || defined(OPTi93X) 471#if defined(CS4231) || defined(OPTi93X)
480 if (chip->dma1 == chip->dma2) { 472 if (dma1 == dma2) {
481 snd_printk(KERN_ERR "don't want to share dmas\n"); 473 snd_printk(KERN_ERR "don't want to share dmas\n");
482 return -EBUSY; 474 return -EBUSY;
483 } 475 }
484 476
485 switch (chip->dma2) { 477 switch (dma2) {
486 case 0: 478 case 0:
487 case 1: 479 case 1:
488 break; 480 break;
489 default: 481 default:
490 snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", 482 snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", dma2);
491 chip->dma2);
492 goto __skip_resources; 483 goto __skip_resources;
493 } 484 }
494 dma_bits |= 0x04; 485 dma_bits |= 0x04;
495#endif /* CS4231 || OPTi93X */ 486#endif /* CS4231 || OPTi93X */
496 487
497#ifndef OPTi93X 488#ifndef OPTi93X
498 outb(irq_bits << 3 | dma_bits, chip->wss_base); 489 outb(irq_bits << 3 | dma_bits, wss_base);
499#else /* OPTi93X */ 490#else /* OPTi93X */
500 snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits)); 491 snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
501#endif /* OPTi93X */ 492#endif /* OPTi93X */
502 493
503__skip_resources: 494__skip_resources:
504 if (chip->hardware > OPTi9XX_HW_82C928) { 495 if (chip->hardware > OPTi9XX_HW_82C928) {
505 switch (chip->mpu_port) { 496 switch (mpu_port) {
506 case 0: 497 case 0:
507 case -1: 498 case -1:
508 break; 499 break;
@@ -520,12 +511,11 @@ __skip_resources:
520 break; 511 break;
521 default: 512 default:
522 snd_printk(KERN_WARNING 513 snd_printk(KERN_WARNING
523 "MPU-401 port 0x%lx not valid\n", 514 "MPU-401 port 0x%lx not valid\n", mpu_port);
524 chip->mpu_port);
525 goto __skip_mpu; 515 goto __skip_mpu;
526 } 516 }
527 517
528 switch (chip->mpu_irq) { 518 switch (mpu_irq) {
529 case 5: 519 case 5:
530 mpu_irq_bits = 0x02; 520 mpu_irq_bits = 0x02;
531 break; 521 break;
@@ -540,12 +530,12 @@ __skip_resources:
540 break; 530 break;
541 default: 531 default:
542 snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n", 532 snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n",
543 chip->mpu_irq); 533 mpu_irq);
544 goto __skip_mpu; 534 goto __skip_mpu;
545 } 535 }
546 536
547 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6), 537 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6),
548 (chip->mpu_port <= 0) ? 0x00 : 538 (mpu_port <= 0) ? 0x00 :
549 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3, 539 0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
550 0xf8); 540 0xf8);
551 } 541 }
@@ -558,10 +548,13 @@ __skip_mpu:
558 548
559static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id) 549static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
560{ 550{
561 struct snd_wss *codec = dev_id; 551 struct snd_opti9xx *chip = dev_id;
562 struct snd_opti9xx *chip = codec->card->private_data; 552 struct snd_wss *codec = chip->codec;
563 unsigned char status; 553 unsigned char status;
564 554
555 if (!codec)
556 return IRQ_HANDLED;
557
565 status = snd_opti9xx_read(chip, OPTi9XX_MC_REG(11)); 558 status = snd_opti9xx_read(chip, OPTi9XX_MC_REG(11));
566 if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream) 559 if ((status & OPTi93X_IRQ_PLAYBACK) && codec->playback_substream)
567 snd_pcm_period_elapsed(codec->playback_substream); 560 snd_pcm_period_elapsed(codec->playback_substream);
@@ -575,57 +568,69 @@ static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
575 568
576#endif /* OPTi93X */ 569#endif /* OPTi93X */
577 570
578static int __devinit snd_card_opti9xx_detect(struct snd_card *card, 571static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
579 struct snd_opti9xx *chip)
580{ 572{
581 int i, err; 573 unsigned char value;
574#ifdef OPTi93X
575 unsigned long flags;
576#endif
582 577
578 chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
579 "OPTi9xx MC");
580 if (chip->res_mc_base == NULL)
581 return -EBUSY;
583#ifndef OPTi93X 582#ifndef OPTi93X
584 for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) { 583 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1));
585 unsigned char value; 584 if (value != 0xff && value != inb(chip->mc_base + OPTi9XX_MC_REG(1)))
585 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
586 return 0;
587#else /* OPTi93X */
588 chip->res_mc_indir = request_region(chip->mc_indir_index,
589 chip->mc_indir_size,
590 "OPTi93x MC");
591 if (chip->res_mc_indir == NULL)
592 return -EBUSY;
586 593
587 if ((err = snd_opti9xx_init(chip, i)) < 0) 594 spin_lock_irqsave(&chip->lock, flags);
588 return err; 595 outb(chip->password, chip->mc_base + chip->pwd_reg);
596 outb(((chip->mc_indir_index & 0x1f0) >> 4), chip->mc_base);
597 spin_unlock_irqrestore(&chip->lock, flags);
589 598
590 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) 599 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
591 continue; 600 snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
601 if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
602 return 0;
592 603
593 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)); 604 release_and_free_resource(chip->res_mc_indir);
594 if ((value != 0xff) && (value != inb(chip->mc_base + 1))) 605 chip->res_mc_indir = NULL;
595 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) 606#endif /* OPTi93X */
596 return 1; 607 release_and_free_resource(chip->res_mc_base);
608 chip->res_mc_base = NULL;
597 609
598 release_and_free_resource(chip->res_mc_base); 610 return -ENODEV;
599 chip->res_mc_base = NULL; 611}
600 612
601 } 613static int __devinit snd_card_opti9xx_detect(struct snd_card *card,
602#else /* OPTi93X */ 614 struct snd_opti9xx *chip)
603 for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) { 615{
604 unsigned long flags; 616 int i, err;
605 unsigned char value;
606 617
607 if ((err = snd_opti9xx_init(chip, i)) < 0) 618#ifndef OPTi93X
619 for (i = OPTi9XX_HW_82C928; i < OPTi9XX_HW_82C930; i++) {
620#else
621 for (i = OPTi9XX_HW_82C931; i >= OPTi9XX_HW_82C930; i--) {
622#endif
623 err = snd_opti9xx_init(chip, i);
624 if (err < 0)
608 return err; 625 return err;
609 626
610 if ((chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size, "OPTi9xx MC")) == NULL) 627 err = snd_opti9xx_read_check(chip);
611 continue; 628 if (err == 0)
612
613 spin_lock_irqsave(&chip->lock, flags);
614 outb(chip->password, chip->mc_base + chip->pwd_reg);
615 outb(((chip->mc_indir_index & (1 << 8)) >> 4) |
616 ((chip->mc_indir_index & 0xf0) >> 4), chip->mc_base);
617 spin_unlock_irqrestore(&chip->lock, flags);
618
619 value = snd_opti9xx_read(chip, OPTi9XX_MC_REG(7));
620 snd_opti9xx_write(chip, OPTi9XX_MC_REG(7), 0xff - value);
621 if (snd_opti9xx_read(chip, OPTi9XX_MC_REG(7)) == 0xff - value)
622 return 1; 629 return 1;
623 630#ifdef OPTi93X
624 release_and_free_resource(chip->res_mc_base); 631 chip->mc_indir_index = 0;
625 chip->res_mc_base = NULL; 632#endif
626 } 633 }
627#endif /* OPTi93X */
628
629 return -ENODEV; 634 return -ENODEV;
630} 635}
631 636
@@ -654,6 +659,8 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
654#ifdef OPTi93X 659#ifdef OPTi93X
655 port = pnp_port_start(pdev, 0) - 4; 660 port = pnp_port_start(pdev, 0) - 4;
656 fm_port = pnp_port_start(pdev, 1) + 8; 661 fm_port = pnp_port_start(pdev, 1) + 8;
662 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2;
663 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2;
657#else 664#else
658 if (pid->driver_data != 0x0924) 665 if (pid->driver_data != 0x0924)
659 port = pnp_port_start(pdev, 1); 666 port = pnp_port_start(pdev, 1);
@@ -684,14 +691,14 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
684static void snd_card_opti9xx_free(struct snd_card *card) 691static void snd_card_opti9xx_free(struct snd_card *card)
685{ 692{
686 struct snd_opti9xx *chip = card->private_data; 693 struct snd_opti9xx *chip = card->private_data;
687 694
688 if (chip) { 695 if (chip) {
689#ifdef OPTi93X 696#ifdef OPTi93X
690 struct snd_wss *codec = chip->codec; 697 if (chip->irq > 0) {
691 if (codec && codec->irq > 0) { 698 disable_irq(chip->irq);
692 disable_irq(codec->irq); 699 free_irq(chip->irq, chip);
693 free_irq(codec->irq, codec);
694 } 700 }
701 release_and_free_resource(chip->res_mc_indir);
695#endif 702#endif
696 release_and_free_resource(chip->res_mc_base); 703 release_and_free_resource(chip->res_mc_base);
697 } 704 }
@@ -701,6 +708,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
701{ 708{
702 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1}; 709 static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
703 int error; 710 int error;
711 int xdma2;
704 struct snd_opti9xx *chip = card->private_data; 712 struct snd_opti9xx *chip = card->private_data;
705 struct snd_wss *codec; 713 struct snd_wss *codec;
706#ifdef CS4231 714#ifdef CS4231
@@ -710,36 +718,25 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
710 struct snd_rawmidi *rmidi; 718 struct snd_rawmidi *rmidi;
711 struct snd_hwdep *synth; 719 struct snd_hwdep *synth;
712 720
713 if (! chip->res_mc_base &&
714 (chip->res_mc_base = request_region(chip->mc_base, chip->mc_base_size,
715 "OPTi9xx MC")) == NULL)
716 return -ENOMEM;
717
718 chip->wss_base = port;
719 chip->fm_port = fm_port;
720 chip->mpu_port = mpu_port;
721 chip->irq = irq;
722 chip->mpu_irq = mpu_irq;
723 chip->dma1 = dma1;
724#if defined(CS4231) || defined(OPTi93X) 721#if defined(CS4231) || defined(OPTi93X)
725 chip->dma2 = dma2; 722 xdma2 = dma2;
726#else 723#else
727 chip->dma2 = -1; 724 xdma2 = -1;
728#endif 725#endif
729 726
730 if (chip->wss_base == SNDRV_AUTO_PORT) { 727 if (port == SNDRV_AUTO_PORT) {
731 chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4); 728 port = snd_legacy_find_free_ioport(possible_ports, 4);
732 if (chip->wss_base < 0) { 729 if (port < 0) {
733 snd_printk(KERN_ERR "unable to find a free WSS port\n"); 730 snd_printk(KERN_ERR "unable to find a free WSS port\n");
734 return -EBUSY; 731 return -EBUSY;
735 } 732 }
736 } 733 }
737 error = snd_opti9xx_configure(chip); 734 error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
735 mpu_port, mpu_irq);
738 if (error) 736 if (error)
739 return error; 737 return error;
740 738
741 error = snd_wss_create(card, chip->wss_base + 4, -1, 739 error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2,
742 chip->irq, chip->dma1, chip->dma2,
743#ifdef OPTi93X 740#ifdef OPTi93X
744 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ, 741 WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
745#else 742#else
@@ -763,35 +760,35 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
763 return error; 760 return error;
764#endif 761#endif
765#ifdef OPTi93X 762#ifdef OPTi93X
766 error = request_irq(chip->irq, snd_opti93x_interrupt, 763 error = request_irq(irq, snd_opti93x_interrupt,
767 IRQF_DISABLED, DEV_NAME" - WSS", codec); 764 IRQF_DISABLED, DEV_NAME" - WSS", chip);
768 if (error < 0) { 765 if (error < 0) {
769 snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq); 766 snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", irq);
770 return error; 767 return error;
771 } 768 }
772#endif 769#endif
770 chip->irq = irq;
773 strcpy(card->driver, chip->name); 771 strcpy(card->driver, chip->name);
774 sprintf(card->shortname, "OPTi %s", card->driver); 772 sprintf(card->shortname, "OPTi %s", card->driver);
775#if defined(CS4231) || defined(OPTi93X) 773#if defined(CS4231) || defined(OPTi93X)
776 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d", 774 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
777 card->shortname, pcm->name, chip->wss_base + 4, 775 card->shortname, pcm->name, port + 4, irq, dma1, xdma2);
778 chip->irq, chip->dma1, chip->dma2);
779#else 776#else
780 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d", 777 sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
781 card->shortname, pcm->name, chip->wss_base + 4, 778 card->shortname, pcm->name, port + 4, irq, dma1);
782 chip->irq, chip->dma1);
783#endif /* CS4231 || OPTi93X */ 779#endif /* CS4231 || OPTi93X */
784 780
785 if (chip->mpu_port <= 0 || chip->mpu_port == SNDRV_AUTO_PORT) 781 if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
786 rmidi = NULL; 782 rmidi = NULL;
787 else 783 else {
788 if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401, 784 error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
789 chip->mpu_port, 0, chip->mpu_irq, IRQF_DISABLED, 785 mpu_port, 0, mpu_irq, IRQF_DISABLED, &rmidi);
790 &rmidi))) 786 if (error)
791 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n", 787 snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
792 chip->mpu_port); 788 mpu_port);
789 }
793 790
794 if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) { 791 if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
795 struct snd_opl3 *opl3 = NULL; 792 struct snd_opl3 *opl3 = NULL;
796#ifndef OPTi93X 793#ifndef OPTi93X
797 if (chip->hardware == OPTi9XX_HW_82C928 || 794 if (chip->hardware == OPTi9XX_HW_82C928 ||
@@ -801,9 +798,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
801 /* assume we have an OPL4 */ 798 /* assume we have an OPL4 */
802 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 799 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
803 0x20, 0x20); 800 0x20, 0x20);
804 if (snd_opl4_create(card, 801 if (snd_opl4_create(card, fm_port, fm_port - 8,
805 chip->fm_port,
806 chip->fm_port - 8,
807 2, &opl3, &opl4) < 0) { 802 2, &opl3, &opl4) < 0) {
808 /* no luck, use OPL3 instead */ 803 /* no luck, use OPL3 instead */
809 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2), 804 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
@@ -811,12 +806,10 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
811 } 806 }
812 } 807 }
813#endif /* !OPTi93X */ 808#endif /* !OPTi93X */
814 if (!opl3 && snd_opl3_create(card, 809 if (!opl3 && snd_opl3_create(card, fm_port, fm_port + 2,
815 chip->fm_port,
816 chip->fm_port + 2,
817 OPL3_HW_AUTO, 0, &opl3) < 0) { 810 OPL3_HW_AUTO, 0, &opl3) < 0) {
818 snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n", 811 snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
819 chip->fm_port, chip->fm_port + 4 - 1); 812 fm_port, fm_port + 4 - 1);
820 } 813 }
821 if (opl3) { 814 if (opl3) {
822 error = snd_opl3_hwdep_new(opl3, 0, 1, &synth); 815 error = snd_opl3_hwdep_new(opl3, 0, 1, &synth);
@@ -978,6 +971,13 @@ static int __devinit snd_opti9xx_pnp_probe(struct pnp_card_link *pcard,
978 } 971 }
979 if (hw <= OPTi9XX_HW_82C930) 972 if (hw <= OPTi9XX_HW_82C930)
980 chip->mc_base -= 0x80; 973 chip->mc_base -= 0x80;
974
975 error = snd_opti9xx_read_check(chip);
976 if (error) {
977 snd_printk(KERN_ERR "OPTI chip not found\n");
978 snd_card_free(card);
979 return error;
980 }
981 snd_card_set_dev(card, &pcard->card->dev); 981 snd_card_set_dev(card, &pcard->card->dev);
982 if ((error = snd_opti9xx_probe(card)) < 0) { 982 if ((error = snd_opti9xx_probe(card)) < 0) {
983 snd_card_free(card); 983 snd_card_free(card);
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 2ba18978b419..5b9d6c18bc45 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -1682,7 +1682,7 @@ static void snd_wss_resume(struct snd_wss *chip)
1682} 1682}
1683#endif /* CONFIG_PM */ 1683#endif /* CONFIG_PM */
1684 1684
1685int snd_wss_free(struct snd_wss *chip) 1685static int snd_wss_free(struct snd_wss *chip)
1686{ 1686{
1687 release_and_free_resource(chip->res_port); 1687 release_and_free_resource(chip->res_port);
1688 release_and_free_resource(chip->res_cport); 1688 release_and_free_resource(chip->res_cport);
@@ -1705,7 +1705,6 @@ int snd_wss_free(struct snd_wss *chip)
1705 kfree(chip); 1705 kfree(chip);
1706 return 0; 1706 return 0;
1707} 1707}
1708EXPORT_SYMBOL(snd_wss_free);
1709 1708
1710static int snd_wss_dev_free(struct snd_device *device) 1709static int snd_wss_dev_free(struct snd_device *device)
1711{ 1710{
@@ -2225,7 +2224,7 @@ WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
2225 .get = snd_wss_get_mux, 2224 .get = snd_wss_get_mux,
2226 .put = snd_wss_put_mux, 2225 .put = snd_wss_put_mux,
2227}, 2226},
2228WSS_DOUBLE("Mic Boost", 0, 2227WSS_DOUBLE("Mic Boost (+20dB)", 0,
2229 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0), 2228 CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
2230WSS_SINGLE("Loopback Capture Switch", 0, 2229WSS_SINGLE("Loopback Capture Switch", 0,
2231 CS4231_LOOPBACK, 0, 1, 0), 2230 CS4231_LOOPBACK, 0, 1, 0),
@@ -2236,14 +2235,14 @@ WSS_DOUBLE("Line Playback Switch", 0,
2236WSS_DOUBLE_TLV("Line Playback Volume", 0, 2235WSS_DOUBLE_TLV("Line Playback Volume", 0,
2237 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1, 2236 CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
2238 db_scale_5bit_12db_max), 2237 db_scale_5bit_12db_max),
2239WSS_SINGLE("Mono Playback Switch", 0, 2238WSS_SINGLE("Beep Playback Switch", 0,
2240 CS4231_MONO_CTRL, 7, 1, 1), 2239 CS4231_MONO_CTRL, 7, 1, 1),
2241WSS_SINGLE_TLV("Mono Playback Volume", 0, 2240WSS_SINGLE_TLV("Beep Playback Volume", 0,
2242 CS4231_MONO_CTRL, 0, 15, 1, 2241 CS4231_MONO_CTRL, 0, 15, 1,
2243 db_scale_4bit), 2242 db_scale_4bit),
2244WSS_SINGLE("Mono Output Playback Switch", 0, 2243WSS_SINGLE("Mono Output Playback Switch", 0,
2245 CS4231_MONO_CTRL, 6, 1, 1), 2244 CS4231_MONO_CTRL, 6, 1, 1),
2246WSS_SINGLE("Mono Output Playback Bypass", 0, 2245WSS_SINGLE("Beep Bypass Playback Switch", 0,
2247 CS4231_MONO_CTRL, 5, 1, 0), 2246 CS4231_MONO_CTRL, 5, 1, 0),
2248}; 2247};
2249 2248
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig
index 135a2b77cc4a..a513651fa149 100644
--- a/sound/oss/Kconfig
+++ b/sound/oss/Kconfig
@@ -1,5 +1,3 @@
1# drivers/sound/Config.in
2#
3# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net> 1# 18 Apr 1998, Michael Elizabeth Chastain, <mailto:mec@shout.net>
4# More hacking for modularisation. 2# More hacking for modularisation.
5# 3#
diff --git a/sound/oss/audio.c b/sound/oss/audio.c
index b69c05b7ea7b..7df48a25c4ee 100644
--- a/sound/oss/audio.c
+++ b/sound/oss/audio.c
@@ -838,7 +838,7 @@ static int dma_ioctl(int dev, unsigned int cmd, void __user *arg)
838 if ((err = audio_devs[dev]->d->prepare_for_input(dev, 838 if ((err = audio_devs[dev]->d->prepare_for_input(dev,
839 dmap_in->fragment_size, dmap_in->nbufs)) < 0) { 839 dmap_in->fragment_size, dmap_in->nbufs)) < 0) {
840 spin_unlock_irqrestore(&dmap_in->lock,flags); 840 spin_unlock_irqrestore(&dmap_in->lock,flags);
841 return -err; 841 return err;
842 } 842 }
843 dmap_in->dma_mode = DMODE_INPUT; 843 dmap_in->dma_mode = DMODE_INPUT;
844 audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT; 844 audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT;
diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c
index 793b7f478433..3f3c3f71db4b 100644
--- a/sound/oss/dmasound/dmasound_core.c
+++ b/sound/oss/dmasound/dmasound_core.c
@@ -219,7 +219,9 @@ static int shared_resources_initialised;
219 * Mid level stuff 219 * Mid level stuff
220 */ 220 */
221 221
222struct sound_settings dmasound = { .lock = SPIN_LOCK_UNLOCKED }; 222struct sound_settings dmasound = {
223 .lock = __SPIN_LOCK_UNLOCKED(dmasound.lock)
224};
223 225
224static inline void sound_silence(void) 226static inline void sound_silence(void)
225{ 227{
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c
index 06e9e88e4c05..bb14e4c67e89 100644
--- a/sound/oss/dmasound/dmasound_paula.c
+++ b/sound/oss/dmasound/dmasound_paula.c
@@ -657,7 +657,7 @@ static int AmiStateInfo(char *buffer, size_t space)
657 len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n", 657 len += sprintf(buffer+len, "\tsound.volume_right = %d [0...64]\n",
658 dmasound.volume_right); 658 dmasound.volume_right);
659 if (len >= space) { 659 if (len >= space) {
660 printk(KERN_ERR "dmasound_paula: overlowed state buffer alloc.\n") ; 660 printk(KERN_ERR "dmasound_paula: overflowed state buffer alloc.\n") ;
661 len = space ; 661 len = space ;
662 } 662 }
663 return len; 663 return len;
diff --git a/sound/oss/hex2hex.c b/sound/oss/hex2hex.c
index 5460faae98c9..041ef5c52bc2 100644
--- a/sound/oss/hex2hex.c
+++ b/sound/oss/hex2hex.c
@@ -12,7 +12,7 @@
12#define MAX_SIZE (256*1024) 12#define MAX_SIZE (256*1024)
13unsigned char buf[MAX_SIZE]; 13unsigned char buf[MAX_SIZE];
14 14
15int loadhex(FILE *inf, unsigned char *buf) 15static int loadhex(FILE *inf, unsigned char *buf)
16{ 16{
17 int l=0, c, i; 17 int l=0, c, i;
18 18
diff --git a/sound/oss/midi_synth.c b/sound/oss/midi_synth.c
index 9e450988ed36..3bc7104c5379 100644
--- a/sound/oss/midi_synth.c
+++ b/sound/oss/midi_synth.c
@@ -426,7 +426,7 @@ midi_synth_open(int dev, int mode)
426 int err; 426 int err;
427 struct midi_input_info *inc; 427 struct midi_input_info *inc;
428 428
429 if (orig_dev < 0 || orig_dev > num_midis || midi_devs[orig_dev] == NULL) 429 if (orig_dev < 0 || orig_dev >= num_midis || midi_devs[orig_dev] == NULL)
430 return -ENXIO; 430 return -ENXIO;
431 431
432 midi2synth[orig_dev] = dev; 432 midi2synth[orig_dev] = dev;
diff --git a/sound/oss/mpu401.c b/sound/oss/mpu401.c
index 734b8f9e2f78..0af9d24feb8f 100644
--- a/sound/oss/mpu401.c
+++ b/sound/oss/mpu401.c
@@ -770,7 +770,7 @@ static int mpu_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
770 770
771 midi_dev = synth_devs[dev]->midi_dev; 771 midi_dev = synth_devs[dev]->midi_dev;
772 772
773 if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev] == NULL) 773 if (midi_dev < 0 || midi_dev >= num_midis || midi_devs[midi_dev] == NULL)
774 return -ENXIO; 774 return -ENXIO;
775 775
776 devc = &dev_conf[midi_dev]; 776 devc = &dev_conf[midi_dev];
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c
index 77d0e5efda76..ce4db49291f7 100644
--- a/sound/oss/sb_common.c
+++ b/sound/oss/sb_common.c
@@ -157,7 +157,7 @@ static void sb_intr (sb_devc *devc)
157 break; 157 break;
158 158
159 default: 159 default:
160 /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */ 160 /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
161 ; 161 ;
162 } 162 }
163 } 163 }
@@ -177,7 +177,7 @@ static void sb_intr (sb_devc *devc)
177 break; 177 break;
178 178
179 default: 179 default:
180 /* printk(KERN_WARN "Sound Blaster: Unexpected interrupt\n"); */ 180 /* printk(KERN_WARNING "Sound Blaster: Unexpected interrupt\n"); */
181 ; 181 ;
182 } 182 }
183 } 183 }
diff --git a/sound/oss/sb_ess.c b/sound/oss/sb_ess.c
index 180e95c87e3e..51a3d381a59e 100644
--- a/sound/oss/sb_ess.c
+++ b/sound/oss/sb_ess.c
@@ -782,7 +782,7 @@ printk(KERN_INFO "FKS: ess_handle_channel %s irq_mode=%d\n", channel, irq_mode);
782 break; 782 break;
783 783
784 default:; 784 default:;
785 /* printk(KERN_WARN "ESS: Unexpected interrupt\n"); */ 785 /* printk(KERN_WARNING "ESS: Unexpected interrupt\n"); */
786 } 786 }
787} 787}
788 788
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 75c602b5b132..351654cf7b09 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -570,6 +570,7 @@ config SND_ICE1712
570 tristate "ICEnsemble ICE1712 (Envy24)" 570 tristate "ICEnsemble ICE1712 (Envy24)"
571 select SND_MPU401_UART 571 select SND_MPU401_UART
572 select SND_AC97_CODEC 572 select SND_AC97_CODEC
573 select BITREVERSE
573 help 574 help
574 Say Y here to include support for soundcards based on the 575 Say Y here to include support for soundcards based on the
575 ICE1712 (Envy24) chip. 576 ICE1712 (Envy24) chip.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 20cb60afb200..c11920623009 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -2122,7 +2122,7 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
2122 } 2122 }
2123 /* nothing should be in powerdown mode */ 2123 /* nothing should be in powerdown mode */
2124 snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0); 2124 snd_ac97_write_cache(ac97, AC97_GENERAL_PURPOSE, 0);
2125 end_time = jiffies + msecs_to_jiffies(120); 2125 end_time = jiffies + msecs_to_jiffies(5000);
2126 do { 2126 do {
2127 if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f) 2127 if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f)
2128 goto __ready_ok; 2128 goto __ready_ok;
diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c
index 15523e60351c..0470461cc03e 100644
--- a/sound/pci/ca0106/ca0106_proc.c
+++ b/sound/pci/ca0106/ca0106_proc.c
@@ -233,7 +233,7 @@ static void snd_ca0106_proc_dump_iec958( struct snd_info_buffer *buffer, u32 val
233 snd_iprintf(buffer, "user-defined\n"); 233 snd_iprintf(buffer, "user-defined\n");
234 break; 234 break;
235 default: 235 default:
236 snd_iprintf(buffer, "unkown\n"); 236 snd_iprintf(buffer, "unknown\n");
237 break; 237 break;
238 } 238 }
239 snd_iprintf(buffer, "Sample Bits: "); 239 snd_iprintf(buffer, "Sample Bits: ");
diff --git a/sound/pci/cs46xx/imgs/cwcdma.asp b/sound/pci/cs46xx/imgs/cwcdma.asp
index 09d24c76f034..a65e1193c89a 100644
--- a/sound/pci/cs46xx/imgs/cwcdma.asp
+++ b/sound/pci/cs46xx/imgs/cwcdma.asp
@@ -26,10 +26,11 @@
26// 26//
27// 27//
28// The purpose of this code is very simple: make it possible to tranfser 28// The purpose of this code is very simple: make it possible to tranfser
29// the samples 'as they are' with no alteration from a PCMreader SCB (DMA from host) 29// the samples 'as they are' with no alteration from a PCMreader
30// to any other SCB. This is useful for AC3 throug SPDIF. SRC (source rate converters) 30// SCB (DMA from host) to any other SCB. This is useful for AC3 through SPDIF.
31// task always alters the samples in some how, however it's from 48khz -> 48khz. The 31// SRC (source rate converters) task always alters the samples in somehow,
32// alterations are not audible, but AC3 wont work. 32// however it's from 48khz -> 48khz.
33// The alterations are not audible, but AC3 wont work.
33// 34//
34// ... 35// ...
35// | 36// |
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 6b8ae7b5cd54..1d369ff73805 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -184,7 +184,7 @@ MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard.");
184 * The hardware has 3 channels for playback and 1 for capture. 184 * The hardware has 3 channels for playback and 1 for capture.
185 * - channel 0 is the front channel 185 * - channel 0 is the front channel
186 * - channel 1 is the rear channel 186 * - channel 1 is the rear channel
187 * - channel 2 is the center/lfe chanel 187 * - channel 2 is the center/lfe channel
188 * Volume is controlled by the AC97 for the front and rear channels by 188 * Volume is controlled by the AC97 for the front and rear channels by
189 * the PCM Playback Volume, Sigmatel Surround Playback Volume and 189 * the PCM Playback Volume, Sigmatel Surround Playback Volume and
190 * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects 190 * Surround Playback Volume. The Sigmatel 4-Speaker Stereo switch affects
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index 60cdb9e0b68d..83508b3964fb 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -55,7 +55,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
55 * 1 = MediaForte 256-PCS 55 * 1 = MediaForte 256-PCS
56 * 2 = MediaForte 256-PCPR 56 * 2 = MediaForte 256-PCPR
57 * 3 = MediaForte 64-PCR 57 * 3 = MediaForte 64-PCR
58 * 16 = setup tuner only (this is additional bit), i.e. SF-64-PCR FM card 58 * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card
59 * High 16-bits are video (radio) device number + 1 59 * High 16-bits are video (radio) device number + 1
60 */ 60 */
61static int tea575x_tuner[SNDRV_CARDS]; 61static int tea575x_tuner[SNDRV_CARDS];
@@ -67,7 +67,10 @@ MODULE_PARM_DESC(id, "ID string for the FM801 soundcard.");
67module_param_array(enable, bool, NULL, 0444); 67module_param_array(enable, bool, NULL, 0444);
68MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); 68MODULE_PARM_DESC(enable, "Enable FM801 soundcard.");
69module_param_array(tea575x_tuner, int, NULL, 0444); 69module_param_array(tea575x_tuner, int, NULL, 0444);
70MODULE_PARM_DESC(tea575x_tuner, "Enable TEA575x tuner."); 70MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR, +16=tuner-only).");
71
72#define TUNER_ONLY (1<<4)
73#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF)
71 74
72/* 75/*
73 * Direct registers 76 * Direct registers
@@ -160,7 +163,7 @@ struct fm801 {
160 unsigned int multichannel: 1, /* multichannel support */ 163 unsigned int multichannel: 1, /* multichannel support */
161 secondary: 1; /* secondary codec */ 164 secondary: 1; /* secondary codec */
162 unsigned char secondary_addr; /* address of the secondary codec */ 165 unsigned char secondary_addr; /* address of the secondary codec */
163 unsigned int tea575x_tuner; /* tuner flags */ 166 unsigned int tea575x_tuner; /* tuner access method & flags */
164 167
165 unsigned short ply_ctrl; /* playback control */ 168 unsigned short ply_ctrl; /* playback control */
166 unsigned short cap_ctrl; /* capture control */ 169 unsigned short cap_ctrl; /* capture control */
@@ -1287,7 +1290,7 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume)
1287{ 1290{
1288 unsigned short cmdw; 1291 unsigned short cmdw;
1289 1292
1290 if (chip->tea575x_tuner & 0x0010) 1293 if (chip->tea575x_tuner & TUNER_ONLY)
1291 goto __ac97_ok; 1294 goto __ac97_ok;
1292 1295
1293 /* codec cold reset + AC'97 warm reset */ 1296 /* codec cold reset + AC'97 warm reset */
@@ -1296,11 +1299,13 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume)
1296 udelay(100); 1299 udelay(100);
1297 outw(0, FM801_REG(chip, CODEC_CTRL)); 1300 outw(0, FM801_REG(chip, CODEC_CTRL));
1298 1301
1299 if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0) { 1302 if (wait_for_codec(chip, 0, AC97_RESET, msecs_to_jiffies(750)) < 0)
1300 snd_printk(KERN_ERR "Primary AC'97 codec not found\n"); 1303 if (!resume) {
1301 if (! resume) 1304 snd_printk(KERN_INFO "Primary AC'97 codec not found, "
1302 return -EIO; 1305 "assume SF64-PCR (tuner-only)\n");
1303 } 1306 chip->tea575x_tuner = 3 | TUNER_ONLY;
1307 goto __ac97_ok;
1308 }
1304 1309
1305 if (chip->multichannel) { 1310 if (chip->multichannel) {
1306 if (chip->secondary_addr) { 1311 if (chip->secondary_addr) {
@@ -1414,7 +1419,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1414 return err; 1419 return err;
1415 } 1420 }
1416 chip->port = pci_resource_start(pci, 0); 1421 chip->port = pci_resource_start(pci, 0);
1417 if ((tea575x_tuner & 0x0010) == 0) { 1422 if ((tea575x_tuner & TUNER_ONLY) == 0) {
1418 if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED, 1423 if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
1419 "FM801", chip)) { 1424 "FM801", chip)) {
1420 snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq); 1425 snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
@@ -1429,6 +1434,14 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1429 chip->multichannel = 1; 1434 chip->multichannel = 1;
1430 1435
1431 snd_fm801_chip_init(chip, 0); 1436 snd_fm801_chip_init(chip, 0);
1437 /* init might set tuner access method */
1438 tea575x_tuner = chip->tea575x_tuner;
1439
1440 if (chip->irq >= 0 && (tea575x_tuner & TUNER_ONLY)) {
1441 pci_clear_master(pci);
1442 free_irq(chip->irq, chip);
1443 chip->irq = -1;
1444 }
1432 1445
1433 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { 1446 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
1434 snd_fm801_free(chip); 1447 snd_fm801_free(chip);
@@ -1438,12 +1451,13 @@ static int __devinit snd_fm801_create(struct snd_card *card,
1438 snd_card_set_dev(card, &pci->dev); 1451 snd_card_set_dev(card, &pci->dev);
1439 1452
1440#ifdef TEA575X_RADIO 1453#ifdef TEA575X_RADIO
1441 if (tea575x_tuner > 0 && (tea575x_tuner & 0x000f) < 4) { 1454 if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 &&
1455 (tea575x_tuner & TUNER_TYPE_MASK) < 4) {
1442 chip->tea.dev_nr = tea575x_tuner >> 16; 1456 chip->tea.dev_nr = tea575x_tuner >> 16;
1443 chip->tea.card = card; 1457 chip->tea.card = card;
1444 chip->tea.freq_fixup = 10700; 1458 chip->tea.freq_fixup = 10700;
1445 chip->tea.private_data = chip; 1459 chip->tea.private_data = chip;
1446 chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & 0x000f) - 1]; 1460 chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & TUNER_TYPE_MASK) - 1];
1447 snd_tea575x_init(&chip->tea); 1461 snd_tea575x_init(&chip->tea);
1448 } 1462 }
1449#endif 1463#endif
@@ -1483,7 +1497,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
1483 sprintf(card->longname, "%s at 0x%lx, irq %i", 1497 sprintf(card->longname, "%s at 0x%lx, irq %i",
1484 card->shortname, chip->port, chip->irq); 1498 card->shortname, chip->port, chip->irq);
1485 1499
1486 if (tea575x_tuner[dev] & 0x0010) 1500 if (chip->tea575x_tuner & TUNER_ONLY)
1487 goto __fm801_tuner_only; 1501 goto __fm801_tuner_only;
1488 1502
1489 if ((err = snd_fm801_pcm(chip, 0, NULL)) < 0) { 1503 if ((err = snd_fm801_pcm(chip, 0, NULL)) < 0) {
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 2439e84dcb21..4b200da1bd18 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -938,7 +938,7 @@ static void init_input(struct hda_codec *codec)
938 coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */ 938 coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */
939 if (is_active_pin(codec, CS_DMIC1_PIN_NID)) 939 if (is_active_pin(codec, CS_DMIC1_PIN_NID))
940 coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0 940 coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0
941 * No effect if SPDIF_OUT2 is slected in 941 * No effect if SPDIF_OUT2 is selected in
942 * IDX_SPDIF_CTL. 942 * IDX_SPDIF_CTL.
943 */ 943 */
944 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); 944 cs_vendor_coef_set(codec, IDX_ADC_CFG, coef);
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 85c81feb10cf..a45c1169762b 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -66,7 +66,7 @@ struct cmi_spec {
66 66
67 struct hda_pcm pcm_rec[2]; /* PCM information */ 67 struct hda_pcm pcm_rec[2]; /* PCM information */
68 68
69 /* pin deafault configuration */ 69 /* pin default configuration */
70 hda_nid_t pin_nid[NUM_PINS]; 70 hda_nid_t pin_nid[NUM_PINS];
71 unsigned int def_conf[NUM_PINS]; 71 unsigned int def_conf[NUM_PINS];
72 unsigned int pin_def_confs; 72 unsigned int pin_def_confs;
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index b3abe9ca826d..0877bae5dae1 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -6673,7 +6673,7 @@ static struct hda_input_mux alc889A_mb31_capture_source = {
6673 /* Front Mic (0x01) unused */ 6673 /* Front Mic (0x01) unused */
6674 { "Line", 0x2 }, 6674 { "Line", 0x2 },
6675 /* Line 2 (0x03) unused */ 6675 /* Line 2 (0x03) unused */
6676 /* CD (0x04) unsused? */ 6676 /* CD (0x04) unused? */
6677 }, 6677 },
6678}; 6678};
6679 6679
@@ -9287,8 +9287,6 @@ static struct alc_config_preset alc882_presets[] = {
9287 .dac_nids = alc883_dac_nids, 9287 .dac_nids = alc883_dac_nids,
9288 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids), 9288 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
9289 .adc_nids = alc889_adc_nids, 9289 .adc_nids = alc889_adc_nids,
9290 .capsrc_nids = alc889_capsrc_nids,
9291 .capsrc_nids = alc889_capsrc_nids,
9292 .dig_out_nid = ALC883_DIGOUT_NID, 9290 .dig_out_nid = ALC883_DIGOUT_NID,
9293 .dig_in_nid = ALC883_DIGIN_NID, 9291 .dig_in_nid = ALC883_DIGIN_NID,
9294 .slave_dig_outs = alc883_slave_dig_outs, 9292 .slave_dig_outs = alc883_slave_dig_outs,
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 110d16e52733..765d7bd4c3d4 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -689,32 +689,14 @@ static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
689 return change; 689 return change;
690} 690}
691 691
692static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); 692static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -10000, 100, 1);
693static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); 693static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
694static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0); 694static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
695static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0); 695static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
696static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0); 696static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
697 697
698/* 698#define WM_VOL_MAX 100
699 * Logarithmic volume values for WM8770 699#define WM_VOL_CNT 101 /* 0dB .. -100dB */
700 * Computed as 20 * Log10(255 / x)
701 */
702static const unsigned char wm_vol[256] = {
703 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
704 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
705 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
706 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
707 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
708 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
709 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
710 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
711 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
712 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
713 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
714 0, 0
715};
716
717#define WM_VOL_MAX (sizeof(wm_vol) - 1)
718#define WM_VOL_MUTE 0x8000 700#define WM_VOL_MUTE 0x8000
719 701
720static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master) 702static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master)
@@ -724,7 +706,8 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho
724 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) 706 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
725 nvol = 0; 707 nvol = 0;
726 else 708 else
727 nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; 709 nvol = ((vol % WM_VOL_CNT) * (master % WM_VOL_CNT)) /
710 WM_VOL_MAX;
728 711
729 wm_put(ice, index, nvol); 712 wm_put(ice, index, nvol);
730 wm_put_nocache(ice, index, 0x180 | nvol); 713 wm_put_nocache(ice, index, 0x180 | nvol);
@@ -820,7 +803,7 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *
820 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 803 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
821 uinfo->count = voices; 804 uinfo->count = voices;
822 uinfo->value.integer.min = 0; /* mute (-101dB) */ 805 uinfo->value.integer.min = 0; /* mute (-101dB) */
823 uinfo->value.integer.max = 0x7F; /* 0dB */ 806 uinfo->value.integer.max = WM_VOL_MAX; /* 0dB */
824 return 0; 807 return 0;
825} 808}
826 809
@@ -850,7 +833,7 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
850 snd_ice1712_save_gpio_status(ice); 833 snd_ice1712_save_gpio_status(ice);
851 for (i = 0; i < voices; i++) { 834 for (i = 0; i < voices; i++) {
852 unsigned int vol = ucontrol->value.integer.value[i]; 835 unsigned int vol = ucontrol->value.integer.value[i];
853 if (vol > 0x7f) 836 if (vol > WM_VOL_MAX)
854 continue; 837 continue;
855 vol |= spec->vol[ofs+i]; 838 vol |= spec->vol[ofs+i];
856 if (vol != spec->vol[ofs+i]) { 839 if (vol != spec->vol[ofs+i]) {
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 4615bca39e18..0da778a69ef8 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -387,8 +387,8 @@ struct snd_ice1712 {
387#ifdef CONFIG_PM 387#ifdef CONFIG_PM
388 int (*pm_suspend)(struct snd_ice1712 *); 388 int (*pm_suspend)(struct snd_ice1712 *);
389 int (*pm_resume)(struct snd_ice1712 *); 389 int (*pm_resume)(struct snd_ice1712 *);
390 int pm_suspend_enabled:1; 390 unsigned int pm_suspend_enabled:1;
391 int pm_saved_is_spdif_master:1; 391 unsigned int pm_saved_is_spdif_master:1;
392 unsigned int pm_saved_spdif_ctrl; 392 unsigned int pm_saved_spdif_ctrl;
393 unsigned char pm_saved_spdif_cfg; 393 unsigned char pm_saved_spdif_cfg;
394 unsigned int pm_saved_route; 394 unsigned int pm_saved_route;
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 4bed9633a4cd..98bc3b7681b5 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -380,7 +380,7 @@ static struct snd_kcontrol_new juli_mute_controls[] __devinitdata = {
380 * inputs) are fed from Xilinx. 380 * inputs) are fed from Xilinx.
381 * 381 *
382 * I even checked traces on board and coded a support in driver for 382 * I even checked traces on board and coded a support in driver for
383 * an alternative possiblity - the unused I2S ICE output channels 383 * an alternative possibility - the unused I2S ICE output channels
384 * switched to HW-IN/SPDIF-IN and providing the monitoring signal to 384 * switched to HW-IN/SPDIF-IN and providing the monitoring signal to
385 * the DAC - to no avail. The I2S outputs seem to be unconnected. 385 * the DAC - to no avail. The I2S outputs seem to be unconnected.
386 * 386 *
@@ -483,6 +483,31 @@ static int __devinit juli_add_controls(struct snd_ice1712 *ice)
483} 483}
484 484
485/* 485/*
486 * suspend/resume
487 * */
488
489#ifdef CONFIG_PM
490static int juli_resume(struct snd_ice1712 *ice)
491{
492 struct snd_akm4xxx *ak = ice->akm;
493 struct juli_spec *spec = ice->spec;
494 /* akm4358 un-reset, un-mute */
495 snd_akm4xxx_reset(ak, 0);
496 /* reinit ak4114 */
497 snd_ak4114_reinit(spec->ak4114);
498 return 0;
499}
500
501static int juli_suspend(struct snd_ice1712 *ice)
502{
503 struct snd_akm4xxx *ak = ice->akm;
504 /* akm4358 reset and soft-mute */
505 snd_akm4xxx_reset(ak, 1);
506 return 0;
507}
508#endif
509
510/*
486 * initialize the chip 511 * initialize the chip
487 */ 512 */
488 513
@@ -626,6 +651,13 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
626 ice->set_spdif_clock = juli_set_spdif_clock; 651 ice->set_spdif_clock = juli_set_spdif_clock;
627 652
628 ice->spdif.ops.open = juli_spdif_in_open; 653 ice->spdif.ops.open = juli_spdif_in_open;
654
655#ifdef CONFIG_PM
656 ice->pm_resume = juli_resume;
657 ice->pm_suspend = juli_suspend;
658 ice->pm_suspend_enabled = 1;
659#endif
660
629 return 0; 661 return 0;
630} 662}
631 663
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
index c75515f5be6f..6a9fee3ee78f 100644
--- a/sound/pci/ice1712/prodigy_hifi.c
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -1100,7 +1100,7 @@ static void ak4396_init(struct snd_ice1712 *ice)
1100} 1100}
1101 1101
1102#ifdef CONFIG_PM 1102#ifdef CONFIG_PM
1103static int __devinit prodigy_hd2_resume(struct snd_ice1712 *ice) 1103static int prodigy_hd2_resume(struct snd_ice1712 *ice)
1104{ 1104{
1105 /* initialize ak4396 codec and restore previous mixer volumes */ 1105 /* initialize ak4396 codec and restore previous mixer volumes */
1106 struct prodigy_hifi_spec *spec = ice->spec; 1106 struct prodigy_hifi_spec *spec = ice->spec;
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 754867ed4785..b990143636f1 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -1950,6 +1950,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
1950 }, 1950 },
1951 { 1951 {
1952 .subvendor = 0x104d, 1952 .subvendor = 0x104d,
1953 .subdevice = 0x8144,
1954 .name = "Sony",
1955 .type = AC97_TUNE_INV_EAPD
1956 },
1957 {
1958 .subvendor = 0x104d,
1953 .subdevice = 0x8197, 1959 .subdevice = 0x8197,
1954 .name = "Sony S1XP", 1960 .name = "Sony S1XP",
1955 .type = AC97_TUNE_INV_EAPD 1961 .type = AC97_TUNE_INV_EAPD
@@ -2057,6 +2063,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
2057 .type = AC97_TUNE_HP_ONLY 2063 .type = AC97_TUNE_HP_ONLY
2058 }, 2064 },
2059 { 2065 {
2066 .subvendor = 0x161f,
2067 .subdevice = 0x203a,
2068 .name = "Gateway 4525GZ", /* AD1981B */
2069 .type = AC97_TUNE_INV_EAPD
2070 },
2071 {
2060 .subvendor = 0x1734, 2072 .subvendor = 0x1734,
2061 .subdevice = 0x0088, 2073 .subdevice = 0x0088,
2062 .name = "Fujitsu-Siemens D1522", /* AD1981 */ 2074 .name = "Fujitsu-Siemens D1522", /* AD1981 */
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 0dce331a2a3b..a1b10d1a384d 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -3017,7 +3017,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3017 insel = "Coaxial"; 3017 insel = "Coaxial";
3018 break; 3018 break;
3019 default: 3019 default:
3020 insel = "Unkown"; 3020 insel = "Unknown";
3021 } 3021 }
3022 3022
3023 switch (hdspm->control_register & HDSPM_SyncRefMask) { 3023 switch (hdspm->control_register & HDSPM_SyncRefMask) {
@@ -3028,7 +3028,7 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
3028 syncref = "MADI"; 3028 syncref = "MADI";
3029 break; 3029 break;
3030 default: 3030 default:
3031 syncref = "Unkown"; 3031 syncref = "Unknown";
3032 } 3032 }
3033 snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel, 3033 snd_iprintf(buffer, "Inputsel = %s, SyncRef = %s\n", insel,
3034 syncref); 3034 syncref);
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 7dea74b71cf1..7717e01fc071 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -131,7 +131,7 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
131 return err; 131 return err;
132 } 132 }
133 133
134 snd_card_set_dev(card, &handle_to_dev(link)); 134 snd_card_set_dev(card, &link->dev);
135 135
136 pdacf->index = i; 136 pdacf->index = i;
137 card_list[i] = card; 137 card_list[i] = card;
@@ -142,12 +142,10 @@ static int snd_pdacf_probe(struct pcmcia_device *link)
142 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 142 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
143 link->io.NumPorts1 = 16; 143 link->io.NumPorts1 = 16;
144 144
145 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT | IRQ_FORCED_PULSE; 145 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE;
146 // link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED; 146 // link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
147 147
148 link->irq.IRQInfo1 = 0 /* | IRQ_LEVEL_ID */;
149 link->irq.Handler = pdacf_interrupt; 148 link->irq.Handler = pdacf_interrupt;
150 link->irq.Instance = pdacf;
151 link->conf.Attributes = CONF_ENABLE_IRQ; 149 link->conf.Attributes = CONF_ENABLE_IRQ;
152 link->conf.IntType = INT_MEMORY_AND_IO; 150 link->conf.IntType = INT_MEMORY_AND_IO;
153 link->conf.ConfigIndex = 1; 151 link->conf.ConfigIndex = 1;
@@ -217,20 +215,25 @@ static void snd_pdacf_detach(struct pcmcia_device *link)
217 * configuration callback 215 * configuration callback
218 */ 216 */
219 217
220#define CS_CHECK(fn, ret) \
221do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
222
223static int pdacf_config(struct pcmcia_device *link) 218static int pdacf_config(struct pcmcia_device *link)
224{ 219{
225 struct snd_pdacf *pdacf = link->priv; 220 struct snd_pdacf *pdacf = link->priv;
226 int last_fn, last_ret; 221 int ret;
227 222
228 snd_printdd(KERN_DEBUG "pdacf_config called\n"); 223 snd_printdd(KERN_DEBUG "pdacf_config called\n");
229 link->conf.ConfigIndex = 0x5; 224 link->conf.ConfigIndex = 0x5;
230 225
231 CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); 226 ret = pcmcia_request_io(link, &link->io);
232 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 227 if (ret)
233 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 228 goto failed;
229
230 ret = pcmcia_request_irq(link, &link->irq);
231 if (ret)
232 goto failed;
233
234 ret = pcmcia_request_configuration(link, &link->conf);
235 if (ret)
236 goto failed;
234 237
235 if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0) 238 if (snd_pdacf_assign_resources(pdacf, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
236 goto failed; 239 goto failed;
@@ -238,8 +241,6 @@ static int pdacf_config(struct pcmcia_device *link)
238 link->dev_node = &pdacf->node; 241 link->dev_node = &pdacf->node;
239 return 0; 242 return 0;
240 243
241cs_failed:
242 cs_error(link, last_fn, last_ret);
243failed: 244failed:
244 pcmcia_disable_device(link); 245 pcmcia_disable_device(link);
245 return -ENODEV; 246 return -ENODEV;
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 7445cc8a47d3..7be3b3357045 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -161,11 +161,9 @@ static int snd_vxpocket_new(struct snd_card *card, int ibl,
161 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO; 161 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
162 link->io.NumPorts1 = 16; 162 link->io.NumPorts1 = 16;
163 163
164 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; 164 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
165 165
166 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
167 link->irq.Handler = &snd_vx_irq_handler; 166 link->irq.Handler = &snd_vx_irq_handler;
168 link->irq.Instance = chip;
169 167
170 link->conf.Attributes = CONF_ENABLE_IRQ; 168 link->conf.Attributes = CONF_ENABLE_IRQ;
171 link->conf.IntType = INT_MEMORY_AND_IO; 169 link->conf.IntType = INT_MEMORY_AND_IO;
@@ -213,14 +211,11 @@ static int snd_vxpocket_assign_resources(struct vx_core *chip, int port, int irq
213 * configuration callback 211 * configuration callback
214 */ 212 */
215 213
216#define CS_CHECK(fn, ret) \
217do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
218
219static int vxpocket_config(struct pcmcia_device *link) 214static int vxpocket_config(struct pcmcia_device *link)
220{ 215{
221 struct vx_core *chip = link->priv; 216 struct vx_core *chip = link->priv;
222 struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip; 217 struct snd_vxpocket *vxp = (struct snd_vxpocket *)chip;
223 int last_fn, last_ret; 218 int ret;
224 219
225 snd_printdd(KERN_DEBUG "vxpocket_config called\n"); 220 snd_printdd(KERN_DEBUG "vxpocket_config called\n");
226 221
@@ -235,11 +230,19 @@ static int vxpocket_config(struct pcmcia_device *link)
235 strcpy(chip->card->driver, vxp440_hw.name); 230 strcpy(chip->card->driver, vxp440_hw.name);
236 } 231 }
237 232
238 CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io)); 233 ret = pcmcia_request_io(link, &link->io);
239 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq)); 234 if (ret)
240 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf)); 235 goto failed;
236
237 ret = pcmcia_request_irq(link, &link->irq);
238 if (ret)
239 goto failed;
240
241 ret = pcmcia_request_configuration(link, &link->conf);
242 if (ret)
243 goto failed;
241 244
242 chip->dev = &handle_to_dev(link); 245 chip->dev = &link->dev;
243 snd_card_set_dev(chip->card, chip->dev); 246 snd_card_set_dev(chip->card, chip->dev);
244 247
245 if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0) 248 if (snd_vxpocket_assign_resources(chip, link->io.BasePort1, link->irq.AssignedIRQ) < 0)
@@ -248,8 +251,6 @@ static int vxpocket_config(struct pcmcia_device *link)
248 link->dev_node = &vxp->node; 251 link->dev_node = &vxp->node;
249 return 0; 252 return 0;
250 253
251cs_failed:
252 cs_error(link, last_fn, last_ret);
253failed: 254failed:
254 pcmcia_disable_device(link); 255 pcmcia_disable_device(link);
255 return -ENODEV; 256 return -ENODEV;
diff --git a/sound/ppc/Kconfig b/sound/ppc/Kconfig
index bd2338ab2ced..0519c60f5be1 100644
--- a/sound/ppc/Kconfig
+++ b/sound/ppc/Kconfig
@@ -2,7 +2,7 @@
2 2
3menuconfig SND_PPC 3menuconfig SND_PPC
4 bool "PowerPC sound devices" 4 bool "PowerPC sound devices"
5 depends on PPC64 || PPC32 5 depends on PPC
6 default y 6 default y
7 help 7 help
8 Support for sound devices specific to PowerPC architectures. 8 Support for sound devices specific to PowerPC architectures.
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 583a3693df75..a0df401ebb9f 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -49,6 +49,7 @@ MODULE_AUTHOR("Adrian McMenamin <adrian@mcmen.demon.co.uk>");
49MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver"); 49MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver");
50MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
51MODULE_SUPPORTED_DEVICE("{{Yamaha/SEGA, AICA}}"); 51MODULE_SUPPORTED_DEVICE("{{Yamaha/SEGA, AICA}}");
52MODULE_FIRMWARE("aica_firmware.bin");
52 53
53/* module parameters */ 54/* module parameters */
54#define CARD_NAME "AICA" 55#define CARD_NAME "AICA"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 0c5eac01bf2e..1470141d4167 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,4 +1,4 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o 1snd-soc-core-objs := soc-core.o soc-dapm.o soc-jack.o soc-cache.o soc-utils.o
2 2
3obj-$(CONFIG_SND_SOC) += snd-soc-core.o 3obj-$(CONFIG_SND_SOC) += snd-soc-core.o
4obj-$(CONFIG_SND_SOC) += codecs/ 4obj-$(CONFIG_SND_SOC) += codecs/
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 9eb610c2ba91..9df4c68ef000 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -268,7 +268,7 @@ static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream,
268#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ 268#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */
269 269
270 270
271 ret = snd_soc_dai_set_pll(codec_dai, 0, 271 ret = snd_soc_dai_set_pll(codec_dai, 0, 0,
272 clk_get_rate(CODEC_CLK), pll_out); 272 clk_get_rate(CODEC_CLK), pll_out);
273 if (ret < 0) { 273 if (ret < 0) {
274 pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n", 274 pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n",
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index 885ba012557e..e028744c32ce 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -207,7 +207,7 @@ static int __init at91sam9g20ek_init(void)
207 struct clk *pllb; 207 struct clk *pllb;
208 int ret; 208 int ret;
209 209
210 if (!machine_is_at91sam9g20ek()) 210 if (!(machine_is_at91sam9g20ek() || machine_is_at91sam9g20ek_2mmc()))
211 return -ENODEV; 211 return -ENODEV;
212 212
213 /* 213 /*
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 594c6c5b7838..19e4d37eba1c 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -2,7 +2,7 @@
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -333,6 +333,30 @@ static int au1xpsc_pcm_new(struct snd_card *card,
333 333
334static int au1xpsc_pcm_probe(struct platform_device *pdev) 334static int au1xpsc_pcm_probe(struct platform_device *pdev)
335{ 335{
336 if (!au1xpsc_audio_pcmdma[PCM_TX] || !au1xpsc_audio_pcmdma[PCM_RX])
337 return -ENODEV;
338
339 return 0;
340}
341
342static int au1xpsc_pcm_remove(struct platform_device *pdev)
343{
344 return 0;
345}
346
347/* au1xpsc audio platform */
348struct snd_soc_platform au1xpsc_soc_platform = {
349 .name = "au1xpsc-pcm-dbdma",
350 .probe = au1xpsc_pcm_probe,
351 .remove = au1xpsc_pcm_remove,
352 .pcm_ops = &au1xpsc_pcm_ops,
353 .pcm_new = au1xpsc_pcm_new,
354 .pcm_free = au1xpsc_pcm_free_dma_buffers,
355};
356EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
357
358static int __devinit au1xpsc_pcm_drvprobe(struct platform_device *pdev)
359{
336 struct resource *r; 360 struct resource *r;
337 int ret; 361 int ret;
338 362
@@ -365,7 +389,9 @@ static int au1xpsc_pcm_probe(struct platform_device *pdev)
365 } 389 }
366 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start; 390 (au1xpsc_audio_pcmdma[PCM_RX])->ddma_id = r->start;
367 391
368 return 0; 392 ret = snd_soc_register_platform(&au1xpsc_soc_platform);
393 if (!ret)
394 return ret;
369 395
370out2: 396out2:
371 kfree(au1xpsc_audio_pcmdma[PCM_RX]); 397 kfree(au1xpsc_audio_pcmdma[PCM_RX]);
@@ -376,10 +402,12 @@ out1:
376 return ret; 402 return ret;
377} 403}
378 404
379static int au1xpsc_pcm_remove(struct platform_device *pdev) 405static int __devexit au1xpsc_pcm_drvremove(struct platform_device *pdev)
380{ 406{
381 int i; 407 int i;
382 408
409 snd_soc_unregister_platform(&au1xpsc_soc_platform);
410
383 for (i = 0; i < 2; i++) { 411 for (i = 0; i < 2; i++) {
384 if (au1xpsc_audio_pcmdma[i]) { 412 if (au1xpsc_audio_pcmdma[i]) {
385 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]); 413 au1x_pcm_dbdma_free(au1xpsc_audio_pcmdma[i]);
@@ -391,32 +419,81 @@ static int au1xpsc_pcm_remove(struct platform_device *pdev)
391 return 0; 419 return 0;
392} 420}
393 421
394/* au1xpsc audio platform */ 422static struct platform_driver au1xpsc_pcm_driver = {
395struct snd_soc_platform au1xpsc_soc_platform = { 423 .driver = {
396 .name = "au1xpsc-pcm-dbdma", 424 .name = "au1xpsc-pcm",
397 .probe = au1xpsc_pcm_probe, 425 .owner = THIS_MODULE,
398 .remove = au1xpsc_pcm_remove, 426 },
399 .pcm_ops = &au1xpsc_pcm_ops, 427 .probe = au1xpsc_pcm_drvprobe,
400 .pcm_new = au1xpsc_pcm_new, 428 .remove = __devexit_p(au1xpsc_pcm_drvremove),
401 .pcm_free = au1xpsc_pcm_free_dma_buffers,
402}; 429};
403EXPORT_SYMBOL_GPL(au1xpsc_soc_platform);
404 430
405static int __init au1xpsc_audio_dbdma_init(void) 431static int __init au1xpsc_audio_dbdma_load(void)
406{ 432{
407 au1xpsc_audio_pcmdma[PCM_TX] = NULL; 433 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
408 au1xpsc_audio_pcmdma[PCM_RX] = NULL; 434 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
409 return snd_soc_register_platform(&au1xpsc_soc_platform); 435 return platform_driver_register(&au1xpsc_pcm_driver);
410} 436}
411 437
412static void __exit au1xpsc_audio_dbdma_exit(void) 438static void __exit au1xpsc_audio_dbdma_unload(void)
413{ 439{
414 snd_soc_unregister_platform(&au1xpsc_soc_platform); 440 platform_driver_unregister(&au1xpsc_pcm_driver);
415} 441}
416 442
417module_init(au1xpsc_audio_dbdma_init); 443module_init(au1xpsc_audio_dbdma_load);
418module_exit(au1xpsc_audio_dbdma_exit); 444module_exit(au1xpsc_audio_dbdma_unload);
445
446
447struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev)
448{
449 struct resource *res, *r;
450 struct platform_device *pd;
451 int id[2];
452 int ret;
453
454 r = platform_get_resource(pdev, IORESOURCE_DMA, 0);
455 if (!r)
456 return NULL;
457 id[0] = r->start;
458
459 r = platform_get_resource(pdev, IORESOURCE_DMA, 1);
460 if (!r)
461 return NULL;
462 id[1] = r->start;
463
464 res = kzalloc(sizeof(struct resource) * 2, GFP_KERNEL);
465 if (!res)
466 return NULL;
467
468 res[0].start = res[0].end = id[0];
469 res[1].start = res[1].end = id[1];
470 res[0].flags = res[1].flags = IORESOURCE_DMA;
471
472 pd = platform_device_alloc("au1xpsc-pcm", -1);
473 if (!pd)
474 goto out;
475
476 pd->resource = res;
477 pd->num_resources = 2;
478
479 ret = platform_device_add(pd);
480 if (!ret)
481 return pd;
482
483 platform_device_put(pd);
484out:
485 kfree(res);
486 return NULL;
487}
488EXPORT_SYMBOL_GPL(au1xpsc_pcm_add);
489
490void au1xpsc_pcm_destroy(struct platform_device *dmapd)
491{
492 if (dmapd)
493 platform_device_unregister(dmapd);
494}
495EXPORT_SYMBOL_GPL(au1xpsc_pcm_destroy);
419 496
420MODULE_LICENSE("GPL"); 497MODULE_LICENSE("GPL");
421MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver"); 498MODULE_DESCRIPTION("Au12x0/Au1550 PSC Audio DMA driver");
422MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 499MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index a521aa90ddee..340311d7fed5 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -61,7 +61,8 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
61{ 61{
62 /* FIXME */ 62 /* FIXME */
63 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 63 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
64 unsigned short data, retry, tmo; 64 unsigned short retry, tmo;
65 unsigned long data;
65 66
66 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 67 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
67 au_sync(); 68 au_sync();
@@ -74,20 +75,26 @@ static unsigned short au1xpsc_ac97_read(struct snd_ac97 *ac97,
74 AC97_CDC(pscdata)); 75 AC97_CDC(pscdata));
75 au_sync(); 76 au_sync();
76 77
77 tmo = 2000; 78 tmo = 20;
78 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) 79 do {
79 && --tmo) 80 udelay(21);
80 udelay(2); 81 if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)
82 break;
83 } while (--tmo);
81 84
82 data = au_readl(AC97_CDC(pscdata)) & 0xffff; 85 data = au_readl(AC97_CDC(pscdata));
83 86
84 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 87 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
85 au_sync(); 88 au_sync();
86 89
87 mutex_unlock(&pscdata->lock); 90 mutex_unlock(&pscdata->lock);
91
92 if (reg != ((data >> 16) & 0x7f))
93 tmo = 1; /* wrong register, try again */
94
88 } while (--retry && !tmo); 95 } while (--retry && !tmo);
89 96
90 return retry ? data : 0xffff; 97 return retry ? data & 0xffff : 0xffff;
91} 98}
92 99
93/* AC97 controller writes to codec register */ 100/* AC97 controller writes to codec register */
@@ -109,10 +116,12 @@ static void au1xpsc_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
109 AC97_CDC(pscdata)); 116 AC97_CDC(pscdata));
110 au_sync(); 117 au_sync();
111 118
112 tmo = 2000; 119 tmo = 20;
113 while ((!(au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)) 120 do {
114 && --tmo) 121 udelay(21);
115 udelay(2); 122 if (au_readl(AC97_EVNT(pscdata)) & PSC_AC97EVNT_CD)
123 break;
124 } while (--tmo);
116 125
117 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata)); 126 au_writel(PSC_AC97EVNT_CD, AC97_EVNT(pscdata));
118 au_sync(); 127 au_sync();
@@ -195,7 +204,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
195 /* FIXME */ 204 /* FIXME */
196 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 205 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
197 unsigned long r, ro, stat; 206 unsigned long r, ro, stat;
198 int chans, stype = SUBSTREAM_TYPE(substream); 207 int chans, t, stype = SUBSTREAM_TYPE(substream);
199 208
200 chans = params_channels(params); 209 chans = params_channels(params);
201 210
@@ -237,8 +246,12 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
237 au_sync(); 246 au_sync();
238 247
239 /* ...wait for it... */ 248 /* ...wait for it... */
240 while (au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) 249 t = 100;
241 asm volatile ("nop"); 250 while ((au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR) && --t)
251 msleep(1);
252
253 if (!t)
254 printk(KERN_ERR "PSC-AC97: can't disable!\n");
242 255
243 /* ...write config... */ 256 /* ...write config... */
244 au_writel(r, AC97_CFG(pscdata)); 257 au_writel(r, AC97_CFG(pscdata));
@@ -249,8 +262,12 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
249 au_sync(); 262 au_sync();
250 263
251 /* ...and wait for ready bit */ 264 /* ...and wait for ready bit */
252 while (!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) 265 t = 100;
253 asm volatile ("nop"); 266 while ((!(au_readl(AC97_STAT(pscdata)) & PSC_AC97STAT_DR)) && --t)
267 msleep(1);
268
269 if (!t)
270 printk(KERN_ERR "PSC-AC97: can't enable!\n");
254 271
255 mutex_unlock(&pscdata->lock); 272 mutex_unlock(&pscdata->lock);
256 273
@@ -300,19 +317,55 @@ static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
300static int au1xpsc_ac97_probe(struct platform_device *pdev, 317static int au1xpsc_ac97_probe(struct platform_device *pdev,
301 struct snd_soc_dai *dai) 318 struct snd_soc_dai *dai)
302{ 319{
320 return au1xpsc_ac97_workdata ? 0 : -ENODEV;
321}
322
323static void au1xpsc_ac97_remove(struct platform_device *pdev,
324 struct snd_soc_dai *dai)
325{
326}
327
328static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = {
329 .trigger = au1xpsc_ac97_trigger,
330 .hw_params = au1xpsc_ac97_hw_params,
331};
332
333struct snd_soc_dai au1xpsc_ac97_dai = {
334 .name = "au1xpsc_ac97",
335 .ac97_control = 1,
336 .probe = au1xpsc_ac97_probe,
337 .remove = au1xpsc_ac97_remove,
338 .playback = {
339 .rates = AC97_RATES,
340 .formats = AC97_FMTS,
341 .channels_min = 2,
342 .channels_max = 2,
343 },
344 .capture = {
345 .rates = AC97_RATES,
346 .formats = AC97_FMTS,
347 .channels_min = 2,
348 .channels_max = 2,
349 },
350 .ops = &au1xpsc_ac97_dai_ops,
351};
352EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
353
354static int __devinit au1xpsc_ac97_drvprobe(struct platform_device *pdev)
355{
303 int ret; 356 int ret;
304 struct resource *r; 357 struct resource *r;
305 unsigned long sel; 358 unsigned long sel;
359 struct au1xpsc_audio_data *wd;
306 360
307 if (au1xpsc_ac97_workdata) 361 if (au1xpsc_ac97_workdata)
308 return -EBUSY; 362 return -EBUSY;
309 363
310 au1xpsc_ac97_workdata = 364 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
311 kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); 365 if (!wd)
312 if (!au1xpsc_ac97_workdata)
313 return -ENOMEM; 366 return -ENOMEM;
314 367
315 mutex_init(&au1xpsc_ac97_workdata->lock); 368 mutex_init(&wd->lock);
316 369
317 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 370 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
318 if (!r) { 371 if (!r) {
@@ -321,81 +374,95 @@ static int au1xpsc_ac97_probe(struct platform_device *pdev,
321 } 374 }
322 375
323 ret = -EBUSY; 376 ret = -EBUSY;
324 au1xpsc_ac97_workdata->ioarea = 377 wd->ioarea = request_mem_region(r->start, r->end - r->start + 1,
325 request_mem_region(r->start, r->end - r->start + 1,
326 "au1xpsc_ac97"); 378 "au1xpsc_ac97");
327 if (!au1xpsc_ac97_workdata->ioarea) 379 if (!wd->ioarea)
328 goto out0; 380 goto out0;
329 381
330 au1xpsc_ac97_workdata->mmio = ioremap(r->start, 0xffff); 382 wd->mmio = ioremap(r->start, 0xffff);
331 if (!au1xpsc_ac97_workdata->mmio) 383 if (!wd->mmio)
332 goto out1; 384 goto out1;
333 385
334 /* configuration: max dma trigger threshold, enable ac97 */ 386 /* configuration: max dma trigger threshold, enable ac97 */
335 au1xpsc_ac97_workdata->cfg = PSC_AC97CFG_RT_FIFO8 | 387 wd->cfg = PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8 |
336 PSC_AC97CFG_TT_FIFO8 | 388 PSC_AC97CFG_DE_ENABLE;
337 PSC_AC97CFG_DE_ENABLE;
338 389
339 /* preserve PSC clock source set up by platform (dev.platform_data 390 /* preserve PSC clock source set up by platform */
340 * is already occupied by soc layer) 391 sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
341 */ 392 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
342 sel = au_readl(PSC_SEL(au1xpsc_ac97_workdata)) & PSC_SEL_CLK_MASK;
343 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata));
344 au_sync(); 393 au_sync();
345 au_writel(0, PSC_SEL(au1xpsc_ac97_workdata)); 394 au_writel(0, PSC_SEL(wd));
346 au_sync(); 395 au_sync();
347 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(au1xpsc_ac97_workdata)); 396 au_writel(PSC_SEL_PS_AC97MODE | sel, PSC_SEL(wd));
348 au_sync(); 397 au_sync();
349 /* next up: cold reset. Dont check for PSC-ready now since
350 * there may not be any codec clock yet.
351 */
352 398
353 return 0; 399 ret = snd_soc_register_dai(&au1xpsc_ac97_dai);
400 if (ret)
401 goto out1;
354 402
403 wd->dmapd = au1xpsc_pcm_add(pdev);
404 if (wd->dmapd) {
405 platform_set_drvdata(pdev, wd);
406 au1xpsc_ac97_workdata = wd; /* MDEV */
407 return 0;
408 }
409
410 snd_soc_unregister_dai(&au1xpsc_ac97_dai);
355out1: 411out1:
356 release_resource(au1xpsc_ac97_workdata->ioarea); 412 release_resource(wd->ioarea);
357 kfree(au1xpsc_ac97_workdata->ioarea); 413 kfree(wd->ioarea);
358out0: 414out0:
359 kfree(au1xpsc_ac97_workdata); 415 kfree(wd);
360 au1xpsc_ac97_workdata = NULL;
361 return ret; 416 return ret;
362} 417}
363 418
364static void au1xpsc_ac97_remove(struct platform_device *pdev, 419static int __devexit au1xpsc_ac97_drvremove(struct platform_device *pdev)
365 struct snd_soc_dai *dai)
366{ 420{
421 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
422
423 if (wd->dmapd)
424 au1xpsc_pcm_destroy(wd->dmapd);
425
426 snd_soc_unregister_dai(&au1xpsc_ac97_dai);
427
367 /* disable PSC completely */ 428 /* disable PSC completely */
368 au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); 429 au_writel(0, AC97_CFG(wd));
369 au_sync(); 430 au_sync();
370 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata)); 431 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
371 au_sync(); 432 au_sync();
372 433
373 iounmap(au1xpsc_ac97_workdata->mmio); 434 iounmap(wd->mmio);
374 release_resource(au1xpsc_ac97_workdata->ioarea); 435 release_resource(wd->ioarea);
375 kfree(au1xpsc_ac97_workdata->ioarea); 436 kfree(wd->ioarea);
376 kfree(au1xpsc_ac97_workdata); 437 kfree(wd);
377 au1xpsc_ac97_workdata = NULL; 438
439 au1xpsc_ac97_workdata = NULL; /* MDEV */
440
441 return 0;
378} 442}
379 443
380static int au1xpsc_ac97_suspend(struct snd_soc_dai *dai) 444#ifdef CONFIG_PM
445static int au1xpsc_ac97_drvsuspend(struct device *dev)
381{ 446{
447 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
448
382 /* save interesting registers and disable PSC */ 449 /* save interesting registers and disable PSC */
383 au1xpsc_ac97_workdata->pm[0] = 450 wd->pm[0] = au_readl(PSC_SEL(wd));
384 au_readl(PSC_SEL(au1xpsc_ac97_workdata));
385 451
386 au_writel(0, AC97_CFG(au1xpsc_ac97_workdata)); 452 au_writel(0, AC97_CFG(wd));
387 au_sync(); 453 au_sync();
388 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_ac97_workdata)); 454 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
389 au_sync(); 455 au_sync();
390 456
391 return 0; 457 return 0;
392} 458}
393 459
394static int au1xpsc_ac97_resume(struct snd_soc_dai *dai) 460static int au1xpsc_ac97_drvresume(struct device *dev)
395{ 461{
462 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
463
396 /* restore PSC clock config */ 464 /* restore PSC clock config */
397 au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE, 465 au_writel(wd->pm[0] | PSC_SEL_PS_AC97MODE, PSC_SEL(wd));
398 PSC_SEL(au1xpsc_ac97_workdata));
399 au_sync(); 466 au_sync();
400 467
401 /* after this point the ac97 core will cold-reset the codec. 468 /* after this point the ac97 core will cold-reset the codec.
@@ -405,48 +472,44 @@ static int au1xpsc_ac97_resume(struct snd_soc_dai *dai)
405 return 0; 472 return 0;
406} 473}
407 474
408static struct snd_soc_dai_ops au1xpsc_ac97_dai_ops = { 475static struct dev_pm_ops au1xpscac97_pmops = {
409 .trigger = au1xpsc_ac97_trigger, 476 .suspend = au1xpsc_ac97_drvsuspend,
410 .hw_params = au1xpsc_ac97_hw_params, 477 .resume = au1xpsc_ac97_drvresume,
411}; 478};
412 479
413struct snd_soc_dai au1xpsc_ac97_dai = { 480#define AU1XPSCAC97_PMOPS &au1xpscac97_pmops
414 .name = "au1xpsc_ac97", 481
415 .ac97_control = 1, 482#else
416 .probe = au1xpsc_ac97_probe, 483
417 .remove = au1xpsc_ac97_remove, 484#define AU1XPSCAC97_PMOPS NULL
418 .suspend = au1xpsc_ac97_suspend, 485
419 .resume = au1xpsc_ac97_resume, 486#endif
420 .playback = { 487
421 .rates = AC97_RATES, 488static struct platform_driver au1xpsc_ac97_driver = {
422 .formats = AC97_FMTS, 489 .driver = {
423 .channels_min = 2, 490 .name = "au1xpsc_ac97",
424 .channels_max = 2, 491 .owner = THIS_MODULE,
425 }, 492 .pm = AU1XPSCAC97_PMOPS,
426 .capture = {
427 .rates = AC97_RATES,
428 .formats = AC97_FMTS,
429 .channels_min = 2,
430 .channels_max = 2,
431 }, 493 },
432 .ops = &au1xpsc_ac97_dai_ops, 494 .probe = au1xpsc_ac97_drvprobe,
495 .remove = __devexit_p(au1xpsc_ac97_drvremove),
433}; 496};
434EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
435 497
436static int __init au1xpsc_ac97_init(void) 498static int __init au1xpsc_ac97_load(void)
437{ 499{
438 au1xpsc_ac97_workdata = NULL; 500 au1xpsc_ac97_workdata = NULL;
439 return snd_soc_register_dai(&au1xpsc_ac97_dai); 501 return platform_driver_register(&au1xpsc_ac97_driver);
440} 502}
441 503
442static void __exit au1xpsc_ac97_exit(void) 504static void __exit au1xpsc_ac97_unload(void)
443{ 505{
444 snd_soc_unregister_dai(&au1xpsc_ac97_dai); 506 platform_driver_unregister(&au1xpsc_ac97_driver);
445} 507}
446 508
447module_init(au1xpsc_ac97_init); 509module_init(au1xpsc_ac97_load);
448module_exit(au1xpsc_ac97_exit); 510module_exit(au1xpsc_ac97_unload);
449 511
450MODULE_LICENSE("GPL"); 512MODULE_LICENSE("GPL");
451MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver"); 513MODULE_DESCRIPTION("Au12x0/Au1550 PSC AC97 ALSA ASoC audio driver");
452MODULE_AUTHOR("Manuel Lauss <manuel.lauss@gmail.com>"); 514MODULE_AUTHOR("Manuel Lauss");
515
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index bb589327ee32..0cf2ca61c776 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -2,7 +2,7 @@
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -265,16 +265,52 @@ static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
265static int au1xpsc_i2s_probe(struct platform_device *pdev, 265static int au1xpsc_i2s_probe(struct platform_device *pdev,
266 struct snd_soc_dai *dai) 266 struct snd_soc_dai *dai)
267{ 267{
268 return au1xpsc_i2s_workdata ? 0 : -ENODEV;
269}
270
271static void au1xpsc_i2s_remove(struct platform_device *pdev,
272 struct snd_soc_dai *dai)
273{
274}
275
276static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = {
277 .trigger = au1xpsc_i2s_trigger,
278 .hw_params = au1xpsc_i2s_hw_params,
279 .set_fmt = au1xpsc_i2s_set_fmt,
280};
281
282struct snd_soc_dai au1xpsc_i2s_dai = {
283 .name = "au1xpsc_i2s",
284 .probe = au1xpsc_i2s_probe,
285 .remove = au1xpsc_i2s_remove,
286 .playback = {
287 .rates = AU1XPSC_I2S_RATES,
288 .formats = AU1XPSC_I2S_FMTS,
289 .channels_min = 2,
290 .channels_max = 8, /* 2 without external help */
291 },
292 .capture = {
293 .rates = AU1XPSC_I2S_RATES,
294 .formats = AU1XPSC_I2S_FMTS,
295 .channels_min = 2,
296 .channels_max = 8, /* 2 without external help */
297 },
298 .ops = &au1xpsc_i2s_dai_ops,
299};
300EXPORT_SYMBOL(au1xpsc_i2s_dai);
301
302static int __init au1xpsc_i2s_drvprobe(struct platform_device *pdev)
303{
268 struct resource *r; 304 struct resource *r;
269 unsigned long sel; 305 unsigned long sel;
270 int ret; 306 int ret;
307 struct au1xpsc_audio_data *wd;
271 308
272 if (au1xpsc_i2s_workdata) 309 if (au1xpsc_i2s_workdata)
273 return -EBUSY; 310 return -EBUSY;
274 311
275 au1xpsc_i2s_workdata = 312 wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
276 kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL); 313 if (!wd)
277 if (!au1xpsc_i2s_workdata)
278 return -ENOMEM; 314 return -ENOMEM;
279 315
280 r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 316 r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -284,131 +320,146 @@ static int au1xpsc_i2s_probe(struct platform_device *pdev,
284 } 320 }
285 321
286 ret = -EBUSY; 322 ret = -EBUSY;
287 au1xpsc_i2s_workdata->ioarea = 323 wd->ioarea = request_mem_region(r->start, r->end - r->start + 1,
288 request_mem_region(r->start, r->end - r->start + 1,
289 "au1xpsc_i2s"); 324 "au1xpsc_i2s");
290 if (!au1xpsc_i2s_workdata->ioarea) 325 if (!wd->ioarea)
291 goto out0; 326 goto out0;
292 327
293 au1xpsc_i2s_workdata->mmio = ioremap(r->start, 0xffff); 328 wd->mmio = ioremap(r->start, 0xffff);
294 if (!au1xpsc_i2s_workdata->mmio) 329 if (!wd->mmio)
295 goto out1; 330 goto out1;
296 331
297 /* preserve PSC clock source set up by platform (dev.platform_data 332 /* preserve PSC clock source set up by platform (dev.platform_data
298 * is already occupied by soc layer) 333 * is already occupied by soc layer)
299 */ 334 */
300 sel = au_readl(PSC_SEL(au1xpsc_i2s_workdata)) & PSC_SEL_CLK_MASK; 335 sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
301 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 336 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
302 au_sync(); 337 au_sync();
303 au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(au1xpsc_i2s_workdata)); 338 au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(wd));
304 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); 339 au_writel(0, I2S_CFG(wd));
305 au_sync(); 340 au_sync();
306 341
307 /* preconfigure: set max rx/tx fifo depths */ 342 /* preconfigure: set max rx/tx fifo depths */
308 au1xpsc_i2s_workdata->cfg |= 343 wd->cfg |= PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8;
309 PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8;
310 344
311 /* don't wait for I2S core to become ready now; clocks may not 345 /* don't wait for I2S core to become ready now; clocks may not
312 * be running yet; depending on clock input for PSC a wait might 346 * be running yet; depending on clock input for PSC a wait might
313 * time out. 347 * time out.
314 */ 348 */
315 349
316 return 0; 350 ret = snd_soc_register_dai(&au1xpsc_i2s_dai);
351 if (ret)
352 goto out1;
317 353
354 /* finally add the DMA device for this PSC */
355 wd->dmapd = au1xpsc_pcm_add(pdev);
356 if (wd->dmapd) {
357 platform_set_drvdata(pdev, wd);
358 au1xpsc_i2s_workdata = wd;
359 return 0;
360 }
361
362 snd_soc_unregister_dai(&au1xpsc_i2s_dai);
318out1: 363out1:
319 release_resource(au1xpsc_i2s_workdata->ioarea); 364 release_resource(wd->ioarea);
320 kfree(au1xpsc_i2s_workdata->ioarea); 365 kfree(wd->ioarea);
321out0: 366out0:
322 kfree(au1xpsc_i2s_workdata); 367 kfree(wd);
323 au1xpsc_i2s_workdata = NULL;
324 return ret; 368 return ret;
325} 369}
326 370
327static void au1xpsc_i2s_remove(struct platform_device *pdev, 371static int __devexit au1xpsc_i2s_drvremove(struct platform_device *pdev)
328 struct snd_soc_dai *dai)
329{ 372{
330 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); 373 struct au1xpsc_audio_data *wd = platform_get_drvdata(pdev);
374
375 if (wd->dmapd)
376 au1xpsc_pcm_destroy(wd->dmapd);
377
378 snd_soc_unregister_dai(&au1xpsc_i2s_dai);
379
380 au_writel(0, I2S_CFG(wd));
331 au_sync(); 381 au_sync();
332 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 382 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
333 au_sync(); 383 au_sync();
334 384
335 iounmap(au1xpsc_i2s_workdata->mmio); 385 iounmap(wd->mmio);
336 release_resource(au1xpsc_i2s_workdata->ioarea); 386 release_resource(wd->ioarea);
337 kfree(au1xpsc_i2s_workdata->ioarea); 387 kfree(wd->ioarea);
338 kfree(au1xpsc_i2s_workdata); 388 kfree(wd);
339 au1xpsc_i2s_workdata = NULL; 389
390 au1xpsc_i2s_workdata = NULL; /* MDEV */
391
392 return 0;
340} 393}
341 394
342static int au1xpsc_i2s_suspend(struct snd_soc_dai *cpu_dai) 395#ifdef CONFIG_PM
396static int au1xpsc_i2s_drvsuspend(struct device *dev)
343{ 397{
398 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
399
344 /* save interesting register and disable PSC */ 400 /* save interesting register and disable PSC */
345 au1xpsc_i2s_workdata->pm[0] = 401 wd->pm[0] = au_readl(PSC_SEL(wd));
346 au_readl(PSC_SEL(au1xpsc_i2s_workdata));
347 402
348 au_writel(0, I2S_CFG(au1xpsc_i2s_workdata)); 403 au_writel(0, I2S_CFG(wd));
349 au_sync(); 404 au_sync();
350 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 405 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
351 au_sync(); 406 au_sync();
352 407
353 return 0; 408 return 0;
354} 409}
355 410
356static int au1xpsc_i2s_resume(struct snd_soc_dai *cpu_dai) 411static int au1xpsc_i2s_drvresume(struct device *dev)
357{ 412{
413 struct au1xpsc_audio_data *wd = dev_get_drvdata(dev);
414
358 /* select I2S mode and PSC clock */ 415 /* select I2S mode and PSC clock */
359 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 416 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
360 au_sync(); 417 au_sync();
361 au_writel(0, PSC_SEL(au1xpsc_i2s_workdata)); 418 au_writel(0, PSC_SEL(wd));
362 au_sync(); 419 au_sync();
363 au_writel(au1xpsc_i2s_workdata->pm[0], 420 au_writel(wd->pm[0], PSC_SEL(wd));
364 PSC_SEL(au1xpsc_i2s_workdata));
365 au_sync(); 421 au_sync();
366 422
367 return 0; 423 return 0;
368} 424}
369 425
370static struct snd_soc_dai_ops au1xpsc_i2s_dai_ops = { 426static struct dev_pm_ops au1xpsci2s_pmops = {
371 .trigger = au1xpsc_i2s_trigger, 427 .suspend = au1xpsc_i2s_drvsuspend,
372 .hw_params = au1xpsc_i2s_hw_params, 428 .resume = au1xpsc_i2s_drvresume,
373 .set_fmt = au1xpsc_i2s_set_fmt,
374}; 429};
375 430
376struct snd_soc_dai au1xpsc_i2s_dai = { 431#define AU1XPSCI2S_PMOPS &au1xpsci2s_pmops
377 .name = "au1xpsc_i2s", 432
378 .probe = au1xpsc_i2s_probe, 433#else
379 .remove = au1xpsc_i2s_remove, 434
380 .suspend = au1xpsc_i2s_suspend, 435#define AU1XPSCI2S_PMOPS NULL
381 .resume = au1xpsc_i2s_resume, 436
382 .playback = { 437#endif
383 .rates = AU1XPSC_I2S_RATES, 438
384 .formats = AU1XPSC_I2S_FMTS, 439static struct platform_driver au1xpsc_i2s_driver = {
385 .channels_min = 2, 440 .driver = {
386 .channels_max = 8, /* 2 without external help */ 441 .name = "au1xpsc_i2s",
387 }, 442 .owner = THIS_MODULE,
388 .capture = { 443 .pm = AU1XPSCI2S_PMOPS,
389 .rates = AU1XPSC_I2S_RATES,
390 .formats = AU1XPSC_I2S_FMTS,
391 .channels_min = 2,
392 .channels_max = 8, /* 2 without external help */
393 }, 444 },
394 .ops = &au1xpsc_i2s_dai_ops, 445 .probe = au1xpsc_i2s_drvprobe,
446 .remove = __devexit_p(au1xpsc_i2s_drvremove),
395}; 447};
396EXPORT_SYMBOL(au1xpsc_i2s_dai);
397 448
398static int __init au1xpsc_i2s_init(void) 449static int __init au1xpsc_i2s_load(void)
399{ 450{
400 au1xpsc_i2s_workdata = NULL; 451 au1xpsc_i2s_workdata = NULL;
401 return snd_soc_register_dai(&au1xpsc_i2s_dai); 452 return platform_driver_register(&au1xpsc_i2s_driver);
402} 453}
403 454
404static void __exit au1xpsc_i2s_exit(void) 455static void __exit au1xpsc_i2s_unload(void)
405{ 456{
406 snd_soc_unregister_dai(&au1xpsc_i2s_dai); 457 platform_driver_unregister(&au1xpsc_i2s_driver);
407} 458}
408 459
409module_init(au1xpsc_i2s_init); 460module_init(au1xpsc_i2s_load);
410module_exit(au1xpsc_i2s_exit); 461module_exit(au1xpsc_i2s_unload);
411 462
412MODULE_LICENSE("GPL"); 463MODULE_LICENSE("GPL");
413MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver"); 464MODULE_DESCRIPTION("Au12x0/Au1550 PSC I2S ALSA ASoC audio driver");
414MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 465MODULE_AUTHOR("Manuel Lauss");
diff --git a/sound/soc/au1x/psc.h b/sound/soc/au1x/psc.h
index 3f474e8ed4f6..32d3807d3f5a 100644
--- a/sound/soc/au1x/psc.h
+++ b/sound/soc/au1x/psc.h
@@ -2,7 +2,7 @@
2 * Au12x0/Au1550 PSC ALSA ASoC audio support. 2 * Au12x0/Au1550 PSC ALSA ASoC audio support.
3 * 3 *
4 * (c) 2007-2008 MSC Vertriebsges.m.b.H., 4 * (c) 2007-2008 MSC Vertriebsges.m.b.H.,
5 * Manuel Lauss <mano@roarinelk.homelinux.net> 5 * Manuel Lauss <manuel.lauss@gmail.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -21,6 +21,10 @@ extern struct snd_soc_dai au1xpsc_i2s_dai;
21extern struct snd_soc_platform au1xpsc_soc_platform; 21extern struct snd_soc_platform au1xpsc_soc_platform;
22extern struct snd_ac97_bus_ops soc_ac97_ops; 22extern struct snd_ac97_bus_ops soc_ac97_ops;
23 23
24/* DBDMA helpers */
25extern struct platform_device *au1xpsc_pcm_add(struct platform_device *pdev);
26extern void au1xpsc_pcm_destroy(struct platform_device *dmapd);
27
24struct au1xpsc_audio_data { 28struct au1xpsc_audio_data {
25 void __iomem *mmio; 29 void __iomem *mmio;
26 30
@@ -30,6 +34,7 @@ struct au1xpsc_audio_data {
30 unsigned long pm[2]; 34 unsigned long pm[2];
31 struct resource *ioarea; 35 struct resource *ioarea;
32 struct mutex lock; 36 struct mutex lock;
37 struct platform_device *dmapd;
33}; 38};
34 39
35#define PCM_TX 0 40#define PCM_TX 0
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index cd361e304b0f..0f45a3f56be8 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -52,6 +52,7 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
52 struct snd_soc_pcm_runtime *rtd = substream->private_data; 52 struct snd_soc_pcm_runtime *rtd = substream->private_data;
53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 53 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
54 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 54 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
55 unsigned int channel_map[] = {0, 4, 1, 5, 2, 6, 3, 7};
55 int ret = 0; 56 int ret = 0;
56 /* set cpu DAI configuration */ 57 /* set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 58 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
@@ -65,6 +66,12 @@ static int bf5xx_ad1836_hw_params(struct snd_pcm_substream *substream,
65 if (ret < 0) 66 if (ret < 0)
66 return ret; 67 return ret;
67 68
69 /* set cpu DAI channel mapping */
70 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
71 channel_map, ARRAY_SIZE(channel_map), channel_map);
72 if (ret < 0)
73 return ret;
74
68 return 0; 75 return 0;
69} 76}
70 77
diff --git a/sound/soc/blackfin/bf5xx-ad1938.c b/sound/soc/blackfin/bf5xx-ad1938.c
index 08269e91810c..2ef1e5013b8c 100644
--- a/sound/soc/blackfin/bf5xx-ad1938.c
+++ b/sound/soc/blackfin/bf5xx-ad1938.c
@@ -61,6 +61,7 @@ static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream,
61 struct snd_soc_pcm_runtime *rtd = substream->private_data; 61 struct snd_soc_pcm_runtime *rtd = substream->private_data;
62 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 62 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 63 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
64 unsigned int channel_map[] = {0, 1, 2, 3, 4, 5, 6, 7};
64 int ret = 0; 65 int ret = 0;
65 /* set cpu DAI configuration */ 66 /* set cpu DAI configuration */
66 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 67 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
@@ -75,7 +76,13 @@ static int bf5xx_ad1938_hw_params(struct snd_pcm_substream *substream,
75 return ret; 76 return ret;
76 77
77 /* set codec DAI slots, 8 channels, all channels are enabled */ 78 /* set codec DAI slots, 8 channels, all channels are enabled */
78 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 8); 79 ret = snd_soc_dai_set_tdm_slot(codec_dai, 0xFF, 0xFF, 8, 32);
80 if (ret < 0)
81 return ret;
82
83 /* set cpu DAI channel mapping */
84 ret = snd_soc_dai_set_channel_map(cpu_dai, ARRAY_SIZE(channel_map),
85 channel_map, ARRAY_SIZE(channel_map), channel_map);
79 if (ret < 0) 86 if (ret < 0)
80 return ret; 87 return ret;
81 88
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index 084b68884ada..3e6ada0dd1c4 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -49,7 +49,6 @@ struct bf5xx_i2s_port {
49 u16 rcr1; 49 u16 rcr1;
50 u16 tcr2; 50 u16 tcr2;
51 u16 rcr2; 51 u16 rcr2;
52 int counter;
53 int configured; 52 int configured;
54}; 53};
55 54
@@ -133,16 +132,6 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
133 return ret; 132 return ret;
134} 133}
135 134
136static int bf5xx_i2s_startup(struct snd_pcm_substream *substream,
137 struct snd_soc_dai *dai)
138{
139 pr_debug("%s enter\n", __func__);
140
141 /*this counter is used for counting how many pcm streams are opened*/
142 bf5xx_i2s.counter++;
143 return 0;
144}
145
146static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, 135static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
147 struct snd_pcm_hw_params *params, 136 struct snd_pcm_hw_params *params,
148 struct snd_soc_dai *dai) 137 struct snd_soc_dai *dai)
@@ -201,9 +190,8 @@ static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
201 struct snd_soc_dai *dai) 190 struct snd_soc_dai *dai)
202{ 191{
203 pr_debug("%s enter\n", __func__); 192 pr_debug("%s enter\n", __func__);
204 bf5xx_i2s.counter--;
205 /* No active stream, SPORT is allowed to be configured again. */ 193 /* No active stream, SPORT is allowed to be configured again. */
206 if (!bf5xx_i2s.counter) 194 if (!dai->active)
207 bf5xx_i2s.configured = 0; 195 bf5xx_i2s.configured = 0;
208} 196}
209 197
@@ -284,7 +272,6 @@ static int bf5xx_i2s_resume(struct snd_soc_dai *dai)
284 SNDRV_PCM_FMTBIT_S32_LE) 272 SNDRV_PCM_FMTBIT_S32_LE)
285 273
286static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = { 274static struct snd_soc_dai_ops bf5xx_i2s_dai_ops = {
287 .startup = bf5xx_i2s_startup,
288 .shutdown = bf5xx_i2s_shutdown, 275 .shutdown = bf5xx_i2s_shutdown,
289 .hw_params = bf5xx_i2s_hw_params, 276 .hw_params = bf5xx_i2s_hw_params,
290 .set_fmt = bf5xx_i2s_set_dai_fmt, 277 .set_fmt = bf5xx_i2s_set_dai_fmt,
diff --git a/sound/soc/blackfin/bf5xx-tdm-pcm.c b/sound/soc/blackfin/bf5xx-tdm-pcm.c
index ccb5e823bd18..a8c73cbbd685 100644
--- a/sound/soc/blackfin/bf5xx-tdm-pcm.c
+++ b/sound/soc/blackfin/bf5xx-tdm-pcm.c
@@ -43,7 +43,7 @@
43#include "bf5xx-tdm.h" 43#include "bf5xx-tdm.h"
44#include "bf5xx-sport.h" 44#include "bf5xx-sport.h"
45 45
46#define PCM_BUFFER_MAX 0x10000 46#define PCM_BUFFER_MAX 0x8000
47#define FRAGMENT_SIZE_MIN (4*1024) 47#define FRAGMENT_SIZE_MIN (4*1024)
48#define FRAGMENTS_MIN 2 48#define FRAGMENTS_MIN 2
49#define FRAGMENTS_MAX 32 49#define FRAGMENTS_MAX 32
@@ -177,6 +177,9 @@ out:
177static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel, 177static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
178 snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count) 178 snd_pcm_uframes_t pos, void *buf, snd_pcm_uframes_t count)
179{ 179{
180 struct snd_pcm_runtime *runtime = substream->runtime;
181 struct sport_device *sport = runtime->private_data;
182 struct bf5xx_tdm_port *tdm_port = sport->private_data;
180 unsigned int *src; 183 unsigned int *src;
181 unsigned int *dst; 184 unsigned int *dst;
182 int i; 185 int i;
@@ -188,7 +191,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
188 dst += pos * 8; 191 dst += pos * 8;
189 while (count--) { 192 while (count--) {
190 for (i = 0; i < substream->runtime->channels; i++) 193 for (i = 0; i < substream->runtime->channels; i++)
191 *(dst + i) = *src++; 194 *(dst + tdm_port->tx_map[i]) = *src++;
192 dst += 8; 195 dst += 8;
193 } 196 }
194 } else { 197 } else {
@@ -198,7 +201,7 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
198 src += pos * 8; 201 src += pos * 8;
199 while (count--) { 202 while (count--) {
200 for (i = 0; i < substream->runtime->channels; i++) 203 for (i = 0; i < substream->runtime->channels; i++)
201 *dst++ = *(src+i); 204 *dst++ = *(src + tdm_port->rx_map[i]);
202 src += 8; 205 src += 8;
203 } 206 }
204 } 207 }
diff --git a/sound/soc/blackfin/bf5xx-tdm.c b/sound/soc/blackfin/bf5xx-tdm.c
index ff546e91a22e..4b360124083e 100644
--- a/sound/soc/blackfin/bf5xx-tdm.c
+++ b/sound/soc/blackfin/bf5xx-tdm.c
@@ -46,14 +46,6 @@
46#include "bf5xx-sport.h" 46#include "bf5xx-sport.h"
47#include "bf5xx-tdm.h" 47#include "bf5xx-tdm.h"
48 48
49struct bf5xx_tdm_port {
50 u16 tcr1;
51 u16 rcr1;
52 u16 tcr2;
53 u16 rcr2;
54 int configured;
55};
56
57static struct bf5xx_tdm_port bf5xx_tdm; 49static struct bf5xx_tdm_port bf5xx_tdm;
58static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; 50static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
59 51
@@ -181,6 +173,40 @@ static void bf5xx_tdm_shutdown(struct snd_pcm_substream *substream,
181 bf5xx_tdm.configured = 0; 173 bf5xx_tdm.configured = 0;
182} 174}
183 175
176static int bf5xx_tdm_set_channel_map(struct snd_soc_dai *dai,
177 unsigned int tx_num, unsigned int *tx_slot,
178 unsigned int rx_num, unsigned int *rx_slot)
179{
180 int i;
181 unsigned int slot;
182 unsigned int tx_mapped = 0, rx_mapped = 0;
183
184 if ((tx_num > BFIN_TDM_DAI_MAX_SLOTS) ||
185 (rx_num > BFIN_TDM_DAI_MAX_SLOTS))
186 return -EINVAL;
187
188 for (i = 0; i < tx_num; i++) {
189 slot = tx_slot[i];
190 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
191 (!(tx_mapped & (1 << slot)))) {
192 bf5xx_tdm.tx_map[i] = slot;
193 tx_mapped |= 1 << slot;
194 } else
195 return -EINVAL;
196 }
197 for (i = 0; i < rx_num; i++) {
198 slot = rx_slot[i];
199 if ((slot < BFIN_TDM_DAI_MAX_SLOTS) &&
200 (!(rx_mapped & (1 << slot)))) {
201 bf5xx_tdm.rx_map[i] = slot;
202 rx_mapped |= 1 << slot;
203 } else
204 return -EINVAL;
205 }
206
207 return 0;
208}
209
184#ifdef CONFIG_PM 210#ifdef CONFIG_PM
185static int bf5xx_tdm_suspend(struct snd_soc_dai *dai) 211static int bf5xx_tdm_suspend(struct snd_soc_dai *dai)
186{ 212{
@@ -235,6 +261,7 @@ static struct snd_soc_dai_ops bf5xx_tdm_dai_ops = {
235 .hw_params = bf5xx_tdm_hw_params, 261 .hw_params = bf5xx_tdm_hw_params,
236 .set_fmt = bf5xx_tdm_set_dai_fmt, 262 .set_fmt = bf5xx_tdm_set_dai_fmt,
237 .shutdown = bf5xx_tdm_shutdown, 263 .shutdown = bf5xx_tdm_shutdown,
264 .set_channel_map = bf5xx_tdm_set_channel_map,
238}; 265};
239 266
240struct snd_soc_dai bf5xx_tdm_dai = { 267struct snd_soc_dai bf5xx_tdm_dai = {
@@ -300,6 +327,8 @@ static int __devinit bfin_tdm_probe(struct platform_device *pdev)
300 pr_err("Failed to register DAI: %d\n", ret); 327 pr_err("Failed to register DAI: %d\n", ret);
301 goto sport_config_err; 328 goto sport_config_err;
302 } 329 }
330
331 sport_handle->private_data = &bf5xx_tdm;
303 return 0; 332 return 0;
304 333
305sport_config_err: 334sport_config_err:
diff --git a/sound/soc/blackfin/bf5xx-tdm.h b/sound/soc/blackfin/bf5xx-tdm.h
index 618ec3d90cd4..04189a18c1ba 100644
--- a/sound/soc/blackfin/bf5xx-tdm.h
+++ b/sound/soc/blackfin/bf5xx-tdm.h
@@ -9,6 +9,17 @@
9#ifndef _BF5XX_TDM_H 9#ifndef _BF5XX_TDM_H
10#define _BF5XX_TDM_H 10#define _BF5XX_TDM_H
11 11
12#define BFIN_TDM_DAI_MAX_SLOTS 8
13struct bf5xx_tdm_port {
14 u16 tcr1;
15 u16 rcr1;
16 u16 tcr2;
17 u16 rcr2;
18 unsigned int tx_map[BFIN_TDM_DAI_MAX_SLOTS];
19 unsigned int rx_map[BFIN_TDM_DAI_MAX_SLOTS];
20 int configured;
21};
22
12extern struct snd_soc_dai bf5xx_tdm_dai; 23extern struct snd_soc_dai bf5xx_tdm_dai;
13 24
14#endif 25#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 0edca93af3b0..52b005f8fed4 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -15,10 +15,12 @@ config SND_SOC_ALL_CODECS
15 select SND_SOC_AD1836 if SPI_MASTER 15 select SND_SOC_AD1836 if SPI_MASTER
16 select SND_SOC_AD1938 if SPI_MASTER 16 select SND_SOC_AD1938 if SPI_MASTER
17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS 17 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
18 select SND_SOC_ADS117X
18 select SND_SOC_AD73311 if I2C 19 select SND_SOC_AD73311 if I2C
19 select SND_SOC_AK4104 if SPI_MASTER 20 select SND_SOC_AK4104 if SPI_MASTER
20 select SND_SOC_AK4535 if I2C 21 select SND_SOC_AK4535 if I2C
21 select SND_SOC_AK4642 if I2C 22 select SND_SOC_AK4642 if I2C
23 select SND_SOC_AK4671 if I2C
22 select SND_SOC_CS4270 if I2C 24 select SND_SOC_CS4270 if I2C
23 select SND_SOC_MAX9877 if I2C 25 select SND_SOC_MAX9877 if I2C
24 select SND_SOC_PCM3008 26 select SND_SOC_PCM3008
@@ -28,6 +30,8 @@ config SND_SOC_ALL_CODECS
28 select SND_SOC_TLV320AIC23 if I2C 30 select SND_SOC_TLV320AIC23 if I2C
29 select SND_SOC_TLV320AIC26 if SPI_MASTER 31 select SND_SOC_TLV320AIC26 if SPI_MASTER
30 select SND_SOC_TLV320AIC3X if I2C 32 select SND_SOC_TLV320AIC3X if I2C
33 select SND_SOC_TPA6130A2 if I2C
34 select SND_SOC_TLV320DAC33 if I2C
31 select SND_SOC_TWL4030 if TWL4030_CORE 35 select SND_SOC_TWL4030 if TWL4030_CORE
32 select SND_SOC_UDA134X 36 select SND_SOC_UDA134X
33 select SND_SOC_UDA1380 if I2C 37 select SND_SOC_UDA1380 if I2C
@@ -36,6 +40,8 @@ config SND_SOC_ALL_CODECS
36 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 40 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
37 select SND_SOC_WM8523 if I2C 41 select SND_SOC_WM8523 if I2C
38 select SND_SOC_WM8580 if I2C 42 select SND_SOC_WM8580 if I2C
43 select SND_SOC_WM8711 if SND_SOC_I2C_AND_SPI
44 select SND_SOC_WM8727
39 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 45 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
40 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 46 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
41 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 47 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
@@ -86,6 +92,9 @@ config SND_SOC_AD1980
86 92
87config SND_SOC_AD73311 93config SND_SOC_AD73311
88 tristate 94 tristate
95
96config SND_SOC_ADS117X
97 tristate
89 98
90config SND_SOC_AK4104 99config SND_SOC_AK4104
91 tristate 100 tristate
@@ -96,6 +105,9 @@ config SND_SOC_AK4535
96config SND_SOC_AK4642 105config SND_SOC_AK4642
97 tristate 106 tristate
98 107
108config SND_SOC_AK4671
109 tristate
110
99# Cirrus Logic CS4270 Codec 111# Cirrus Logic CS4270 Codec
100config SND_SOC_CS4270 112config SND_SOC_CS4270
101 tristate 113 tristate
@@ -136,7 +148,11 @@ config SND_SOC_TLV320AIC26
136config SND_SOC_TLV320AIC3X 148config SND_SOC_TLV320AIC3X
137 tristate 149 tristate
138 150
151config SND_SOC_TLV320DAC33
152 tristate
153
139config SND_SOC_TWL4030 154config SND_SOC_TWL4030
155 select TWL4030_CODEC
140 tristate 156 tristate
141 157
142config SND_SOC_UDA134X 158config SND_SOC_UDA134X
@@ -160,6 +176,12 @@ config SND_SOC_WM8523
160config SND_SOC_WM8580 176config SND_SOC_WM8580
161 tristate 177 tristate
162 178
179config SND_SOC_WM8711
180 tristate
181
182config SND_SOC_WM8727
183 tristate
184
163config SND_SOC_WM8728 185config SND_SOC_WM8728
164 tristate 186 tristate
165 187
@@ -220,3 +242,6 @@ config SND_SOC_WM9713
220# Amp 242# Amp
221config SND_SOC_MAX9877 243config SND_SOC_MAX9877
222 tristate 244 tristate
245
246config SND_SOC_TPA6130A2
247 tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index fb4af28486ba..dbaecb133ac7 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -3,9 +3,11 @@ snd-soc-ad1836-objs := ad1836.o
3snd-soc-ad1938-objs := ad1938.o 3snd-soc-ad1938-objs := ad1938.o
4snd-soc-ad1980-objs := ad1980.o 4snd-soc-ad1980-objs := ad1980.o
5snd-soc-ad73311-objs := ad73311.o 5snd-soc-ad73311-objs := ad73311.o
6snd-soc-ads117x-objs := ads117x.o
6snd-soc-ak4104-objs := ak4104.o 7snd-soc-ak4104-objs := ak4104.o
7snd-soc-ak4535-objs := ak4535.o 8snd-soc-ak4535-objs := ak4535.o
8snd-soc-ak4642-objs := ak4642.o 9snd-soc-ak4642-objs := ak4642.o
10snd-soc-ak4671-objs := ak4671.o
9snd-soc-cs4270-objs := cs4270.o 11snd-soc-cs4270-objs := cs4270.o
10snd-soc-cx20442-objs := cx20442.o 12snd-soc-cx20442-objs := cx20442.o
11snd-soc-l3-objs := l3.o 13snd-soc-l3-objs := l3.o
@@ -16,6 +18,7 @@ snd-soc-stac9766-objs := stac9766.o
16snd-soc-tlv320aic23-objs := tlv320aic23.o 18snd-soc-tlv320aic23-objs := tlv320aic23.o
17snd-soc-tlv320aic26-objs := tlv320aic26.o 19snd-soc-tlv320aic26-objs := tlv320aic26.o
18snd-soc-tlv320aic3x-objs := tlv320aic3x.o 20snd-soc-tlv320aic3x-objs := tlv320aic3x.o
21snd-soc-tlv320dac33-objs := tlv320dac33.o
19snd-soc-twl4030-objs := twl4030.o 22snd-soc-twl4030-objs := twl4030.o
20snd-soc-uda134x-objs := uda134x.o 23snd-soc-uda134x-objs := uda134x.o
21snd-soc-uda1380-objs := uda1380.o 24snd-soc-uda1380-objs := uda1380.o
@@ -24,6 +27,8 @@ snd-soc-wm8400-objs := wm8400.o
24snd-soc-wm8510-objs := wm8510.o 27snd-soc-wm8510-objs := wm8510.o
25snd-soc-wm8523-objs := wm8523.o 28snd-soc-wm8523-objs := wm8523.o
26snd-soc-wm8580-objs := wm8580.o 29snd-soc-wm8580-objs := wm8580.o
30snd-soc-wm8711-objs := wm8711.o
31snd-soc-wm8727-objs := wm8727.o
27snd-soc-wm8728-objs := wm8728.o 32snd-soc-wm8728-objs := wm8728.o
28snd-soc-wm8731-objs := wm8731.o 33snd-soc-wm8731-objs := wm8731.o
29snd-soc-wm8750-objs := wm8750.o 34snd-soc-wm8750-objs := wm8750.o
@@ -47,15 +52,18 @@ snd-soc-wm-hubs-objs := wm_hubs.o
47 52
48# Amp 53# Amp
49snd-soc-max9877-objs := max9877.o 54snd-soc-max9877-objs := max9877.o
55snd-soc-tpa6130a2-objs := tpa6130a2.o
50 56
51obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 57obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
52obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 58obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
53obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o 59obj-$(CONFIG_SND_SOC_AD1938) += snd-soc-ad1938.o
54obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o 60obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
55obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 61obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
62obj-$(CONFIG_SND_SOC_ADS117X) += snd-soc-ads117x.o
56obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o 63obj-$(CONFIG_SND_SOC_AK4104) += snd-soc-ak4104.o
57obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 64obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
58obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o 65obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
66obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
59obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 67obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
60obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 68obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
61obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 69obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
@@ -66,6 +74,7 @@ obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
66obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 74obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
67obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 75obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
68obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 76obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
77obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
69obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o 78obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
70obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o 79obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
71obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 80obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
@@ -74,6 +83,8 @@ obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
74obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 83obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
75obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o 84obj-$(CONFIG_SND_SOC_WM8523) += snd-soc-wm8523.o
76obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 85obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
86obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
87obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
77obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 88obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
78obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 89obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
79obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 90obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
@@ -97,3 +108,4 @@ obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
97 108
98# Amp 109# Amp
99obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o 110obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
111obj-$(CONFIG_SND_SOC_TPA6130A2) += snd-soc-tpa6130a2.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 932299bb5d1e..69bd0acc81c8 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -117,9 +117,6 @@ static int ac97_soc_probe(struct platform_device *pdev)
117 if (ret < 0) 117 if (ret < 0)
118 goto bus_err; 118 goto bus_err;
119 119
120 ret = snd_soc_init_card(socdev);
121 if (ret < 0)
122 goto bus_err;
123 return 0; 120 return 0;
124 121
125bus_err: 122bus_err:
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index c48485f2c55d..2c18e3d1b71e 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -385,19 +385,7 @@ static int ad1836_probe(struct platform_device *pdev)
385 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets, 385 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets,
386 ARRAY_SIZE(ad1836_dapm_widgets)); 386 ARRAY_SIZE(ad1836_dapm_widgets));
387 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 387 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
388 snd_soc_dapm_new_widgets(codec);
389 388
390 ret = snd_soc_init_card(socdev);
391 if (ret < 0) {
392 dev_err(codec->dev, "failed to register card: %d\n", ret);
393 goto card_err;
394 }
395
396 return ret;
397
398card_err:
399 snd_soc_free_pcms(socdev);
400 snd_soc_dapm_free(socdev);
401pcm_err: 389pcm_err:
402 return ret; 390 return ret;
403} 391}
diff --git a/sound/soc/codecs/ad1938.c b/sound/soc/codecs/ad1938.c
index 34b30efc3cb0..5d489186c05b 100644
--- a/sound/soc/codecs/ad1938.c
+++ b/sound/soc/codecs/ad1938.c
@@ -592,21 +592,9 @@ static int ad1938_probe(struct platform_device *pdev)
592 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets, 592 snd_soc_dapm_new_controls(codec, ad1938_dapm_widgets,
593 ARRAY_SIZE(ad1938_dapm_widgets)); 593 ARRAY_SIZE(ad1938_dapm_widgets));
594 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 594 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
595 snd_soc_dapm_new_widgets(codec);
596 595
597 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 596 ad1938_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
598 597
599 ret = snd_soc_init_card(socdev);
600 if (ret < 0) {
601 dev_err(codec->dev, "failed to register card: %d\n", ret);
602 goto card_err;
603 }
604
605 return ret;
606
607card_err:
608 snd_soc_free_pcms(socdev);
609 snd_soc_dapm_free(socdev);
610pcm_err: 598pcm_err:
611 return ret; 599 return ret;
612} 600}
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index d7440a982d22..39c0f7584e65 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -257,11 +257,6 @@ static int ad1980_soc_probe(struct platform_device *pdev)
257 257
258 snd_soc_add_controls(codec, ad1980_snd_ac97_controls, 258 snd_soc_add_controls(codec, ad1980_snd_ac97_controls,
259 ARRAY_SIZE(ad1980_snd_ac97_controls)); 259 ARRAY_SIZE(ad1980_snd_ac97_controls));
260 ret = snd_soc_init_card(socdev);
261 if (ret < 0) {
262 printk(KERN_ERR "ad1980: failed to register card\n");
263 goto reset_err;
264 }
265 260
266 return 0; 261 return 0;
267 262
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index e61dac5e7b8f..d2fcc601722c 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -64,16 +64,8 @@ static int ad73311_soc_probe(struct platform_device *pdev)
64 goto pcm_err; 64 goto pcm_err;
65 } 65 }
66 66
67 ret = snd_soc_init_card(socdev);
68 if (ret < 0) {
69 printk(KERN_ERR "ad73311: failed to register card\n");
70 goto register_err;
71 }
72
73 return ret; 67 return ret;
74 68
75register_err:
76 snd_soc_free_pcms(socdev);
77pcm_err: 69pcm_err:
78 kfree(socdev->card->codec); 70 kfree(socdev->card->codec);
79 socdev->card->codec = NULL; 71 socdev->card->codec = NULL;
diff --git a/sound/soc/codecs/ads117x.c b/sound/soc/codecs/ads117x.c
new file mode 100644
index 000000000000..cc96411ca3e6
--- /dev/null
+++ b/sound/soc/codecs/ads117x.c
@@ -0,0 +1,123 @@
1/*
2 * ads117x.c -- Driver for ads1174/8 ADC chips
3 *
4 * Copyright 2009 ShotSpotter Inc.
5 * Author: Graeme Gregory <gg@slimlogic.co.uk>
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#include <linux/kernel.h>
14#include <linux/init.h>
15#include <linux/device.h>
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/initval.h>
19#include <sound/soc.h>
20
21#include "ads117x.h"
22
23#define ADS117X_RATES (SNDRV_PCM_RATE_8000_48000)
24
25#define ADS117X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
26
27struct snd_soc_dai ads117x_dai = {
28/* ADC */
29 .name = "ADS117X ADC",
30 .id = 1,
31 .capture = {
32 .stream_name = "Capture",
33 .channels_min = 1,
34 .channels_max = 32,
35 .rates = ADS117X_RATES,
36 .formats = ADS117X_FORMATS,},
37};
38EXPORT_SYMBOL_GPL(ads117x_dai);
39
40static int ads117x_probe(struct platform_device *pdev)
41{
42 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
43 struct snd_soc_codec *codec;
44 int ret;
45
46 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
47 if (codec == NULL)
48 return -ENOMEM;
49
50 socdev->card->codec = codec;
51 mutex_init(&codec->mutex);
52 INIT_LIST_HEAD(&codec->dapm_widgets);
53 INIT_LIST_HEAD(&codec->dapm_paths);
54 codec->name = "ADS117X";
55 codec->owner = THIS_MODULE;
56 codec->dai = &ads117x_dai;
57 codec->num_dai = 1;
58
59 /* register pcms */
60 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
61 if (ret < 0) {
62 printk(KERN_ERR "ads117x: failed to create pcms\n");
63 kfree(codec);
64 return ret;
65 }
66
67 return 0;
68}
69
70static int ads117x_remove(struct platform_device *pdev)
71{
72 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
73 struct snd_soc_codec *codec = socdev->card->codec;
74
75 snd_soc_free_pcms(socdev);
76 kfree(codec);
77
78 return 0;
79}
80
81struct snd_soc_codec_device soc_codec_dev_ads117x = {
82 .probe = ads117x_probe,
83 .remove = ads117x_remove,
84};
85EXPORT_SYMBOL_GPL(soc_codec_dev_ads117x);
86
87static __devinit int ads117x_platform_probe(struct platform_device *pdev)
88{
89 ads117x_dai.dev = &pdev->dev;
90 return snd_soc_register_dai(&ads117x_dai);
91}
92
93static int __devexit ads117x_platform_remove(struct platform_device *pdev)
94{
95 snd_soc_unregister_dai(&ads117x_dai);
96 return 0;
97}
98
99static struct platform_driver ads117x_codec_driver = {
100 .driver = {
101 .name = "ads117x",
102 .owner = THIS_MODULE,
103 },
104
105 .probe = ads117x_platform_probe,
106 .remove = __devexit_p(ads117x_platform_remove),
107};
108
109static int __init ads117x_init(void)
110{
111 return platform_driver_register(&ads117x_codec_driver);
112}
113module_init(ads117x_init);
114
115static void __exit ads117x_exit(void)
116{
117 platform_driver_unregister(&ads117x_codec_driver);
118}
119module_exit(ads117x_exit);
120
121MODULE_DESCRIPTION("ASoC ads117x driver");
122MODULE_AUTHOR("Graeme Gregory");
123MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ads117x.h b/sound/soc/codecs/ads117x.h
new file mode 100644
index 000000000000..dbcf50ec9bd1
--- /dev/null
+++ b/sound/soc/codecs/ads117x.h
@@ -0,0 +1,13 @@
1/*
2 * ads117x.h -- Driver for ads1174/8 ADC chips
3 *
4 * Copyright 2009 ShotSpotter Inc.
5 * Author: Graeme Gregory <gg@slimlogic.co.uk>
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 */
12extern struct snd_soc_dai ads117x_dai;
13extern struct snd_soc_codec_device soc_codec_dev_ads117x;
diff --git a/sound/soc/codecs/ak4104.c b/sound/soc/codecs/ak4104.c
index 4d47bc4f7428..3a14c6fc4f5e 100644
--- a/sound/soc/codecs/ak4104.c
+++ b/sound/soc/codecs/ak4104.c
@@ -313,14 +313,6 @@ static int ak4104_probe(struct platform_device *pdev)
313 return ret; 313 return ret;
314 } 314 }
315 315
316 /* Register the socdev */
317 ret = snd_soc_init_card(socdev);
318 if (ret < 0) {
319 dev_err(codec->dev, "failed to register card\n");
320 snd_soc_free_pcms(socdev);
321 return ret;
322 }
323
324 return 0; 316 return 0;
325} 317}
326 318
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 0abec0d29a96..ff966567e2ba 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -294,7 +294,6 @@ static int ak4535_add_widgets(struct snd_soc_codec *codec)
294 294
295 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 295 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
296 296
297 snd_soc_dapm_new_widgets(codec);
298 return 0; 297 return 0;
299} 298}
300 299
@@ -485,17 +484,9 @@ static int ak4535_init(struct snd_soc_device *socdev)
485 snd_soc_add_controls(codec, ak4535_snd_controls, 484 snd_soc_add_controls(codec, ak4535_snd_controls,
486 ARRAY_SIZE(ak4535_snd_controls)); 485 ARRAY_SIZE(ak4535_snd_controls));
487 ak4535_add_widgets(codec); 486 ak4535_add_widgets(codec);
488 ret = snd_soc_init_card(socdev);
489 if (ret < 0) {
490 printk(KERN_ERR "ak4535: failed to register card\n");
491 goto card_err;
492 }
493 487
494 return ret; 488 return ret;
495 489
496card_err:
497 snd_soc_free_pcms(socdev);
498 snd_soc_dapm_free(socdev);
499pcm_err: 490pcm_err:
500 kfree(codec->reg_cache); 491 kfree(codec->reg_cache);
501 492
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index e057c7b578df..b69861d52161 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -442,18 +442,9 @@ static int ak4642_probe(struct platform_device *pdev)
442 goto pcm_err; 442 goto pcm_err;
443 } 443 }
444 444
445 ret = snd_soc_init_card(socdev);
446 if (ret < 0) {
447 printk(KERN_ERR "ak4642: failed to register card\n");
448 goto card_err;
449 }
450
451 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION); 445 dev_info(&pdev->dev, "AK4642 Audio Codec %s", AK4642_VERSION);
452 return ret; 446 return ret;
453 447
454card_err:
455 snd_soc_free_pcms(socdev);
456 snd_soc_dapm_free(socdev);
457pcm_err: 448pcm_err:
458 return ret; 449 return ret;
459 450
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
new file mode 100644
index 000000000000..82fca284d007
--- /dev/null
+++ b/sound/soc/codecs/ak4671.c
@@ -0,0 +1,815 @@
1/*
2 * ak4671.c -- audio driver for AK4671
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
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 <linux/module.h>
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <linux/delay.h>
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20#include <sound/initval.h>
21#include <sound/tlv.h>
22
23#include "ak4671.h"
24
25static struct snd_soc_codec *ak4671_codec;
26
27/* codec private data */
28struct ak4671_priv {
29 struct snd_soc_codec codec;
30 u8 reg_cache[AK4671_CACHEREGNUM];
31};
32
33/* ak4671 register cache & default register settings */
34static const u8 ak4671_reg[AK4671_CACHEREGNUM] = {
35 0x00, /* AK4671_AD_DA_POWER_MANAGEMENT (0x00) */
36 0xf6, /* AK4671_PLL_MODE_SELECT0 (0x01) */
37 0x00, /* AK4671_PLL_MODE_SELECT1 (0x02) */
38 0x02, /* AK4671_FORMAT_SELECT (0x03) */
39 0x00, /* AK4671_MIC_SIGNAL_SELECT (0x04) */
40 0x55, /* AK4671_MIC_AMP_GAIN (0x05) */
41 0x00, /* AK4671_MIXING_POWER_MANAGEMENT0 (0x06) */
42 0x00, /* AK4671_MIXING_POWER_MANAGEMENT1 (0x07) */
43 0xb5, /* AK4671_OUTPUT_VOLUME_CONTROL (0x08) */
44 0x00, /* AK4671_LOUT1_SIGNAL_SELECT (0x09) */
45 0x00, /* AK4671_ROUT1_SIGNAL_SELECT (0x0a) */
46 0x00, /* AK4671_LOUT2_SIGNAL_SELECT (0x0b) */
47 0x00, /* AK4671_ROUT2_SIGNAL_SELECT (0x0c) */
48 0x00, /* AK4671_LOUT3_SIGNAL_SELECT (0x0d) */
49 0x00, /* AK4671_ROUT3_SIGNAL_SELECT (0x0e) */
50 0x00, /* AK4671_LOUT1_POWER_MANAGERMENT (0x0f) */
51 0x00, /* AK4671_LOUT2_POWER_MANAGERMENT (0x10) */
52 0x80, /* AK4671_LOUT3_POWER_MANAGERMENT (0x11) */
53 0x91, /* AK4671_LCH_INPUT_VOLUME_CONTROL (0x12) */
54 0x91, /* AK4671_RCH_INPUT_VOLUME_CONTROL (0x13) */
55 0xe1, /* AK4671_ALC_REFERENCE_SELECT (0x14) */
56 0x00, /* AK4671_DIGITAL_MIXING_CONTROL (0x15) */
57 0x00, /* AK4671_ALC_TIMER_SELECT (0x16) */
58 0x00, /* AK4671_ALC_MODE_CONTROL (0x17) */
59 0x02, /* AK4671_MODE_CONTROL1 (0x18) */
60 0x01, /* AK4671_MODE_CONTROL2 (0x19) */
61 0x18, /* AK4671_LCH_OUTPUT_VOLUME_CONTROL (0x1a) */
62 0x18, /* AK4671_RCH_OUTPUT_VOLUME_CONTROL (0x1b) */
63 0x00, /* AK4671_SIDETONE_A_CONTROL (0x1c) */
64 0x02, /* AK4671_DIGITAL_FILTER_SELECT (0x1d) */
65 0x00, /* AK4671_FIL3_COEFFICIENT0 (0x1e) */
66 0x00, /* AK4671_FIL3_COEFFICIENT1 (0x1f) */
67 0x00, /* AK4671_FIL3_COEFFICIENT2 (0x20) */
68 0x00, /* AK4671_FIL3_COEFFICIENT3 (0x21) */
69 0x00, /* AK4671_EQ_COEFFICIENT0 (0x22) */
70 0x00, /* AK4671_EQ_COEFFICIENT1 (0x23) */
71 0x00, /* AK4671_EQ_COEFFICIENT2 (0x24) */
72 0x00, /* AK4671_EQ_COEFFICIENT3 (0x25) */
73 0x00, /* AK4671_EQ_COEFFICIENT4 (0x26) */
74 0x00, /* AK4671_EQ_COEFFICIENT5 (0x27) */
75 0xa9, /* AK4671_FIL1_COEFFICIENT0 (0x28) */
76 0x1f, /* AK4671_FIL1_COEFFICIENT1 (0x29) */
77 0xad, /* AK4671_FIL1_COEFFICIENT2 (0x2a) */
78 0x20, /* AK4671_FIL1_COEFFICIENT3 (0x2b) */
79 0x00, /* AK4671_FIL2_COEFFICIENT0 (0x2c) */
80 0x00, /* AK4671_FIL2_COEFFICIENT1 (0x2d) */
81 0x00, /* AK4671_FIL2_COEFFICIENT2 (0x2e) */
82 0x00, /* AK4671_FIL2_COEFFICIENT3 (0x2f) */
83 0x00, /* AK4671_DIGITAL_FILTER_SELECT2 (0x30) */
84 0x00, /* this register not used */
85 0x00, /* AK4671_E1_COEFFICIENT0 (0x32) */
86 0x00, /* AK4671_E1_COEFFICIENT1 (0x33) */
87 0x00, /* AK4671_E1_COEFFICIENT2 (0x34) */
88 0x00, /* AK4671_E1_COEFFICIENT3 (0x35) */
89 0x00, /* AK4671_E1_COEFFICIENT4 (0x36) */
90 0x00, /* AK4671_E1_COEFFICIENT5 (0x37) */
91 0x00, /* AK4671_E2_COEFFICIENT0 (0x38) */
92 0x00, /* AK4671_E2_COEFFICIENT1 (0x39) */
93 0x00, /* AK4671_E2_COEFFICIENT2 (0x3a) */
94 0x00, /* AK4671_E2_COEFFICIENT3 (0x3b) */
95 0x00, /* AK4671_E2_COEFFICIENT4 (0x3c) */
96 0x00, /* AK4671_E2_COEFFICIENT5 (0x3d) */
97 0x00, /* AK4671_E3_COEFFICIENT0 (0x3e) */
98 0x00, /* AK4671_E3_COEFFICIENT1 (0x3f) */
99 0x00, /* AK4671_E3_COEFFICIENT2 (0x40) */
100 0x00, /* AK4671_E3_COEFFICIENT3 (0x41) */
101 0x00, /* AK4671_E3_COEFFICIENT4 (0x42) */
102 0x00, /* AK4671_E3_COEFFICIENT5 (0x43) */
103 0x00, /* AK4671_E4_COEFFICIENT0 (0x44) */
104 0x00, /* AK4671_E4_COEFFICIENT1 (0x45) */
105 0x00, /* AK4671_E4_COEFFICIENT2 (0x46) */
106 0x00, /* AK4671_E4_COEFFICIENT3 (0x47) */
107 0x00, /* AK4671_E4_COEFFICIENT4 (0x48) */
108 0x00, /* AK4671_E4_COEFFICIENT5 (0x49) */
109 0x00, /* AK4671_E5_COEFFICIENT0 (0x4a) */
110 0x00, /* AK4671_E5_COEFFICIENT1 (0x4b) */
111 0x00, /* AK4671_E5_COEFFICIENT2 (0x4c) */
112 0x00, /* AK4671_E5_COEFFICIENT3 (0x4d) */
113 0x00, /* AK4671_E5_COEFFICIENT4 (0x4e) */
114 0x00, /* AK4671_E5_COEFFICIENT5 (0x4f) */
115 0x88, /* AK4671_EQ_CONTROL_250HZ_100HZ (0x50) */
116 0x88, /* AK4671_EQ_CONTROL_3500HZ_1KHZ (0x51) */
117 0x08, /* AK4671_EQ_CONTRO_10KHZ (0x52) */
118 0x00, /* AK4671_PCM_IF_CONTROL0 (0x53) */
119 0x00, /* AK4671_PCM_IF_CONTROL1 (0x54) */
120 0x00, /* AK4671_PCM_IF_CONTROL2 (0x55) */
121 0x18, /* AK4671_DIGITAL_VOLUME_B_CONTROL (0x56) */
122 0x18, /* AK4671_DIGITAL_VOLUME_C_CONTROL (0x57) */
123 0x00, /* AK4671_SIDETONE_VOLUME_CONTROL (0x58) */
124 0x00, /* AK4671_DIGITAL_MIXING_CONTROL2 (0x59) */
125 0x00, /* AK4671_SAR_ADC_CONTROL (0x5a) */
126};
127
128/*
129 * LOUT1/ROUT1 output volume control:
130 * from -24 to 6 dB in 6 dB steps (mute instead of -30 dB)
131 */
132static DECLARE_TLV_DB_SCALE(out1_tlv, -3000, 600, 1);
133
134/*
135 * LOUT2/ROUT2 output volume control:
136 * from -33 to 6 dB in 3 dB steps (mute instead of -33 dB)
137 */
138static DECLARE_TLV_DB_SCALE(out2_tlv, -3300, 300, 1);
139
140/*
141 * LOUT3/ROUT3 output volume control:
142 * from -6 to 3 dB in 3 dB steps
143 */
144static DECLARE_TLV_DB_SCALE(out3_tlv, -600, 300, 0);
145
146/*
147 * Mic amp gain control:
148 * from -15 to 30 dB in 3 dB steps
149 * REVISIT: The actual min value(0x01) is -12 dB and the reg value 0x00 is not
150 * available
151 */
152static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -1500, 300, 0);
153
154static const struct snd_kcontrol_new ak4671_snd_controls[] = {
155 /* Common playback gain controls */
156 SOC_SINGLE_TLV("Line Output1 Playback Volume",
157 AK4671_OUTPUT_VOLUME_CONTROL, 0, 0x6, 0, out1_tlv),
158 SOC_SINGLE_TLV("Headphone Output2 Playback Volume",
159 AK4671_OUTPUT_VOLUME_CONTROL, 4, 0xd, 0, out2_tlv),
160 SOC_SINGLE_TLV("Line Output3 Playback Volume",
161 AK4671_LOUT3_POWER_MANAGERMENT, 6, 0x3, 0, out3_tlv),
162
163 /* Common capture gain controls */
164 SOC_DOUBLE_TLV("Mic Amp Capture Volume",
165 AK4671_MIC_AMP_GAIN, 0, 4, 0xf, 0, mic_amp_tlv),
166};
167
168/* event handlers */
169static int ak4671_out2_event(struct snd_soc_dapm_widget *w,
170 struct snd_kcontrol *kcontrol, int event)
171{
172 struct snd_soc_codec *codec = w->codec;
173 u8 reg;
174
175 switch (event) {
176 case SND_SOC_DAPM_POST_PMU:
177 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT);
178 reg |= AK4671_MUTEN;
179 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
180 break;
181 case SND_SOC_DAPM_PRE_PMD:
182 reg = snd_soc_read(codec, AK4671_LOUT2_POWER_MANAGERMENT);
183 reg &= ~AK4671_MUTEN;
184 snd_soc_write(codec, AK4671_LOUT2_POWER_MANAGERMENT, reg);
185 break;
186 }
187
188 return 0;
189}
190
191/* Output Mixers */
192static const struct snd_kcontrol_new ak4671_lout1_mixer_controls[] = {
193 SOC_DAPM_SINGLE("DACL", AK4671_LOUT1_SIGNAL_SELECT, 0, 1, 0),
194 SOC_DAPM_SINGLE("LINL1", AK4671_LOUT1_SIGNAL_SELECT, 1, 1, 0),
195 SOC_DAPM_SINGLE("LINL2", AK4671_LOUT1_SIGNAL_SELECT, 2, 1, 0),
196 SOC_DAPM_SINGLE("LINL3", AK4671_LOUT1_SIGNAL_SELECT, 3, 1, 0),
197 SOC_DAPM_SINGLE("LINL4", AK4671_LOUT1_SIGNAL_SELECT, 4, 1, 0),
198 SOC_DAPM_SINGLE("LOOPL", AK4671_LOUT1_SIGNAL_SELECT, 5, 1, 0),
199};
200
201static const struct snd_kcontrol_new ak4671_rout1_mixer_controls[] = {
202 SOC_DAPM_SINGLE("DACR", AK4671_ROUT1_SIGNAL_SELECT, 0, 1, 0),
203 SOC_DAPM_SINGLE("RINR1", AK4671_ROUT1_SIGNAL_SELECT, 1, 1, 0),
204 SOC_DAPM_SINGLE("RINR2", AK4671_ROUT1_SIGNAL_SELECT, 2, 1, 0),
205 SOC_DAPM_SINGLE("RINR3", AK4671_ROUT1_SIGNAL_SELECT, 3, 1, 0),
206 SOC_DAPM_SINGLE("RINR4", AK4671_ROUT1_SIGNAL_SELECT, 4, 1, 0),
207 SOC_DAPM_SINGLE("LOOPR", AK4671_ROUT1_SIGNAL_SELECT, 5, 1, 0),
208};
209
210static const struct snd_kcontrol_new ak4671_lout2_mixer_controls[] = {
211 SOC_DAPM_SINGLE("DACHL", AK4671_LOUT2_SIGNAL_SELECT, 0, 1, 0),
212 SOC_DAPM_SINGLE("LINH1", AK4671_LOUT2_SIGNAL_SELECT, 1, 1, 0),
213 SOC_DAPM_SINGLE("LINH2", AK4671_LOUT2_SIGNAL_SELECT, 2, 1, 0),
214 SOC_DAPM_SINGLE("LINH3", AK4671_LOUT2_SIGNAL_SELECT, 3, 1, 0),
215 SOC_DAPM_SINGLE("LINH4", AK4671_LOUT2_SIGNAL_SELECT, 4, 1, 0),
216 SOC_DAPM_SINGLE("LOOPHL", AK4671_LOUT2_SIGNAL_SELECT, 5, 1, 0),
217};
218
219static const struct snd_kcontrol_new ak4671_rout2_mixer_controls[] = {
220 SOC_DAPM_SINGLE("DACHR", AK4671_ROUT2_SIGNAL_SELECT, 0, 1, 0),
221 SOC_DAPM_SINGLE("RINH1", AK4671_ROUT2_SIGNAL_SELECT, 1, 1, 0),
222 SOC_DAPM_SINGLE("RINH2", AK4671_ROUT2_SIGNAL_SELECT, 2, 1, 0),
223 SOC_DAPM_SINGLE("RINH3", AK4671_ROUT2_SIGNAL_SELECT, 3, 1, 0),
224 SOC_DAPM_SINGLE("RINH4", AK4671_ROUT2_SIGNAL_SELECT, 4, 1, 0),
225 SOC_DAPM_SINGLE("LOOPHR", AK4671_ROUT2_SIGNAL_SELECT, 5, 1, 0),
226};
227
228static const struct snd_kcontrol_new ak4671_lout3_mixer_controls[] = {
229 SOC_DAPM_SINGLE("DACSL", AK4671_LOUT3_SIGNAL_SELECT, 0, 1, 0),
230 SOC_DAPM_SINGLE("LINS1", AK4671_LOUT3_SIGNAL_SELECT, 1, 1, 0),
231 SOC_DAPM_SINGLE("LINS2", AK4671_LOUT3_SIGNAL_SELECT, 2, 1, 0),
232 SOC_DAPM_SINGLE("LINS3", AK4671_LOUT3_SIGNAL_SELECT, 3, 1, 0),
233 SOC_DAPM_SINGLE("LINS4", AK4671_LOUT3_SIGNAL_SELECT, 4, 1, 0),
234 SOC_DAPM_SINGLE("LOOPSL", AK4671_LOUT3_SIGNAL_SELECT, 5, 1, 0),
235};
236
237static const struct snd_kcontrol_new ak4671_rout3_mixer_controls[] = {
238 SOC_DAPM_SINGLE("DACSR", AK4671_ROUT3_SIGNAL_SELECT, 0, 1, 0),
239 SOC_DAPM_SINGLE("RINS1", AK4671_ROUT3_SIGNAL_SELECT, 1, 1, 0),
240 SOC_DAPM_SINGLE("RINS2", AK4671_ROUT3_SIGNAL_SELECT, 2, 1, 0),
241 SOC_DAPM_SINGLE("RINS3", AK4671_ROUT3_SIGNAL_SELECT, 3, 1, 0),
242 SOC_DAPM_SINGLE("RINS4", AK4671_ROUT3_SIGNAL_SELECT, 4, 1, 0),
243 SOC_DAPM_SINGLE("LOOPSR", AK4671_ROUT3_SIGNAL_SELECT, 5, 1, 0),
244};
245
246/* Input MUXs */
247static const char *ak4671_lin_mux_texts[] =
248 {"LIN1", "LIN2", "LIN3", "LIN4"};
249static const struct soc_enum ak4671_lin_mux_enum =
250 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 0,
251 ARRAY_SIZE(ak4671_lin_mux_texts),
252 ak4671_lin_mux_texts);
253static const struct snd_kcontrol_new ak4671_lin_mux_control =
254 SOC_DAPM_ENUM("Route", ak4671_lin_mux_enum);
255
256static const char *ak4671_rin_mux_texts[] =
257 {"RIN1", "RIN2", "RIN3", "RIN4"};
258static const struct soc_enum ak4671_rin_mux_enum =
259 SOC_ENUM_SINGLE(AK4671_MIC_SIGNAL_SELECT, 2,
260 ARRAY_SIZE(ak4671_rin_mux_texts),
261 ak4671_rin_mux_texts);
262static const struct snd_kcontrol_new ak4671_rin_mux_control =
263 SOC_DAPM_ENUM("Route", ak4671_rin_mux_enum);
264
265static const struct snd_soc_dapm_widget ak4671_dapm_widgets[] = {
266 /* Inputs */
267 SND_SOC_DAPM_INPUT("LIN1"),
268 SND_SOC_DAPM_INPUT("RIN1"),
269 SND_SOC_DAPM_INPUT("LIN2"),
270 SND_SOC_DAPM_INPUT("RIN2"),
271 SND_SOC_DAPM_INPUT("LIN3"),
272 SND_SOC_DAPM_INPUT("RIN3"),
273 SND_SOC_DAPM_INPUT("LIN4"),
274 SND_SOC_DAPM_INPUT("RIN4"),
275
276 /* Outputs */
277 SND_SOC_DAPM_OUTPUT("LOUT1"),
278 SND_SOC_DAPM_OUTPUT("ROUT1"),
279 SND_SOC_DAPM_OUTPUT("LOUT2"),
280 SND_SOC_DAPM_OUTPUT("ROUT2"),
281 SND_SOC_DAPM_OUTPUT("LOUT3"),
282 SND_SOC_DAPM_OUTPUT("ROUT3"),
283
284 /* DAC */
285 SND_SOC_DAPM_DAC("DAC Left", "Left HiFi Playback",
286 AK4671_AD_DA_POWER_MANAGEMENT, 6, 0),
287 SND_SOC_DAPM_DAC("DAC Right", "Right HiFi Playback",
288 AK4671_AD_DA_POWER_MANAGEMENT, 7, 0),
289
290 /* ADC */
291 SND_SOC_DAPM_ADC("ADC Left", "Left HiFi Capture",
292 AK4671_AD_DA_POWER_MANAGEMENT, 4, 0),
293 SND_SOC_DAPM_ADC("ADC Right", "Right HiFi Capture",
294 AK4671_AD_DA_POWER_MANAGEMENT, 5, 0),
295
296 /* PGA */
297 SND_SOC_DAPM_PGA("LOUT2 Mix Amp",
298 AK4671_LOUT2_POWER_MANAGERMENT, 5, 0, NULL, 0),
299 SND_SOC_DAPM_PGA("ROUT2 Mix Amp",
300 AK4671_LOUT2_POWER_MANAGERMENT, 6, 0, NULL, 0),
301
302 SND_SOC_DAPM_PGA("LIN1 Mixing Circuit",
303 AK4671_MIXING_POWER_MANAGEMENT1, 0, 0, NULL, 0),
304 SND_SOC_DAPM_PGA("RIN1 Mixing Circuit",
305 AK4671_MIXING_POWER_MANAGEMENT1, 1, 0, NULL, 0),
306 SND_SOC_DAPM_PGA("LIN2 Mixing Circuit",
307 AK4671_MIXING_POWER_MANAGEMENT1, 2, 0, NULL, 0),
308 SND_SOC_DAPM_PGA("RIN2 Mixing Circuit",
309 AK4671_MIXING_POWER_MANAGEMENT1, 3, 0, NULL, 0),
310 SND_SOC_DAPM_PGA("LIN3 Mixing Circuit",
311 AK4671_MIXING_POWER_MANAGEMENT1, 4, 0, NULL, 0),
312 SND_SOC_DAPM_PGA("RIN3 Mixing Circuit",
313 AK4671_MIXING_POWER_MANAGEMENT1, 5, 0, NULL, 0),
314 SND_SOC_DAPM_PGA("LIN4 Mixing Circuit",
315 AK4671_MIXING_POWER_MANAGEMENT1, 6, 0, NULL, 0),
316 SND_SOC_DAPM_PGA("RIN4 Mixing Circuit",
317 AK4671_MIXING_POWER_MANAGEMENT1, 7, 0, NULL, 0),
318
319 /* Output Mixers */
320 SND_SOC_DAPM_MIXER("LOUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 0, 0,
321 &ak4671_lout1_mixer_controls[0],
322 ARRAY_SIZE(ak4671_lout1_mixer_controls)),
323 SND_SOC_DAPM_MIXER("ROUT1 Mixer", AK4671_LOUT1_POWER_MANAGERMENT, 1, 0,
324 &ak4671_rout1_mixer_controls[0],
325 ARRAY_SIZE(ak4671_rout1_mixer_controls)),
326 SND_SOC_DAPM_MIXER_E("LOUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
327 0, 0, &ak4671_lout2_mixer_controls[0],
328 ARRAY_SIZE(ak4671_lout2_mixer_controls),
329 ak4671_out2_event,
330 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
331 SND_SOC_DAPM_MIXER_E("ROUT2 Mixer", AK4671_LOUT2_POWER_MANAGERMENT,
332 1, 0, &ak4671_rout2_mixer_controls[0],
333 ARRAY_SIZE(ak4671_rout2_mixer_controls),
334 ak4671_out2_event,
335 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_PRE_PMD),
336 SND_SOC_DAPM_MIXER("LOUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 0, 0,
337 &ak4671_lout3_mixer_controls[0],
338 ARRAY_SIZE(ak4671_lout3_mixer_controls)),
339 SND_SOC_DAPM_MIXER("ROUT3 Mixer", AK4671_LOUT3_POWER_MANAGERMENT, 1, 0,
340 &ak4671_rout3_mixer_controls[0],
341 ARRAY_SIZE(ak4671_rout3_mixer_controls)),
342
343 /* Input MUXs */
344 SND_SOC_DAPM_MUX("LIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 2, 0,
345 &ak4671_lin_mux_control),
346 SND_SOC_DAPM_MUX("RIN MUX", AK4671_AD_DA_POWER_MANAGEMENT, 3, 0,
347 &ak4671_rin_mux_control),
348
349 /* Mic Power */
350 SND_SOC_DAPM_MICBIAS("Mic Bias", AK4671_AD_DA_POWER_MANAGEMENT, 1, 0),
351
352 /* Supply */
353 SND_SOC_DAPM_SUPPLY("PMPLL", AK4671_PLL_MODE_SELECT1, 0, 0, NULL, 0),
354};
355
356static const struct snd_soc_dapm_route intercon[] = {
357 {"DAC Left", "NULL", "PMPLL"},
358 {"DAC Right", "NULL", "PMPLL"},
359 {"ADC Left", "NULL", "PMPLL"},
360 {"ADC Right", "NULL", "PMPLL"},
361
362 /* Outputs */
363 {"LOUT1", "NULL", "LOUT1 Mixer"},
364 {"ROUT1", "NULL", "ROUT1 Mixer"},
365 {"LOUT2", "NULL", "LOUT2 Mix Amp"},
366 {"ROUT2", "NULL", "ROUT2 Mix Amp"},
367 {"LOUT3", "NULL", "LOUT3 Mixer"},
368 {"ROUT3", "NULL", "ROUT3 Mixer"},
369
370 {"LOUT1 Mixer", "DACL", "DAC Left"},
371 {"ROUT1 Mixer", "DACR", "DAC Right"},
372 {"LOUT2 Mixer", "DACHL", "DAC Left"},
373 {"ROUT2 Mixer", "DACHR", "DAC Right"},
374 {"LOUT2 Mix Amp", "NULL", "LOUT2 Mixer"},
375 {"ROUT2 Mix Amp", "NULL", "ROUT2 Mixer"},
376 {"LOUT3 Mixer", "DACSL", "DAC Left"},
377 {"ROUT3 Mixer", "DACSR", "DAC Right"},
378
379 /* Inputs */
380 {"LIN MUX", "LIN1", "LIN1"},
381 {"LIN MUX", "LIN2", "LIN2"},
382 {"LIN MUX", "LIN3", "LIN3"},
383 {"LIN MUX", "LIN4", "LIN4"},
384
385 {"RIN MUX", "RIN1", "RIN1"},
386 {"RIN MUX", "RIN2", "RIN2"},
387 {"RIN MUX", "RIN3", "RIN3"},
388 {"RIN MUX", "RIN4", "RIN4"},
389
390 {"LIN1", NULL, "Mic Bias"},
391 {"RIN1", NULL, "Mic Bias"},
392 {"LIN2", NULL, "Mic Bias"},
393 {"RIN2", NULL, "Mic Bias"},
394
395 {"ADC Left", "NULL", "LIN MUX"},
396 {"ADC Right", "NULL", "RIN MUX"},
397
398 /* Analog Loops */
399 {"LIN1 Mixing Circuit", "NULL", "LIN1"},
400 {"RIN1 Mixing Circuit", "NULL", "RIN1"},
401 {"LIN2 Mixing Circuit", "NULL", "LIN2"},
402 {"RIN2 Mixing Circuit", "NULL", "RIN2"},
403 {"LIN3 Mixing Circuit", "NULL", "LIN3"},
404 {"RIN3 Mixing Circuit", "NULL", "RIN3"},
405 {"LIN4 Mixing Circuit", "NULL", "LIN4"},
406 {"RIN4 Mixing Circuit", "NULL", "RIN4"},
407
408 {"LOUT1 Mixer", "LINL1", "LIN1 Mixing Circuit"},
409 {"ROUT1 Mixer", "RINR1", "RIN1 Mixing Circuit"},
410 {"LOUT2 Mixer", "LINH1", "LIN1 Mixing Circuit"},
411 {"ROUT2 Mixer", "RINH1", "RIN1 Mixing Circuit"},
412 {"LOUT3 Mixer", "LINS1", "LIN1 Mixing Circuit"},
413 {"ROUT3 Mixer", "RINS1", "RIN1 Mixing Circuit"},
414
415 {"LOUT1 Mixer", "LINL2", "LIN2 Mixing Circuit"},
416 {"ROUT1 Mixer", "RINR2", "RIN2 Mixing Circuit"},
417 {"LOUT2 Mixer", "LINH2", "LIN2 Mixing Circuit"},
418 {"ROUT2 Mixer", "RINH2", "RIN2 Mixing Circuit"},
419 {"LOUT3 Mixer", "LINS2", "LIN2 Mixing Circuit"},
420 {"ROUT3 Mixer", "RINS2", "RIN2 Mixing Circuit"},
421
422 {"LOUT1 Mixer", "LINL3", "LIN3 Mixing Circuit"},
423 {"ROUT1 Mixer", "RINR3", "RIN3 Mixing Circuit"},
424 {"LOUT2 Mixer", "LINH3", "LIN3 Mixing Circuit"},
425 {"ROUT2 Mixer", "RINH3", "RIN3 Mixing Circuit"},
426 {"LOUT3 Mixer", "LINS3", "LIN3 Mixing Circuit"},
427 {"ROUT3 Mixer", "RINS3", "RIN3 Mixing Circuit"},
428
429 {"LOUT1 Mixer", "LINL4", "LIN4 Mixing Circuit"},
430 {"ROUT1 Mixer", "RINR4", "RIN4 Mixing Circuit"},
431 {"LOUT2 Mixer", "LINH4", "LIN4 Mixing Circuit"},
432 {"ROUT2 Mixer", "RINH4", "RIN4 Mixing Circuit"},
433 {"LOUT3 Mixer", "LINS4", "LIN4 Mixing Circuit"},
434 {"ROUT3 Mixer", "RINS4", "RIN4 Mixing Circuit"},
435};
436
437static int ak4671_add_widgets(struct snd_soc_codec *codec)
438{
439 snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets,
440 ARRAY_SIZE(ak4671_dapm_widgets));
441
442 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
443
444 return 0;
445}
446
447static int ak4671_hw_params(struct snd_pcm_substream *substream,
448 struct snd_pcm_hw_params *params,
449 struct snd_soc_dai *dai)
450{
451 struct snd_soc_codec *codec = dai->codec;
452 u8 fs;
453
454 fs = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
455 fs &= ~AK4671_FS;
456
457 switch (params_rate(params)) {
458 case 8000:
459 fs |= AK4671_FS_8KHZ;
460 break;
461 case 12000:
462 fs |= AK4671_FS_12KHZ;
463 break;
464 case 16000:
465 fs |= AK4671_FS_16KHZ;
466 break;
467 case 24000:
468 fs |= AK4671_FS_24KHZ;
469 break;
470 case 11025:
471 fs |= AK4671_FS_11_025KHZ;
472 break;
473 case 22050:
474 fs |= AK4671_FS_22_05KHZ;
475 break;
476 case 32000:
477 fs |= AK4671_FS_32KHZ;
478 break;
479 case 44100:
480 fs |= AK4671_FS_44_1KHZ;
481 break;
482 case 48000:
483 fs |= AK4671_FS_48KHZ;
484 break;
485 default:
486 return -EINVAL;
487 }
488
489 snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, fs);
490
491 return 0;
492}
493
494static int ak4671_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
495 unsigned int freq, int dir)
496{
497 struct snd_soc_codec *codec = dai->codec;
498 u8 pll;
499
500 pll = snd_soc_read(codec, AK4671_PLL_MODE_SELECT0);
501 pll &= ~AK4671_PLL;
502
503 switch (freq) {
504 case 11289600:
505 pll |= AK4671_PLL_11_2896MHZ;
506 break;
507 case 12000000:
508 pll |= AK4671_PLL_12MHZ;
509 break;
510 case 12288000:
511 pll |= AK4671_PLL_12_288MHZ;
512 break;
513 case 13000000:
514 pll |= AK4671_PLL_13MHZ;
515 break;
516 case 13500000:
517 pll |= AK4671_PLL_13_5MHZ;
518 break;
519 case 19200000:
520 pll |= AK4671_PLL_19_2MHZ;
521 break;
522 case 24000000:
523 pll |= AK4671_PLL_24MHZ;
524 break;
525 case 26000000:
526 pll |= AK4671_PLL_26MHZ;
527 break;
528 case 27000000:
529 pll |= AK4671_PLL_27MHZ;
530 break;
531 default:
532 return -EINVAL;
533 }
534
535 snd_soc_write(codec, AK4671_PLL_MODE_SELECT0, pll);
536
537 return 0;
538}
539
540static int ak4671_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
541{
542 struct snd_soc_codec *codec = dai->codec;
543 u8 mode;
544 u8 format;
545
546 /* set master/slave audio interface */
547 mode = snd_soc_read(codec, AK4671_PLL_MODE_SELECT1);
548
549 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
550 case SND_SOC_DAIFMT_CBM_CFM:
551 mode |= AK4671_M_S;
552 break;
553 case SND_SOC_DAIFMT_CBM_CFS:
554 mode &= ~(AK4671_M_S);
555 break;
556 default:
557 return -EINVAL;
558 }
559
560 /* interface format */
561 format = snd_soc_read(codec, AK4671_FORMAT_SELECT);
562 format &= ~AK4671_DIF;
563
564 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
565 case SND_SOC_DAIFMT_I2S:
566 format |= AK4671_DIF_I2S_MODE;
567 break;
568 case SND_SOC_DAIFMT_LEFT_J:
569 format |= AK4671_DIF_MSB_MODE;
570 break;
571 case SND_SOC_DAIFMT_DSP_A:
572 format |= AK4671_DIF_DSP_MODE;
573 format |= AK4671_BCKP;
574 format |= AK4671_MSBS;
575 break;
576 default:
577 return -EINVAL;
578 }
579
580 /* set mode and format */
581 snd_soc_write(codec, AK4671_PLL_MODE_SELECT1, mode);
582 snd_soc_write(codec, AK4671_FORMAT_SELECT, format);
583
584 return 0;
585}
586
587static int ak4671_set_bias_level(struct snd_soc_codec *codec,
588 enum snd_soc_bias_level level)
589{
590 u8 reg;
591
592 switch (level) {
593 case SND_SOC_BIAS_ON:
594 case SND_SOC_BIAS_PREPARE:
595 case SND_SOC_BIAS_STANDBY:
596 reg = snd_soc_read(codec, AK4671_AD_DA_POWER_MANAGEMENT);
597 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT,
598 reg | AK4671_PMVCM);
599 break;
600 case SND_SOC_BIAS_OFF:
601 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
602 break;
603 }
604 codec->bias_level = level;
605 return 0;
606}
607
608#define AK4671_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
609 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
610 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
611 SNDRV_PCM_RATE_48000)
612
613#define AK4671_FORMATS SNDRV_PCM_FMTBIT_S16_LE
614
615static struct snd_soc_dai_ops ak4671_dai_ops = {
616 .hw_params = ak4671_hw_params,
617 .set_sysclk = ak4671_set_dai_sysclk,
618 .set_fmt = ak4671_set_dai_fmt,
619};
620
621struct snd_soc_dai ak4671_dai = {
622 .name = "AK4671",
623 .playback = {
624 .stream_name = "Playback",
625 .channels_min = 1,
626 .channels_max = 2,
627 .rates = AK4671_RATES,
628 .formats = AK4671_FORMATS,},
629 .capture = {
630 .stream_name = "Capture",
631 .channels_min = 1,
632 .channels_max = 2,
633 .rates = AK4671_RATES,
634 .formats = AK4671_FORMATS,},
635 .ops = &ak4671_dai_ops,
636};
637EXPORT_SYMBOL_GPL(ak4671_dai);
638
639static int ak4671_probe(struct platform_device *pdev)
640{
641 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
642 struct snd_soc_codec *codec;
643 int ret = 0;
644
645 if (ak4671_codec == NULL) {
646 dev_err(&pdev->dev, "Codec device not registered\n");
647 return -ENODEV;
648 }
649
650 socdev->card->codec = ak4671_codec;
651 codec = ak4671_codec;
652
653 /* register pcms */
654 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
655 if (ret < 0) {
656 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
657 goto pcm_err;
658 }
659
660 snd_soc_add_controls(codec, ak4671_snd_controls,
661 ARRAY_SIZE(ak4671_snd_controls));
662 ak4671_add_widgets(codec);
663
664 ak4671_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
665
666 return ret;
667
668pcm_err:
669 return ret;
670}
671
672static int ak4671_remove(struct platform_device *pdev)
673{
674 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
675
676 snd_soc_free_pcms(socdev);
677 snd_soc_dapm_free(socdev);
678
679 return 0;
680}
681
682struct snd_soc_codec_device soc_codec_dev_ak4671 = {
683 .probe = ak4671_probe,
684 .remove = ak4671_remove,
685};
686EXPORT_SYMBOL_GPL(soc_codec_dev_ak4671);
687
688static int ak4671_register(struct ak4671_priv *ak4671,
689 enum snd_soc_control_type control)
690{
691 int ret;
692 struct snd_soc_codec *codec = &ak4671->codec;
693
694 if (ak4671_codec) {
695 dev_err(codec->dev, "Another AK4671 is registered\n");
696 ret = -EINVAL;
697 goto err;
698 }
699
700 mutex_init(&codec->mutex);
701 INIT_LIST_HEAD(&codec->dapm_widgets);
702 INIT_LIST_HEAD(&codec->dapm_paths);
703
704 codec->private_data = ak4671;
705 codec->name = "AK4671";
706 codec->owner = THIS_MODULE;
707 codec->bias_level = SND_SOC_BIAS_OFF;
708 codec->set_bias_level = ak4671_set_bias_level;
709 codec->dai = &ak4671_dai;
710 codec->num_dai = 1;
711 codec->reg_cache_size = AK4671_CACHEREGNUM;
712 codec->reg_cache = &ak4671->reg_cache;
713
714 memcpy(codec->reg_cache, ak4671_reg, sizeof(ak4671_reg));
715
716 ret = snd_soc_codec_set_cache_io(codec, 8, 8, control);
717 if (ret < 0) {
718 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
719 goto err;
720 }
721
722 ak4671_dai.dev = codec->dev;
723 ak4671_codec = codec;
724
725 ret = snd_soc_register_codec(codec);
726 if (ret != 0) {
727 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
728 goto err;
729 }
730
731 ret = snd_soc_register_dai(&ak4671_dai);
732 if (ret != 0) {
733 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
734 goto err_codec;
735 }
736
737 return 0;
738
739err_codec:
740 snd_soc_unregister_codec(codec);
741err:
742 kfree(ak4671);
743 return ret;
744}
745
746static void ak4671_unregister(struct ak4671_priv *ak4671)
747{
748 ak4671_set_bias_level(&ak4671->codec, SND_SOC_BIAS_OFF);
749 snd_soc_unregister_dai(&ak4671_dai);
750 snd_soc_unregister_codec(&ak4671->codec);
751 kfree(ak4671);
752 ak4671_codec = NULL;
753}
754
755static int __devinit ak4671_i2c_probe(struct i2c_client *client,
756 const struct i2c_device_id *id)
757{
758 struct ak4671_priv *ak4671;
759 struct snd_soc_codec *codec;
760
761 ak4671 = kzalloc(sizeof(struct ak4671_priv), GFP_KERNEL);
762 if (ak4671 == NULL)
763 return -ENOMEM;
764
765 codec = &ak4671->codec;
766 codec->hw_write = (hw_write_t)i2c_master_send;
767
768 i2c_set_clientdata(client, ak4671);
769 codec->control_data = client;
770
771 codec->dev = &client->dev;
772
773 return ak4671_register(ak4671, SND_SOC_I2C);
774}
775
776static __devexit int ak4671_i2c_remove(struct i2c_client *client)
777{
778 struct ak4671_priv *ak4671 = i2c_get_clientdata(client);
779
780 ak4671_unregister(ak4671);
781
782 return 0;
783}
784
785static const struct i2c_device_id ak4671_i2c_id[] = {
786 { "ak4671", 0 },
787 { }
788};
789MODULE_DEVICE_TABLE(i2c, ak4671_i2c_id);
790
791static struct i2c_driver ak4671_i2c_driver = {
792 .driver = {
793 .name = "ak4671",
794 .owner = THIS_MODULE,
795 },
796 .probe = ak4671_i2c_probe,
797 .remove = __devexit_p(ak4671_i2c_remove),
798 .id_table = ak4671_i2c_id,
799};
800
801static int __init ak4671_modinit(void)
802{
803 return i2c_add_driver(&ak4671_i2c_driver);
804}
805module_init(ak4671_modinit);
806
807static void __exit ak4671_exit(void)
808{
809 i2c_del_driver(&ak4671_i2c_driver);
810}
811module_exit(ak4671_exit);
812
813MODULE_DESCRIPTION("ASoC AK4671 codec driver");
814MODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>");
815MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4671.h b/sound/soc/codecs/ak4671.h
new file mode 100644
index 000000000000..e2fad964e88b
--- /dev/null
+++ b/sound/soc/codecs/ak4671.h
@@ -0,0 +1,156 @@
1/*
2 * ak4671.h -- audio driver for AK4671
3 *
4 * Copyright (C) 2009 Samsung Electronics Co.Ltd
5 * Author: Joonyoung Shim <jy0922.shim@samsung.com>
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#ifndef _AK4671_H
15#define _AK4671_H
16
17#define AK4671_AD_DA_POWER_MANAGEMENT 0x00
18#define AK4671_PLL_MODE_SELECT0 0x01
19#define AK4671_PLL_MODE_SELECT1 0x02
20#define AK4671_FORMAT_SELECT 0x03
21#define AK4671_MIC_SIGNAL_SELECT 0x04
22#define AK4671_MIC_AMP_GAIN 0x05
23#define AK4671_MIXING_POWER_MANAGEMENT0 0x06
24#define AK4671_MIXING_POWER_MANAGEMENT1 0x07
25#define AK4671_OUTPUT_VOLUME_CONTROL 0x08
26#define AK4671_LOUT1_SIGNAL_SELECT 0x09
27#define AK4671_ROUT1_SIGNAL_SELECT 0x0a
28#define AK4671_LOUT2_SIGNAL_SELECT 0x0b
29#define AK4671_ROUT2_SIGNAL_SELECT 0x0c
30#define AK4671_LOUT3_SIGNAL_SELECT 0x0d
31#define AK4671_ROUT3_SIGNAL_SELECT 0x0e
32#define AK4671_LOUT1_POWER_MANAGERMENT 0x0f
33#define AK4671_LOUT2_POWER_MANAGERMENT 0x10
34#define AK4671_LOUT3_POWER_MANAGERMENT 0x11
35#define AK4671_LCH_INPUT_VOLUME_CONTROL 0x12
36#define AK4671_RCH_INPUT_VOLUME_CONTROL 0x13
37#define AK4671_ALC_REFERENCE_SELECT 0x14
38#define AK4671_DIGITAL_MIXING_CONTROL 0x15
39#define AK4671_ALC_TIMER_SELECT 0x16
40#define AK4671_ALC_MODE_CONTROL 0x17
41#define AK4671_MODE_CONTROL1 0x18
42#define AK4671_MODE_CONTROL2 0x19
43#define AK4671_LCH_OUTPUT_VOLUME_CONTROL 0x1a
44#define AK4671_RCH_OUTPUT_VOLUME_CONTROL 0x1b
45#define AK4671_SIDETONE_A_CONTROL 0x1c
46#define AK4671_DIGITAL_FILTER_SELECT 0x1d
47#define AK4671_FIL3_COEFFICIENT0 0x1e
48#define AK4671_FIL3_COEFFICIENT1 0x1f
49#define AK4671_FIL3_COEFFICIENT2 0x20
50#define AK4671_FIL3_COEFFICIENT3 0x21
51#define AK4671_EQ_COEFFICIENT0 0x22
52#define AK4671_EQ_COEFFICIENT1 0x23
53#define AK4671_EQ_COEFFICIENT2 0x24
54#define AK4671_EQ_COEFFICIENT3 0x25
55#define AK4671_EQ_COEFFICIENT4 0x26
56#define AK4671_EQ_COEFFICIENT5 0x27
57#define AK4671_FIL1_COEFFICIENT0 0x28
58#define AK4671_FIL1_COEFFICIENT1 0x29
59#define AK4671_FIL1_COEFFICIENT2 0x2a
60#define AK4671_FIL1_COEFFICIENT3 0x2b
61#define AK4671_FIL2_COEFFICIENT0 0x2c
62#define AK4671_FIL2_COEFFICIENT1 0x2d
63#define AK4671_FIL2_COEFFICIENT2 0x2e
64#define AK4671_FIL2_COEFFICIENT3 0x2f
65#define AK4671_DIGITAL_FILTER_SELECT2 0x30
66#define AK4671_E1_COEFFICIENT0 0x32
67#define AK4671_E1_COEFFICIENT1 0x33
68#define AK4671_E1_COEFFICIENT2 0x34
69#define AK4671_E1_COEFFICIENT3 0x35
70#define AK4671_E1_COEFFICIENT4 0x36
71#define AK4671_E1_COEFFICIENT5 0x37
72#define AK4671_E2_COEFFICIENT0 0x38
73#define AK4671_E2_COEFFICIENT1 0x39
74#define AK4671_E2_COEFFICIENT2 0x3a
75#define AK4671_E2_COEFFICIENT3 0x3b
76#define AK4671_E2_COEFFICIENT4 0x3c
77#define AK4671_E2_COEFFICIENT5 0x3d
78#define AK4671_E3_COEFFICIENT0 0x3e
79#define AK4671_E3_COEFFICIENT1 0x3f
80#define AK4671_E3_COEFFICIENT2 0x40
81#define AK4671_E3_COEFFICIENT3 0x41
82#define AK4671_E3_COEFFICIENT4 0x42
83#define AK4671_E3_COEFFICIENT5 0x43
84#define AK4671_E4_COEFFICIENT0 0x44
85#define AK4671_E4_COEFFICIENT1 0x45
86#define AK4671_E4_COEFFICIENT2 0x46
87#define AK4671_E4_COEFFICIENT3 0x47
88#define AK4671_E4_COEFFICIENT4 0x48
89#define AK4671_E4_COEFFICIENT5 0x49
90#define AK4671_E5_COEFFICIENT0 0x4a
91#define AK4671_E5_COEFFICIENT1 0x4b
92#define AK4671_E5_COEFFICIENT2 0x4c
93#define AK4671_E5_COEFFICIENT3 0x4d
94#define AK4671_E5_COEFFICIENT4 0x4e
95#define AK4671_E5_COEFFICIENT5 0x4f
96#define AK4671_EQ_CONTROL_250HZ_100HZ 0x50
97#define AK4671_EQ_CONTROL_3500HZ_1KHZ 0x51
98#define AK4671_EQ_CONTRO_10KHZ 0x52
99#define AK4671_PCM_IF_CONTROL0 0x53
100#define AK4671_PCM_IF_CONTROL1 0x54
101#define AK4671_PCM_IF_CONTROL2 0x55
102#define AK4671_DIGITAL_VOLUME_B_CONTROL 0x56
103#define AK4671_DIGITAL_VOLUME_C_CONTROL 0x57
104#define AK4671_SIDETONE_VOLUME_CONTROL 0x58
105#define AK4671_DIGITAL_MIXING_CONTROL2 0x59
106#define AK4671_SAR_ADC_CONTROL 0x5a
107
108#define AK4671_CACHEREGNUM (AK4671_SAR_ADC_CONTROL + 1)
109
110/* Bitfield Definitions */
111
112/* AK4671_AD_DA_POWER_MANAGEMENT (0x00) Fields */
113#define AK4671_PMVCM 0x01
114
115/* AK4671_PLL_MODE_SELECT0 (0x01) Fields */
116#define AK4671_PLL 0x0f
117#define AK4671_PLL_11_2896MHZ (4 << 0)
118#define AK4671_PLL_12_288MHZ (5 << 0)
119#define AK4671_PLL_12MHZ (6 << 0)
120#define AK4671_PLL_24MHZ (7 << 0)
121#define AK4671_PLL_19_2MHZ (8 << 0)
122#define AK4671_PLL_13_5MHZ (12 << 0)
123#define AK4671_PLL_27MHZ (13 << 0)
124#define AK4671_PLL_13MHZ (14 << 0)
125#define AK4671_PLL_26MHZ (15 << 0)
126#define AK4671_FS 0xf0
127#define AK4671_FS_8KHZ (0 << 4)
128#define AK4671_FS_12KHZ (1 << 4)
129#define AK4671_FS_16KHZ (2 << 4)
130#define AK4671_FS_24KHZ (3 << 4)
131#define AK4671_FS_11_025KHZ (5 << 4)
132#define AK4671_FS_22_05KHZ (7 << 4)
133#define AK4671_FS_32KHZ (10 << 4)
134#define AK4671_FS_48KHZ (11 << 4)
135#define AK4671_FS_44_1KHZ (15 << 4)
136
137/* AK4671_PLL_MODE_SELECT1 (0x02) Fields */
138#define AK4671_PMPLL 0x01
139#define AK4671_M_S 0x02
140
141/* AK4671_FORMAT_SELECT (0x03) Fields */
142#define AK4671_DIF 0x03
143#define AK4671_DIF_DSP_MODE (0 << 0)
144#define AK4671_DIF_MSB_MODE (2 << 0)
145#define AK4671_DIF_I2S_MODE (3 << 0)
146#define AK4671_BCKP 0x04
147#define AK4671_MSBS 0x08
148#define AK4671_SDOD 0x10
149
150/* AK4671_LOUT2_POWER_MANAGEMENT (0x10) Fields */
151#define AK4671_MUTEN 0x04
152
153extern struct snd_soc_dai ak4671_dai;
154extern struct snd_soc_codec_device soc_codec_dev_ak4671;
155
156#endif
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index ca1e24a8f12a..ffe122d1cd76 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -520,6 +520,7 @@ static const struct snd_kcontrol_new cs4270_snd_controls[] = {
520 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0), 520 SOC_SINGLE("Digital Sidetone Switch", CS4270_FORMAT, 5, 1, 0),
521 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0), 521 SOC_SINGLE("Soft Ramp Switch", CS4270_TRANS, 6, 1, 0),
522 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0), 522 SOC_SINGLE("Zero Cross Switch", CS4270_TRANS, 5, 1, 0),
523 SOC_SINGLE("De-emphasis filter", CS4270_TRANS, 0, 1, 0),
523 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1), 524 SOC_SINGLE("Popguard Switch", CS4270_MODE, 0, 1, 1),
524 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0), 525 SOC_SINGLE("Auto-Mute Switch", CS4270_MUTE, 5, 1, 0),
525 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1), 526 SOC_DOUBLE("Master Capture Switch", CS4270_MUTE, 3, 4, 1, 1),
@@ -598,13 +599,6 @@ static int cs4270_probe(struct platform_device *pdev)
598 goto error_free_pcms; 599 goto error_free_pcms;
599 } 600 }
600 601
601 /* And finally, register the socdev */
602 ret = snd_soc_init_card(socdev);
603 if (ret < 0) {
604 dev_err(codec->dev, "failed to register card\n");
605 goto error_free_pcms;
606 }
607
608 return 0; 602 return 0;
609 603
610error_free_pcms: 604error_free_pcms:
@@ -802,22 +796,6 @@ MODULE_DEVICE_TABLE(i2c, cs4270_id);
802 * and all registers are written back to the hardware when resuming. 796 * and all registers are written back to the hardware when resuming.
803 */ 797 */
804 798
805static int cs4270_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
806{
807 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
808 struct snd_soc_codec *codec = &cs4270->codec;
809
810 return snd_soc_suspend_device(codec->dev);
811}
812
813static int cs4270_i2c_resume(struct i2c_client *client)
814{
815 struct cs4270_private *cs4270 = i2c_get_clientdata(client);
816 struct snd_soc_codec *codec = &cs4270->codec;
817
818 return snd_soc_resume_device(codec->dev);
819}
820
821static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg) 799static int cs4270_soc_suspend(struct platform_device *pdev, pm_message_t mesg)
822{ 800{
823 struct snd_soc_codec *codec = cs4270_codec; 801 struct snd_soc_codec *codec = cs4270_codec;
@@ -853,8 +831,6 @@ static int cs4270_soc_resume(struct platform_device *pdev)
853 return snd_soc_write(codec, CS4270_PWRCTL, reg); 831 return snd_soc_write(codec, CS4270_PWRCTL, reg);
854} 832}
855#else 833#else
856#define cs4270_i2c_suspend NULL
857#define cs4270_i2c_resume NULL
858#define cs4270_soc_suspend NULL 834#define cs4270_soc_suspend NULL
859#define cs4270_soc_resume NULL 835#define cs4270_soc_resume NULL
860#endif /* CONFIG_PM */ 836#endif /* CONFIG_PM */
@@ -873,8 +849,6 @@ static struct i2c_driver cs4270_i2c_driver = {
873 .id_table = cs4270_id, 849 .id_table = cs4270_id,
874 .probe = cs4270_i2c_probe, 850 .probe = cs4270_i2c_probe,
875 .remove = cs4270_i2c_remove, 851 .remove = cs4270_i2c_remove,
876 .suspend = cs4270_i2c_suspend,
877 .resume = cs4270_i2c_resume,
878}; 852};
879 853
880/* 854/*
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index 38eac9c866e1..e000cdfec1ec 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -93,7 +93,6 @@ static int cx20442_add_widgets(struct snd_soc_codec *codec)
93 snd_soc_dapm_add_routes(codec, cx20442_audio_map, 93 snd_soc_dapm_add_routes(codec, cx20442_audio_map,
94 ARRAY_SIZE(cx20442_audio_map)); 94 ARRAY_SIZE(cx20442_audio_map));
95 95
96 snd_soc_dapm_new_widgets(codec);
97 return 0; 96 return 0;
98} 97}
99 98
@@ -355,17 +354,6 @@ static int cx20442_codec_probe(struct platform_device *pdev)
355 354
356 cx20442_add_widgets(codec); 355 cx20442_add_widgets(codec);
357 356
358 ret = snd_soc_init_card(socdev);
359 if (ret < 0) {
360 dev_err(&pdev->dev, "failed to register card\n");
361 goto card_err;
362 }
363
364 return ret;
365
366card_err:
367 snd_soc_free_pcms(socdev);
368 snd_soc_dapm_free(socdev);
369pcm_err: 357pcm_err:
370 return ret; 358 return ret;
371} 359}
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
index 5cda9e6b5a74..2afcd0a8669d 100644
--- a/sound/soc/codecs/pcm3008.c
+++ b/sound/soc/codecs/pcm3008.c
@@ -90,13 +90,6 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
90 goto pcm_err; 90 goto pcm_err;
91 } 91 }
92 92
93 /* Register Card. */
94 ret = snd_soc_init_card(socdev);
95 if (ret < 0) {
96 printk(KERN_ERR "pcm3008: failed to register card\n");
97 goto card_err;
98 }
99
100 /* DEM1 DEM0 DE-EMPHASIS_MODE 93 /* DEM1 DEM0 DE-EMPHASIS_MODE
101 * Low Low De-emphasis 44.1 kHz ON 94 * Low Low De-emphasis 44.1 kHz ON
102 * Low High De-emphasis OFF 95 * Low High De-emphasis OFF
@@ -136,8 +129,6 @@ static int pcm3008_soc_probe(struct platform_device *pdev)
136 129
137gpio_err: 130gpio_err:
138 pcm3008_gpio_free(setup); 131 pcm3008_gpio_free(setup);
139card_err:
140 snd_soc_free_pcms(socdev);
141pcm_err: 132pcm_err:
142 kfree(socdev->card->codec); 133 kfree(socdev->card->codec);
143 134
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index c550750c79c0..d2ff1cde6883 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -210,7 +210,6 @@ static int ssm2602_add_widgets(struct snd_soc_codec *codec)
210 210
211 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn)); 211 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn));
212 212
213 snd_soc_dapm_new_widgets(codec);
214 return 0; 213 return 0;
215} 214}
216 215
@@ -613,17 +612,9 @@ static int ssm2602_init(struct snd_soc_device *socdev)
613 snd_soc_add_controls(codec, ssm2602_snd_controls, 612 snd_soc_add_controls(codec, ssm2602_snd_controls,
614 ARRAY_SIZE(ssm2602_snd_controls)); 613 ARRAY_SIZE(ssm2602_snd_controls));
615 ssm2602_add_widgets(codec); 614 ssm2602_add_widgets(codec);
616 ret = snd_soc_init_card(socdev);
617 if (ret < 0) {
618 pr_err("ssm2602: failed to register card\n");
619 goto card_err;
620 }
621 615
622 return ret; 616 return ret;
623 617
624card_err:
625 snd_soc_free_pcms(socdev);
626 snd_soc_dapm_free(socdev);
627pcm_err: 618pcm_err:
628 kfree(codec->reg_cache); 619 kfree(codec->reg_cache);
629 return ret; 620 return ret;
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index befc6488c39a..bbc72c2ddfca 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -418,9 +418,6 @@ static int stac9766_codec_probe(struct platform_device *pdev)
418 snd_soc_add_controls(codec, stac9766_snd_ac97_controls, 418 snd_soc_add_controls(codec, stac9766_snd_ac97_controls,
419 ARRAY_SIZE(stac9766_snd_ac97_controls)); 419 ARRAY_SIZE(stac9766_snd_ac97_controls));
420 420
421 ret = snd_soc_init_card(socdev);
422 if (ret < 0)
423 goto reset_err;
424 return 0; 421 return 0;
425 422
426reset_err: 423reset_err:
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 35606ae60868..a9dc5fb54774 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -265,8 +265,8 @@ static const int bosr_usb_divisor_table[] = {
265#define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15)) 265#define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15))
266static const unsigned short sr_valid_mask[] = { 266static const unsigned short sr_valid_mask[] = {
267 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/ 267 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/
268 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/
269 LOWER_GROUP, /* Usb, bosr - 0*/ 268 LOWER_GROUP, /* Usb, bosr - 0*/
269 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/
270 UPPER_GROUP, /* Usb, bosr - 1*/ 270 UPPER_GROUP, /* Usb, bosr - 1*/
271}; 271};
272/* 272/*
@@ -395,7 +395,6 @@ static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
395 /* set up audio path interconnects */ 395 /* set up audio path interconnects */
396 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 396 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
397 397
398 snd_soc_dapm_new_widgets(codec);
399 return 0; 398 return 0;
400} 399}
401 400
@@ -625,11 +624,10 @@ static int tlv320aic23_resume(struct platform_device *pdev)
625{ 624{
626 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 625 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
627 struct snd_soc_codec *codec = socdev->card->codec; 626 struct snd_soc_codec *codec = socdev->card->codec;
628 int i;
629 u16 reg; 627 u16 reg;
630 628
631 /* Sync reg_cache with the hardware */ 629 /* Sync reg_cache with the hardware */
632 for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) { 630 for (reg = 0; reg < TLV320AIC23_RESET; reg++) {
633 u16 val = tlv320aic23_read_reg_cache(codec, reg); 631 u16 val = tlv320aic23_read_reg_cache(codec, reg);
634 tlv320aic23_write(codec, reg, val); 632 tlv320aic23_write(codec, reg, val);
635 } 633 }
@@ -707,17 +705,9 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
707 snd_soc_add_controls(codec, tlv320aic23_snd_controls, 705 snd_soc_add_controls(codec, tlv320aic23_snd_controls,
708 ARRAY_SIZE(tlv320aic23_snd_controls)); 706 ARRAY_SIZE(tlv320aic23_snd_controls));
709 tlv320aic23_add_widgets(codec); 707 tlv320aic23_add_widgets(codec);
710 ret = snd_soc_init_card(socdev);
711 if (ret < 0) {
712 printk(KERN_ERR "tlv320aic23: failed to register card\n");
713 goto card_err;
714 }
715 708
716 return ret; 709 return ret;
717 710
718card_err:
719 snd_soc_free_pcms(socdev);
720 snd_soc_dapm_free(socdev);
721pcm_err: 711pcm_err:
722 kfree(codec->reg_cache); 712 kfree(codec->reg_cache);
723 return ret; 713 return ret;
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 3387d9e736ea..357b609196e3 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -356,18 +356,7 @@ static int aic26_probe(struct platform_device *pdev)
356 ARRAY_SIZE(aic26_snd_controls)); 356 ARRAY_SIZE(aic26_snd_controls));
357 WARN_ON(err < 0); 357 WARN_ON(err < 0);
358 358
359 /* CODEC is setup, we can register the card now */
360 dev_dbg(&pdev->dev, "Registering card\n");
361 ret = snd_soc_init_card(socdev);
362 if (ret < 0) {
363 dev_err(&pdev->dev, "aic26: failed to register card\n");
364 goto card_err;
365 }
366 return 0; 359 return 0;
367
368 card_err:
369 snd_soc_free_pcms(socdev);
370 return ret;
371} 360}
372 361
373static int aic26_remove(struct platform_device *pdev) 362static int aic26_remove(struct platform_device *pdev)
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 3395cf945d56..2b4dc2b0b017 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -753,7 +753,6 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
753 /* set up audio path interconnects */ 753 /* set up audio path interconnects */
754 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 754 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
755 755
756 snd_soc_dapm_new_widgets(codec);
757 return 0; 756 return 0;
758} 757}
759 758
@@ -1405,18 +1404,8 @@ static int aic3x_probe(struct platform_device *pdev)
1405 1404
1406 aic3x_add_widgets(codec); 1405 aic3x_add_widgets(codec);
1407 1406
1408 ret = snd_soc_init_card(socdev);
1409 if (ret < 0) {
1410 printk(KERN_ERR "aic3x: failed to register card\n");
1411 goto card_err;
1412 }
1413
1414 return ret; 1407 return ret;
1415 1408
1416card_err:
1417 snd_soc_free_pcms(socdev);
1418 snd_soc_dapm_free(socdev);
1419
1420pcm_err: 1409pcm_err:
1421 kfree(codec->reg_cache); 1410 kfree(codec->reg_cache);
1422 return ret; 1411 return ret;
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
new file mode 100644
index 000000000000..9c8903dbe647
--- /dev/null
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -0,0 +1,1229 @@
1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
5 *
6 * Copyright: (C) 2009 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
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/i2c.h>
30#include <linux/platform_device.h>
31#include <linux/interrupt.h>
32#include <linux/gpio.h>
33#include <sound/core.h>
34#include <sound/pcm.h>
35#include <sound/pcm_params.h>
36#include <sound/soc.h>
37#include <sound/soc-dapm.h>
38#include <sound/initval.h>
39#include <sound/tlv.h>
40
41#include <sound/tlv320dac33-plat.h>
42#include "tlv320dac33.h"
43
44#define DAC33_BUFFER_SIZE_BYTES 24576 /* bytes, 12288 16 bit words,
45 * 6144 stereo */
46#define DAC33_BUFFER_SIZE_SAMPLES 6144
47
48#define NSAMPLE_MAX 5700
49
50#define LATENCY_TIME_MS 20
51
52static struct snd_soc_codec *tlv320dac33_codec;
53
54enum dac33_state {
55 DAC33_IDLE = 0,
56 DAC33_PREFILL,
57 DAC33_PLAYBACK,
58 DAC33_FLUSH,
59};
60
61struct tlv320dac33_priv {
62 struct mutex mutex;
63 struct workqueue_struct *dac33_wq;
64 struct work_struct work;
65 struct snd_soc_codec codec;
66 int power_gpio;
67 int chip_power;
68 int irq;
69 unsigned int refclk;
70
71 unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */
72 unsigned int nsample_min; /* nsample should not be lower than
73 * this */
74 unsigned int nsample_max; /* nsample should not be higher than
75 * this */
76 unsigned int nsample_switch; /* Use FIFO or bypass FIFO switch */
77 unsigned int nsample; /* burst read amount from host */
78
79 enum dac33_state state;
80};
81
82static const u8 dac33_reg[DAC33_CACHEREGNUM] = {
830x00, 0x00, 0x00, 0x00, /* 0x00 - 0x03 */
840x00, 0x00, 0x00, 0x00, /* 0x04 - 0x07 */
850x00, 0x00, 0x00, 0x00, /* 0x08 - 0x0b */
860x00, 0x00, 0x00, 0x00, /* 0x0c - 0x0f */
870x00, 0x00, 0x00, 0x00, /* 0x10 - 0x13 */
880x00, 0x00, 0x00, 0x00, /* 0x14 - 0x17 */
890x00, 0x00, 0x00, 0x00, /* 0x18 - 0x1b */
900x00, 0x00, 0x00, 0x00, /* 0x1c - 0x1f */
910x00, 0x00, 0x00, 0x00, /* 0x20 - 0x23 */
920x00, 0x00, 0x00, 0x00, /* 0x24 - 0x27 */
930x00, 0x00, 0x00, 0x00, /* 0x28 - 0x2b */
940x00, 0x00, 0x00, 0x80, /* 0x2c - 0x2f */
950x80, 0x00, 0x00, 0x00, /* 0x30 - 0x33 */
960x00, 0x00, 0x00, 0x00, /* 0x34 - 0x37 */
970x00, 0x00, /* 0x38 - 0x39 */
98/* Registers 0x3a - 0x3f are reserved */
99 0x00, 0x00, /* 0x3a - 0x3b */
1000x00, 0x00, 0x00, 0x00, /* 0x3c - 0x3f */
101
1020x00, 0x00, 0x00, 0x00, /* 0x40 - 0x43 */
1030x00, 0x80, /* 0x44 - 0x45 */
104/* Registers 0x46 - 0x47 are reserved */
105 0x80, 0x80, /* 0x46 - 0x47 */
106
1070x80, 0x00, 0x00, /* 0x48 - 0x4a */
108/* Registers 0x4b - 0x7c are reserved */
109 0x00, /* 0x4b */
1100x00, 0x00, 0x00, 0x00, /* 0x4c - 0x4f */
1110x00, 0x00, 0x00, 0x00, /* 0x50 - 0x53 */
1120x00, 0x00, 0x00, 0x00, /* 0x54 - 0x57 */
1130x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5b */
1140x00, 0x00, 0x00, 0x00, /* 0x5c - 0x5f */
1150x00, 0x00, 0x00, 0x00, /* 0x60 - 0x63 */
1160x00, 0x00, 0x00, 0x00, /* 0x64 - 0x67 */
1170x00, 0x00, 0x00, 0x00, /* 0x68 - 0x6b */
1180x00, 0x00, 0x00, 0x00, /* 0x6c - 0x6f */
1190x00, 0x00, 0x00, 0x00, /* 0x70 - 0x73 */
1200x00, 0x00, 0x00, 0x00, /* 0x74 - 0x77 */
1210x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7b */
1220x00, /* 0x7c */
123
124 0xda, 0x33, 0x03, /* 0x7d - 0x7f */
125};
126
127/* Register read and write */
128static inline unsigned int dac33_read_reg_cache(struct snd_soc_codec *codec,
129 unsigned reg)
130{
131 u8 *cache = codec->reg_cache;
132 if (reg >= DAC33_CACHEREGNUM)
133 return 0;
134
135 return cache[reg];
136}
137
138static inline void dac33_write_reg_cache(struct snd_soc_codec *codec,
139 u8 reg, u8 value)
140{
141 u8 *cache = codec->reg_cache;
142 if (reg >= DAC33_CACHEREGNUM)
143 return;
144
145 cache[reg] = value;
146}
147
148static int dac33_read(struct snd_soc_codec *codec, unsigned int reg,
149 u8 *value)
150{
151 struct tlv320dac33_priv *dac33 = codec->private_data;
152 int val;
153
154 *value = reg & 0xff;
155
156 /* If powered off, return the cached value */
157 if (dac33->chip_power) {
158 val = i2c_smbus_read_byte_data(codec->control_data, value[0]);
159 if (val < 0) {
160 dev_err(codec->dev, "Read failed (%d)\n", val);
161 value[0] = dac33_read_reg_cache(codec, reg);
162 } else {
163 value[0] = val;
164 dac33_write_reg_cache(codec, reg, val);
165 }
166 } else {
167 value[0] = dac33_read_reg_cache(codec, reg);
168 }
169
170 return 0;
171}
172
173static int dac33_write(struct snd_soc_codec *codec, unsigned int reg,
174 unsigned int value)
175{
176 struct tlv320dac33_priv *dac33 = codec->private_data;
177 u8 data[2];
178 int ret = 0;
179
180 /*
181 * data is
182 * D15..D8 dac33 register offset
183 * D7...D0 register data
184 */
185 data[0] = reg & 0xff;
186 data[1] = value & 0xff;
187
188 dac33_write_reg_cache(codec, data[0], data[1]);
189 if (dac33->chip_power) {
190 ret = codec->hw_write(codec->control_data, data, 2);
191 if (ret != 2)
192 dev_err(codec->dev, "Write failed (%d)\n", ret);
193 else
194 ret = 0;
195 }
196
197 return ret;
198}
199
200static int dac33_write_locked(struct snd_soc_codec *codec, unsigned int reg,
201 unsigned int value)
202{
203 struct tlv320dac33_priv *dac33 = codec->private_data;
204 int ret;
205
206 mutex_lock(&dac33->mutex);
207 ret = dac33_write(codec, reg, value);
208 mutex_unlock(&dac33->mutex);
209
210 return ret;
211}
212
213#define DAC33_I2C_ADDR_AUTOINC 0x80
214static int dac33_write16(struct snd_soc_codec *codec, unsigned int reg,
215 unsigned int value)
216{
217 struct tlv320dac33_priv *dac33 = codec->private_data;
218 u8 data[3];
219 int ret = 0;
220
221 /*
222 * data is
223 * D23..D16 dac33 register offset
224 * D15..D8 register data MSB
225 * D7...D0 register data LSB
226 */
227 data[0] = reg & 0xff;
228 data[1] = (value >> 8) & 0xff;
229 data[2] = value & 0xff;
230
231 dac33_write_reg_cache(codec, data[0], data[1]);
232 dac33_write_reg_cache(codec, data[0] + 1, data[2]);
233
234 if (dac33->chip_power) {
235 /* We need to set autoincrement mode for 16 bit writes */
236 data[0] |= DAC33_I2C_ADDR_AUTOINC;
237 ret = codec->hw_write(codec->control_data, data, 3);
238 if (ret != 3)
239 dev_err(codec->dev, "Write failed (%d)\n", ret);
240 else
241 ret = 0;
242 }
243
244 return ret;
245}
246
247static void dac33_restore_regs(struct snd_soc_codec *codec)
248{
249 struct tlv320dac33_priv *dac33 = codec->private_data;
250 u8 *cache = codec->reg_cache;
251 u8 data[2];
252 int i, ret;
253
254 if (!dac33->chip_power)
255 return;
256
257 for (i = DAC33_PWR_CTRL; i <= DAC33_INTP_CTRL_B; i++) {
258 data[0] = i;
259 data[1] = cache[i];
260 /* Skip the read only registers */
261 if ((i >= DAC33_INT_OSC_STATUS &&
262 i <= DAC33_INT_OSC_FREQ_RAT_READ_B) ||
263 (i >= DAC33_FIFO_WPTR_MSB && i <= DAC33_FIFO_IRQ_FLAG) ||
264 i == DAC33_DAC_STATUS_FLAGS ||
265 i == DAC33_SRC_EST_REF_CLK_RATIO_A ||
266 i == DAC33_SRC_EST_REF_CLK_RATIO_B)
267 continue;
268 ret = codec->hw_write(codec->control_data, data, 2);
269 if (ret != 2)
270 dev_err(codec->dev, "Write failed (%d)\n", ret);
271 }
272 for (i = DAC33_LDAC_PWR_CTRL; i <= DAC33_LINEL_TO_LLO_VOL; i++) {
273 data[0] = i;
274 data[1] = cache[i];
275 ret = codec->hw_write(codec->control_data, data, 2);
276 if (ret != 2)
277 dev_err(codec->dev, "Write failed (%d)\n", ret);
278 }
279 for (i = DAC33_LINER_TO_RLO_VOL; i <= DAC33_OSC_TRIM; i++) {
280 data[0] = i;
281 data[1] = cache[i];
282 ret = codec->hw_write(codec->control_data, data, 2);
283 if (ret != 2)
284 dev_err(codec->dev, "Write failed (%d)\n", ret);
285 }
286}
287
288static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
289{
290 u8 reg;
291
292 reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
293 if (power)
294 reg |= DAC33_PDNALLB;
295 else
296 reg &= ~DAC33_PDNALLB;
297 dac33_write(codec, DAC33_PWR_CTRL, reg);
298}
299
300static void dac33_hard_power(struct snd_soc_codec *codec, int power)
301{
302 struct tlv320dac33_priv *dac33 = codec->private_data;
303
304 mutex_lock(&dac33->mutex);
305 if (power) {
306 if (dac33->power_gpio >= 0) {
307 gpio_set_value(dac33->power_gpio, 1);
308 dac33->chip_power = 1;
309 /* Restore registers */
310 dac33_restore_regs(codec);
311 }
312 dac33_soft_power(codec, 1);
313 } else {
314 dac33_soft_power(codec, 0);
315 if (dac33->power_gpio >= 0) {
316 gpio_set_value(dac33->power_gpio, 0);
317 dac33->chip_power = 0;
318 }
319 }
320 mutex_unlock(&dac33->mutex);
321
322}
323
324static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
325 struct snd_ctl_elem_value *ucontrol)
326{
327 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
328 struct tlv320dac33_priv *dac33 = codec->private_data;
329
330 ucontrol->value.integer.value[0] = dac33->nsample;
331
332 return 0;
333}
334
335static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
336 struct snd_ctl_elem_value *ucontrol)
337{
338 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
339 struct tlv320dac33_priv *dac33 = codec->private_data;
340 int ret = 0;
341
342 if (dac33->nsample == ucontrol->value.integer.value[0])
343 return 0;
344
345 if (ucontrol->value.integer.value[0] < dac33->nsample_min ||
346 ucontrol->value.integer.value[0] > dac33->nsample_max)
347 ret = -EINVAL;
348 else
349 dac33->nsample = ucontrol->value.integer.value[0];
350
351 return ret;
352}
353
354static int dac33_get_nsample_switch(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
356{
357 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct tlv320dac33_priv *dac33 = codec->private_data;
359
360 ucontrol->value.integer.value[0] = dac33->nsample_switch;
361
362 return 0;
363}
364
365static int dac33_set_nsample_switch(struct snd_kcontrol *kcontrol,
366 struct snd_ctl_elem_value *ucontrol)
367{
368 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
369 struct tlv320dac33_priv *dac33 = codec->private_data;
370 int ret = 0;
371
372 if (dac33->nsample_switch == ucontrol->value.integer.value[0])
373 return 0;
374 /* Do not allow changes while stream is running*/
375 if (codec->active)
376 return -EPERM;
377
378 if (ucontrol->value.integer.value[0] < 0 ||
379 ucontrol->value.integer.value[0] > 1)
380 ret = -EINVAL;
381 else
382 dac33->nsample_switch = ucontrol->value.integer.value[0];
383
384 return ret;
385}
386
387/*
388 * DACL/R digital volume control:
389 * from 0 dB to -63.5 in 0.5 dB steps
390 * Need to be inverted later on:
391 * 0x00 == 0 dB
392 * 0x7f == -63.5 dB
393 */
394static DECLARE_TLV_DB_SCALE(dac_digivol_tlv, -6350, 50, 0);
395
396static const struct snd_kcontrol_new dac33_snd_controls[] = {
397 SOC_DOUBLE_R_TLV("DAC Digital Playback Volume",
398 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL,
399 0, 0x7f, 1, dac_digivol_tlv),
400 SOC_DOUBLE_R("DAC Digital Playback Switch",
401 DAC33_LDAC_DIG_VOL_CTRL, DAC33_RDAC_DIG_VOL_CTRL, 7, 1, 1),
402 SOC_DOUBLE_R("Line to Line Out Volume",
403 DAC33_LINEL_TO_LLO_VOL, DAC33_LINER_TO_RLO_VOL, 0, 127, 1),
404};
405
406static const struct snd_kcontrol_new dac33_nsample_snd_controls[] = {
407 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
408 dac33_get_nsample, dac33_set_nsample),
409 SOC_SINGLE_EXT("nSample Switch", 0, 0, 1, 0,
410 dac33_get_nsample_switch, dac33_set_nsample_switch),
411};
412
413/* Analog bypass */
414static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
415 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
416
417static const struct snd_kcontrol_new dac33_dapm_abypassr_control =
418 SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1);
419
420static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
421 SND_SOC_DAPM_OUTPUT("LEFT_LO"),
422 SND_SOC_DAPM_OUTPUT("RIGHT_LO"),
423
424 SND_SOC_DAPM_INPUT("LINEL"),
425 SND_SOC_DAPM_INPUT("LINER"),
426
427 SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0),
428 SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0),
429
430 /* Analog bypass */
431 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
432 &dac33_dapm_abypassl_control),
433 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
434 &dac33_dapm_abypassr_control),
435
436 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power",
437 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
438 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power",
439 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
440};
441
442static const struct snd_soc_dapm_route audio_map[] = {
443 /* Analog bypass */
444 {"Analog Left Bypass", "Switch", "LINEL"},
445 {"Analog Right Bypass", "Switch", "LINER"},
446
447 {"Output Left Amp Power", NULL, "DACL"},
448 {"Output Right Amp Power", NULL, "DACR"},
449
450 {"Output Left Amp Power", NULL, "Analog Left Bypass"},
451 {"Output Right Amp Power", NULL, "Analog Right Bypass"},
452
453 /* output */
454 {"LEFT_LO", NULL, "Output Left Amp Power"},
455 {"RIGHT_LO", NULL, "Output Right Amp Power"},
456};
457
458static int dac33_add_widgets(struct snd_soc_codec *codec)
459{
460 snd_soc_dapm_new_controls(codec, dac33_dapm_widgets,
461 ARRAY_SIZE(dac33_dapm_widgets));
462
463 /* set up audio path interconnects */
464 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
465
466 return 0;
467}
468
469static int dac33_set_bias_level(struct snd_soc_codec *codec,
470 enum snd_soc_bias_level level)
471{
472 switch (level) {
473 case SND_SOC_BIAS_ON:
474 dac33_soft_power(codec, 1);
475 break;
476 case SND_SOC_BIAS_PREPARE:
477 break;
478 case SND_SOC_BIAS_STANDBY:
479 if (codec->bias_level == SND_SOC_BIAS_OFF)
480 dac33_hard_power(codec, 1);
481 dac33_soft_power(codec, 0);
482 break;
483 case SND_SOC_BIAS_OFF:
484 dac33_hard_power(codec, 0);
485 break;
486 }
487 codec->bias_level = level;
488
489 return 0;
490}
491
492static void dac33_work(struct work_struct *work)
493{
494 struct snd_soc_codec *codec;
495 struct tlv320dac33_priv *dac33;
496 u8 reg;
497
498 dac33 = container_of(work, struct tlv320dac33_priv, work);
499 codec = &dac33->codec;
500
501 mutex_lock(&dac33->mutex);
502 switch (dac33->state) {
503 case DAC33_PREFILL:
504 dac33->state = DAC33_PLAYBACK;
505 dac33_write16(codec, DAC33_NSAMPLE_MSB,
506 DAC33_THRREG(dac33->nsample));
507 dac33_write16(codec, DAC33_PREFILL_MSB,
508 DAC33_THRREG(dac33->alarm_threshold));
509 break;
510 case DAC33_PLAYBACK:
511 dac33_write16(codec, DAC33_NSAMPLE_MSB,
512 DAC33_THRREG(dac33->nsample));
513 break;
514 case DAC33_IDLE:
515 break;
516 case DAC33_FLUSH:
517 dac33->state = DAC33_IDLE;
518 /* Mask all interrupts from dac33 */
519 dac33_write(codec, DAC33_FIFO_IRQ_MASK, 0);
520
521 /* flush fifo */
522 reg = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
523 reg |= DAC33_FIFOFLUSH;
524 dac33_write(codec, DAC33_FIFO_CTRL_A, reg);
525 break;
526 }
527 mutex_unlock(&dac33->mutex);
528}
529
530static irqreturn_t dac33_interrupt_handler(int irq, void *dev)
531{
532 struct snd_soc_codec *codec = dev;
533 struct tlv320dac33_priv *dac33 = codec->private_data;
534
535 queue_work(dac33->dac33_wq, &dac33->work);
536
537 return IRQ_HANDLED;
538}
539
540static void dac33_shutdown(struct snd_pcm_substream *substream,
541 struct snd_soc_dai *dai)
542{
543 struct snd_soc_pcm_runtime *rtd = substream->private_data;
544 struct snd_soc_device *socdev = rtd->socdev;
545 struct snd_soc_codec *codec = socdev->card->codec;
546 struct tlv320dac33_priv *dac33 = codec->private_data;
547 unsigned int pwr_ctrl;
548
549 /* Stop pending workqueue */
550 if (dac33->nsample_switch)
551 cancel_work_sync(&dac33->work);
552
553 mutex_lock(&dac33->mutex);
554 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
555 pwr_ctrl &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
556 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
557 mutex_unlock(&dac33->mutex);
558}
559
560static void dac33_oscwait(struct snd_soc_codec *codec)
561{
562 int timeout = 20;
563 u8 reg;
564
565 do {
566 msleep(1);
567 dac33_read(codec, DAC33_INT_OSC_STATUS, &reg);
568 } while (((reg & 0x03) != DAC33_OSCSTATUS_NORMAL) && timeout--);
569 if ((reg & 0x03) != DAC33_OSCSTATUS_NORMAL)
570 dev_err(codec->dev,
571 "internal oscillator calibration failed\n");
572}
573
574static int dac33_hw_params(struct snd_pcm_substream *substream,
575 struct snd_pcm_hw_params *params,
576 struct snd_soc_dai *dai)
577{
578 struct snd_soc_pcm_runtime *rtd = substream->private_data;
579 struct snd_soc_device *socdev = rtd->socdev;
580 struct snd_soc_codec *codec = socdev->card->codec;
581
582 /* Check parameters for validity */
583 switch (params_rate(params)) {
584 case 44100:
585 case 48000:
586 break;
587 default:
588 dev_err(codec->dev, "unsupported rate %d\n",
589 params_rate(params));
590 return -EINVAL;
591 }
592
593 switch (params_format(params)) {
594 case SNDRV_PCM_FORMAT_S16_LE:
595 break;
596 default:
597 dev_err(codec->dev, "unsupported format %d\n",
598 params_format(params));
599 return -EINVAL;
600 }
601
602 return 0;
603}
604
605#define CALC_OSCSET(rate, refclk) ( \
606 ((((rate * 10000) / refclk) * 4096) + 5000) / 10000)
607#define CALC_RATIOSET(rate, refclk) ( \
608 ((((refclk * 100000) / rate) * 16384) + 50000) / 100000)
609
610/*
611 * tlv320dac33 is strict on the sequence of the register writes, if the register
612 * writes happens in different order, than dac33 might end up in unknown state.
613 * Use the known, working sequence of register writes to initialize the dac33.
614 */
615static int dac33_prepare_chip(struct snd_pcm_substream *substream)
616{
617 struct snd_soc_pcm_runtime *rtd = substream->private_data;
618 struct snd_soc_device *socdev = rtd->socdev;
619 struct snd_soc_codec *codec = socdev->card->codec;
620 struct tlv320dac33_priv *dac33 = codec->private_data;
621 unsigned int oscset, ratioset, pwr_ctrl, reg_tmp;
622 u8 aictrl_a, fifoctrl_a;
623
624 switch (substream->runtime->rate) {
625 case 44100:
626 case 48000:
627 oscset = CALC_OSCSET(substream->runtime->rate, dac33->refclk);
628 ratioset = CALC_RATIOSET(substream->runtime->rate,
629 dac33->refclk);
630 break;
631 default:
632 dev_err(codec->dev, "unsupported rate %d\n",
633 substream->runtime->rate);
634 return -EINVAL;
635 }
636
637
638 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
639 aictrl_a &= ~(DAC33_NCYCL_MASK | DAC33_WLEN_MASK);
640 fifoctrl_a = dac33_read_reg_cache(codec, DAC33_FIFO_CTRL_A);
641 fifoctrl_a &= ~DAC33_WIDTH;
642 switch (substream->runtime->format) {
643 case SNDRV_PCM_FORMAT_S16_LE:
644 aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16);
645 fifoctrl_a |= DAC33_WIDTH;
646 break;
647 default:
648 dev_err(codec->dev, "unsupported format %d\n",
649 substream->runtime->format);
650 return -EINVAL;
651 }
652
653 mutex_lock(&dac33->mutex);
654 dac33_soft_power(codec, 1);
655
656 reg_tmp = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
657 dac33_write(codec, DAC33_INT_OSC_CTRL, reg_tmp);
658
659 /* Write registers 0x08 and 0x09 (MSB, LSB) */
660 dac33_write16(codec, DAC33_INT_OSC_FREQ_RAT_A, oscset);
661
662 /* calib time: 128 is a nice number ;) */
663 dac33_write(codec, DAC33_CALIB_TIME, 128);
664
665 /* adjustment treshold & step */
666 dac33_write(codec, DAC33_INT_OSC_CTRL_B, DAC33_ADJTHRSHLD(2) |
667 DAC33_ADJSTEP(1));
668
669 /* div=4 / gain=1 / div */
670 dac33_write(codec, DAC33_INT_OSC_CTRL_C, DAC33_REFDIV(4));
671
672 pwr_ctrl = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
673 pwr_ctrl |= DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB;
674 dac33_write(codec, DAC33_PWR_CTRL, pwr_ctrl);
675
676 dac33_oscwait(codec);
677
678 if (dac33->nsample_switch) {
679 /* 50-51 : ASRC Control registers */
680 dac33_write(codec, DAC33_ASRC_CTRL_A, (1 << 4)); /* div=2 */
681 dac33_write(codec, DAC33_ASRC_CTRL_B, 1); /* ??? */
682
683 /* Write registers 0x34 and 0x35 (MSB, LSB) */
684 dac33_write16(codec, DAC33_SRC_REF_CLK_RATIO_A, ratioset);
685
686 /* Set interrupts to high active */
687 dac33_write(codec, DAC33_INTP_CTRL_A, DAC33_INTPM_AHIGH);
688
689 dac33_write(codec, DAC33_FIFO_IRQ_MODE_B,
690 DAC33_ATM(DAC33_FIFO_IRQ_MODE_LEVEL));
691 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MAT);
692 } else {
693 /* 50-51 : ASRC Control registers */
694 dac33_write(codec, DAC33_ASRC_CTRL_A, DAC33_SRCBYP);
695 dac33_write(codec, DAC33_ASRC_CTRL_B, 0); /* ??? */
696 }
697
698 if (dac33->nsample_switch)
699 fifoctrl_a &= ~DAC33_FBYPAS;
700 else
701 fifoctrl_a |= DAC33_FBYPAS;
702 dac33_write(codec, DAC33_FIFO_CTRL_A, fifoctrl_a);
703
704 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
705 reg_tmp = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
706 if (dac33->nsample_switch)
707 reg_tmp &= ~DAC33_BCLKON;
708 else
709 reg_tmp |= DAC33_BCLKON;
710 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg_tmp);
711
712 if (dac33->nsample_switch) {
713 /* 20: BCLK divide ratio */
714 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 3);
715
716 dac33_write16(codec, DAC33_ATHR_MSB,
717 DAC33_THRREG(dac33->alarm_threshold));
718 } else {
719 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
720 }
721
722 mutex_unlock(&dac33->mutex);
723
724 return 0;
725}
726
727static void dac33_calculate_times(struct snd_pcm_substream *substream)
728{
729 struct snd_soc_pcm_runtime *rtd = substream->private_data;
730 struct snd_soc_device *socdev = rtd->socdev;
731 struct snd_soc_codec *codec = socdev->card->codec;
732 struct tlv320dac33_priv *dac33 = codec->private_data;
733 unsigned int nsample_limit;
734
735 /* Number of samples (16bit, stereo) in one period */
736 dac33->nsample_min = snd_pcm_lib_period_bytes(substream) / 4;
737
738 /* Number of samples (16bit, stereo) in ALSA buffer */
739 dac33->nsample_max = snd_pcm_lib_buffer_bytes(substream) / 4;
740 /* Subtract one period from the total */
741 dac33->nsample_max -= dac33->nsample_min;
742
743 /* Number of samples for LATENCY_TIME_MS / 2 */
744 dac33->alarm_threshold = substream->runtime->rate /
745 (1000 / (LATENCY_TIME_MS / 2));
746
747 /* Find and fix up the lowest nsmaple limit */
748 nsample_limit = substream->runtime->rate / (1000 / LATENCY_TIME_MS);
749
750 if (dac33->nsample_min < nsample_limit)
751 dac33->nsample_min = nsample_limit;
752
753 if (dac33->nsample < dac33->nsample_min)
754 dac33->nsample = dac33->nsample_min;
755
756 /*
757 * Find and fix up the highest nsmaple limit
758 * In order to not overflow the DAC33 buffer substract the
759 * alarm_threshold value from the size of the DAC33 buffer
760 */
761 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - dac33->alarm_threshold;
762
763 if (dac33->nsample_max > nsample_limit)
764 dac33->nsample_max = nsample_limit;
765
766 if (dac33->nsample > dac33->nsample_max)
767 dac33->nsample = dac33->nsample_max;
768}
769
770static int dac33_pcm_prepare(struct snd_pcm_substream *substream,
771 struct snd_soc_dai *dai)
772{
773 dac33_calculate_times(substream);
774 dac33_prepare_chip(substream);
775
776 return 0;
777}
778
779static int dac33_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
780 struct snd_soc_dai *dai)
781{
782 struct snd_soc_pcm_runtime *rtd = substream->private_data;
783 struct snd_soc_device *socdev = rtd->socdev;
784 struct snd_soc_codec *codec = socdev->card->codec;
785 struct tlv320dac33_priv *dac33 = codec->private_data;
786 int ret = 0;
787
788 switch (cmd) {
789 case SNDRV_PCM_TRIGGER_START:
790 case SNDRV_PCM_TRIGGER_RESUME:
791 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
792 if (dac33->nsample_switch) {
793 dac33->state = DAC33_PREFILL;
794 queue_work(dac33->dac33_wq, &dac33->work);
795 }
796 break;
797 case SNDRV_PCM_TRIGGER_STOP:
798 case SNDRV_PCM_TRIGGER_SUSPEND:
799 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
800 if (dac33->nsample_switch) {
801 dac33->state = DAC33_FLUSH;
802 queue_work(dac33->dac33_wq, &dac33->work);
803 }
804 break;
805 default:
806 ret = -EINVAL;
807 }
808
809 return ret;
810}
811
812static int dac33_set_dai_sysclk(struct snd_soc_dai *codec_dai,
813 int clk_id, unsigned int freq, int dir)
814{
815 struct snd_soc_codec *codec = codec_dai->codec;
816 struct tlv320dac33_priv *dac33 = codec->private_data;
817 u8 ioc_reg, asrcb_reg;
818
819 ioc_reg = dac33_read_reg_cache(codec, DAC33_INT_OSC_CTRL);
820 asrcb_reg = dac33_read_reg_cache(codec, DAC33_ASRC_CTRL_B);
821 switch (clk_id) {
822 case TLV320DAC33_MCLK:
823 ioc_reg |= DAC33_REFSEL;
824 asrcb_reg |= DAC33_SRCREFSEL;
825 break;
826 case TLV320DAC33_SLEEPCLK:
827 ioc_reg &= ~DAC33_REFSEL;
828 asrcb_reg &= ~DAC33_SRCREFSEL;
829 break;
830 default:
831 dev_err(codec->dev, "Invalid clock ID (%d)\n", clk_id);
832 break;
833 }
834 dac33->refclk = freq;
835
836 dac33_write_reg_cache(codec, DAC33_INT_OSC_CTRL, ioc_reg);
837 dac33_write_reg_cache(codec, DAC33_ASRC_CTRL_B, asrcb_reg);
838
839 return 0;
840}
841
842static int dac33_set_dai_fmt(struct snd_soc_dai *codec_dai,
843 unsigned int fmt)
844{
845 struct snd_soc_codec *codec = codec_dai->codec;
846 u8 aictrl_a, aictrl_b;
847
848 aictrl_a = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A);
849 aictrl_b = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
850 /* set master/slave audio interface */
851 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
852 case SND_SOC_DAIFMT_CBM_CFM:
853 /* Codec Master */
854 aictrl_a |= (DAC33_MSBCLK | DAC33_MSWCLK);
855 break;
856 case SND_SOC_DAIFMT_CBS_CFS:
857 /* Codec Slave */
858 aictrl_a &= ~(DAC33_MSBCLK | DAC33_MSWCLK);
859 break;
860 default:
861 return -EINVAL;
862 }
863
864 aictrl_a &= ~DAC33_AFMT_MASK;
865 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
866 case SND_SOC_DAIFMT_I2S:
867 aictrl_a |= DAC33_AFMT_I2S;
868 break;
869 case SND_SOC_DAIFMT_DSP_A:
870 aictrl_a |= DAC33_AFMT_DSP;
871 aictrl_b &= ~DAC33_DATA_DELAY_MASK;
872 aictrl_b |= DAC33_DATA_DELAY(1); /* 1 bit delay */
873 break;
874 case SND_SOC_DAIFMT_DSP_B:
875 aictrl_a |= DAC33_AFMT_DSP;
876 aictrl_b &= ~DAC33_DATA_DELAY_MASK; /* No delay */
877 break;
878 case SND_SOC_DAIFMT_RIGHT_J:
879 aictrl_a |= DAC33_AFMT_RIGHT_J;
880 break;
881 case SND_SOC_DAIFMT_LEFT_J:
882 aictrl_a |= DAC33_AFMT_LEFT_J;
883 break;
884 default:
885 dev_err(codec->dev, "Unsupported format (%u)\n",
886 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
887 return -EINVAL;
888 }
889
890 dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_A, aictrl_a);
891 dac33_write_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B, aictrl_b);
892
893 return 0;
894}
895
896static void dac33_init_chip(struct snd_soc_codec *codec)
897{
898 /* 44-46: DAC Control Registers */
899 /* A : DAC sample rate Fsref/1.5 */
900 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(1));
901 /* B : DAC src=normal, not muted */
902 dac33_write(codec, DAC33_DAC_CTRL_B, DAC33_DACSRCR_RIGHT |
903 DAC33_DACSRCL_LEFT);
904 /* C : (defaults) */
905 dac33_write(codec, DAC33_DAC_CTRL_C, 0x00);
906
907 /* 64-65 : L&R DAC power control
908 Line In -> OUT 1V/V Gain, DAC -> OUT 4V/V Gain*/
909 dac33_write(codec, DAC33_LDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
910 dac33_write(codec, DAC33_RDAC_PWR_CTRL, DAC33_LROUT_GAIN(2));
911
912 /* 73 : volume soft stepping control,
913 clock source = internal osc (?) */
914 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
915
916 /* 66 : LOP/LOM Modes */
917 dac33_write(codec, DAC33_OUT_AMP_CM_CTRL, 0xff);
918
919 /* 68 : LOM inverted from LOP */
920 dac33_write(codec, DAC33_OUT_AMP_CTRL, (3<<2));
921
922 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
923}
924
925static int dac33_soc_probe(struct platform_device *pdev)
926{
927 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
928 struct snd_soc_codec *codec;
929 struct tlv320dac33_priv *dac33;
930 int ret = 0;
931
932 BUG_ON(!tlv320dac33_codec);
933
934 codec = tlv320dac33_codec;
935 socdev->card->codec = codec;
936 dac33 = codec->private_data;
937
938 /* Power up the codec */
939 dac33_hard_power(codec, 1);
940 /* Set default configuration */
941 dac33_init_chip(codec);
942
943 /* register pcms */
944 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
945 if (ret < 0) {
946 dev_err(codec->dev, "failed to create pcms\n");
947 goto pcm_err;
948 }
949
950 snd_soc_add_controls(codec, dac33_snd_controls,
951 ARRAY_SIZE(dac33_snd_controls));
952 /* Only add the nSample controls, if we have valid IRQ number */
953 if (dac33->irq >= 0)
954 snd_soc_add_controls(codec, dac33_nsample_snd_controls,
955 ARRAY_SIZE(dac33_nsample_snd_controls));
956
957 dac33_add_widgets(codec);
958
959 /* power on device */
960 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
961
962 return 0;
963
964pcm_err:
965 dac33_hard_power(codec, 0);
966 return ret;
967}
968
969static int dac33_soc_remove(struct platform_device *pdev)
970{
971 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
972 struct snd_soc_codec *codec = socdev->card->codec;
973
974 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
975
976 snd_soc_free_pcms(socdev);
977 snd_soc_dapm_free(socdev);
978
979 return 0;
980}
981
982static int dac33_soc_suspend(struct platform_device *pdev, pm_message_t state)
983{
984 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
985 struct snd_soc_codec *codec = socdev->card->codec;
986
987 dac33_set_bias_level(codec, SND_SOC_BIAS_OFF);
988
989 return 0;
990}
991
992static int dac33_soc_resume(struct platform_device *pdev)
993{
994 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
995 struct snd_soc_codec *codec = socdev->card->codec;
996
997 dac33_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
998 dac33_set_bias_level(codec, codec->suspend_bias_level);
999
1000 return 0;
1001}
1002
1003struct snd_soc_codec_device soc_codec_dev_tlv320dac33 = {
1004 .probe = dac33_soc_probe,
1005 .remove = dac33_soc_remove,
1006 .suspend = dac33_soc_suspend,
1007 .resume = dac33_soc_resume,
1008};
1009EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320dac33);
1010
1011#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
1012 SNDRV_PCM_RATE_48000)
1013#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE
1014
1015static struct snd_soc_dai_ops dac33_dai_ops = {
1016 .shutdown = dac33_shutdown,
1017 .hw_params = dac33_hw_params,
1018 .prepare = dac33_pcm_prepare,
1019 .trigger = dac33_pcm_trigger,
1020 .set_sysclk = dac33_set_dai_sysclk,
1021 .set_fmt = dac33_set_dai_fmt,
1022};
1023
1024struct snd_soc_dai dac33_dai = {
1025 .name = "tlv320dac33",
1026 .playback = {
1027 .stream_name = "Playback",
1028 .channels_min = 2,
1029 .channels_max = 2,
1030 .rates = DAC33_RATES,
1031 .formats = DAC33_FORMATS,},
1032 .ops = &dac33_dai_ops,
1033};
1034EXPORT_SYMBOL_GPL(dac33_dai);
1035
1036static int dac33_i2c_probe(struct i2c_client *client,
1037 const struct i2c_device_id *id)
1038{
1039 struct tlv320dac33_platform_data *pdata;
1040 struct tlv320dac33_priv *dac33;
1041 struct snd_soc_codec *codec;
1042 int ret = 0;
1043
1044 if (client->dev.platform_data == NULL) {
1045 dev_err(&client->dev, "Platform data not set\n");
1046 return -ENODEV;
1047 }
1048 pdata = client->dev.platform_data;
1049
1050 dac33 = kzalloc(sizeof(struct tlv320dac33_priv), GFP_KERNEL);
1051 if (dac33 == NULL)
1052 return -ENOMEM;
1053
1054 codec = &dac33->codec;
1055 codec->private_data = dac33;
1056 codec->control_data = client;
1057
1058 mutex_init(&codec->mutex);
1059 mutex_init(&dac33->mutex);
1060 INIT_LIST_HEAD(&codec->dapm_widgets);
1061 INIT_LIST_HEAD(&codec->dapm_paths);
1062
1063 codec->name = "tlv320dac33";
1064 codec->owner = THIS_MODULE;
1065 codec->read = dac33_read_reg_cache;
1066 codec->write = dac33_write_locked;
1067 codec->hw_write = (hw_write_t) i2c_master_send;
1068 codec->bias_level = SND_SOC_BIAS_OFF;
1069 codec->set_bias_level = dac33_set_bias_level;
1070 codec->dai = &dac33_dai;
1071 codec->num_dai = 1;
1072 codec->reg_cache_size = ARRAY_SIZE(dac33_reg);
1073 codec->reg_cache = kmemdup(dac33_reg, ARRAY_SIZE(dac33_reg),
1074 GFP_KERNEL);
1075 if (codec->reg_cache == NULL) {
1076 ret = -ENOMEM;
1077 goto error_reg;
1078 }
1079
1080 i2c_set_clientdata(client, dac33);
1081
1082 dac33->power_gpio = pdata->power_gpio;
1083 dac33->irq = client->irq;
1084 dac33->nsample = NSAMPLE_MAX;
1085 /* Disable FIFO use by default */
1086 dac33->nsample_switch = 0;
1087
1088 tlv320dac33_codec = codec;
1089
1090 codec->dev = &client->dev;
1091 dac33_dai.dev = codec->dev;
1092
1093 /* Check if the reset GPIO number is valid and request it */
1094 if (dac33->power_gpio >= 0) {
1095 ret = gpio_request(dac33->power_gpio, "tlv320dac33 reset");
1096 if (ret < 0) {
1097 dev_err(codec->dev,
1098 "Failed to request reset GPIO (%d)\n",
1099 dac33->power_gpio);
1100 snd_soc_unregister_dai(&dac33_dai);
1101 snd_soc_unregister_codec(codec);
1102 goto error_gpio;
1103 }
1104 gpio_direction_output(dac33->power_gpio, 0);
1105 } else {
1106 dac33->chip_power = 1;
1107 }
1108
1109 /* Check if the IRQ number is valid and request it */
1110 if (dac33->irq >= 0) {
1111 ret = request_irq(dac33->irq, dac33_interrupt_handler,
1112 IRQF_TRIGGER_RISING | IRQF_DISABLED,
1113 codec->name, codec);
1114 if (ret < 0) {
1115 dev_err(codec->dev, "Could not request IRQ%d (%d)\n",
1116 dac33->irq, ret);
1117 dac33->irq = -1;
1118 }
1119 if (dac33->irq != -1) {
1120 /* Setup work queue */
1121 dac33->dac33_wq =
1122 create_singlethread_workqueue("tlv320dac33");
1123 if (dac33->dac33_wq == NULL) {
1124 free_irq(dac33->irq, &dac33->codec);
1125 ret = -ENOMEM;
1126 goto error_wq;
1127 }
1128
1129 INIT_WORK(&dac33->work, dac33_work);
1130 }
1131 }
1132
1133 ret = snd_soc_register_codec(codec);
1134 if (ret != 0) {
1135 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
1136 goto error_codec;
1137 }
1138
1139 ret = snd_soc_register_dai(&dac33_dai);
1140 if (ret != 0) {
1141 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
1142 snd_soc_unregister_codec(codec);
1143 goto error_codec;
1144 }
1145
1146 /* Shut down the codec for now */
1147 dac33_hard_power(codec, 0);
1148
1149 return ret;
1150
1151error_codec:
1152 if (dac33->irq >= 0) {
1153 free_irq(dac33->irq, &dac33->codec);
1154 destroy_workqueue(dac33->dac33_wq);
1155 }
1156error_wq:
1157 if (dac33->power_gpio >= 0)
1158 gpio_free(dac33->power_gpio);
1159error_gpio:
1160 kfree(codec->reg_cache);
1161error_reg:
1162 tlv320dac33_codec = NULL;
1163 kfree(dac33);
1164
1165 return ret;
1166}
1167
1168static int dac33_i2c_remove(struct i2c_client *client)
1169{
1170 struct tlv320dac33_priv *dac33;
1171
1172 dac33 = i2c_get_clientdata(client);
1173 dac33_hard_power(&dac33->codec, 0);
1174
1175 if (dac33->power_gpio >= 0)
1176 gpio_free(dac33->power_gpio);
1177 if (dac33->irq >= 0)
1178 free_irq(dac33->irq, &dac33->codec);
1179
1180 destroy_workqueue(dac33->dac33_wq);
1181 snd_soc_unregister_dai(&dac33_dai);
1182 snd_soc_unregister_codec(&dac33->codec);
1183 kfree(dac33->codec.reg_cache);
1184 kfree(dac33);
1185 tlv320dac33_codec = NULL;
1186
1187 return 0;
1188}
1189
1190static const struct i2c_device_id tlv320dac33_i2c_id[] = {
1191 {
1192 .name = "tlv320dac33",
1193 .driver_data = 0,
1194 },
1195 { },
1196};
1197
1198static struct i2c_driver tlv320dac33_i2c_driver = {
1199 .driver = {
1200 .name = "tlv320dac33",
1201 .owner = THIS_MODULE,
1202 },
1203 .probe = dac33_i2c_probe,
1204 .remove = __devexit_p(dac33_i2c_remove),
1205 .id_table = tlv320dac33_i2c_id,
1206};
1207
1208static int __init dac33_module_init(void)
1209{
1210 int r;
1211 r = i2c_add_driver(&tlv320dac33_i2c_driver);
1212 if (r < 0) {
1213 printk(KERN_ERR "DAC33: driver registration failed\n");
1214 return r;
1215 }
1216 return 0;
1217}
1218module_init(dac33_module_init);
1219
1220static void __exit dac33_module_exit(void)
1221{
1222 i2c_del_driver(&tlv320dac33_i2c_driver);
1223}
1224module_exit(dac33_module_exit);
1225
1226
1227MODULE_DESCRIPTION("ASoC TLV320DAC33 codec driver");
1228MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@nokia.com>");
1229MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320dac33.h b/sound/soc/codecs/tlv320dac33.h
new file mode 100644
index 000000000000..eb8ae07f0bd2
--- /dev/null
+++ b/sound/soc/codecs/tlv320dac33.h
@@ -0,0 +1,267 @@
1/*
2 * ALSA SoC Texas Instruments TLV320DAC33 codec driver
3 *
4 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
5 *
6 * Copyright: (C) 2009 Nokia Corporation
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __TLV320DAC33_H
25#define __TLV320DAC33_H
26
27#define DAC33_PAGE_SELECT 0x00
28#define DAC33_PWR_CTRL 0x01
29#define DAC33_PLL_CTRL_A 0x02
30#define DAC33_PLL_CTRL_B 0x03
31#define DAC33_PLL_CTRL_C 0x04
32#define DAC33_PLL_CTRL_D 0x05
33#define DAC33_PLL_CTRL_E 0x06
34#define DAC33_INT_OSC_CTRL 0x07
35#define DAC33_INT_OSC_FREQ_RAT_A 0x08
36#define DAC33_INT_OSC_FREQ_RAT_B 0x09
37#define DAC33_INT_OSC_DAC_RATIO_SET 0x0A
38#define DAC33_CALIB_TIME 0x0B
39#define DAC33_INT_OSC_CTRL_B 0x0C
40#define DAC33_INT_OSC_CTRL_C 0x0D
41#define DAC33_INT_OSC_STATUS 0x0E
42#define DAC33_INT_OSC_DAC_RATIO_READ 0x0F
43#define DAC33_INT_OSC_FREQ_RAT_READ_A 0x10
44#define DAC33_INT_OSC_FREQ_RAT_READ_B 0x11
45#define DAC33_SER_AUDIOIF_CTRL_A 0x12
46#define DAC33_SER_AUDIOIF_CTRL_B 0x13
47#define DAC33_SER_AUDIOIF_CTRL_C 0x14
48#define DAC33_FIFO_CTRL_A 0x15
49#define DAC33_UTHR_MSB 0x16
50#define DAC33_UTHR_LSB 0x17
51#define DAC33_ATHR_MSB 0x18
52#define DAC33_ATHR_LSB 0x19
53#define DAC33_LTHR_MSB 0x1A
54#define DAC33_LTHR_LSB 0x1B
55#define DAC33_PREFILL_MSB 0x1C
56#define DAC33_PREFILL_LSB 0x1D
57#define DAC33_NSAMPLE_MSB 0x1E
58#define DAC33_NSAMPLE_LSB 0x1F
59#define DAC33_FIFO_WPTR_MSB 0x20
60#define DAC33_FIFO_WPTR_LSB 0x21
61#define DAC33_FIFO_RPTR_MSB 0x22
62#define DAC33_FIFO_RPTR_LSB 0x23
63#define DAC33_FIFO_DEPTH_MSB 0x24
64#define DAC33_FIFO_DEPTH_LSB 0x25
65#define DAC33_SAMPLES_REMAINING_MSB 0x26
66#define DAC33_SAMPLES_REMAINING_LSB 0x27
67#define DAC33_FIFO_IRQ_FLAG 0x28
68#define DAC33_FIFO_IRQ_MASK 0x29
69#define DAC33_FIFO_IRQ_MODE_A 0x2A
70#define DAC33_FIFO_IRQ_MODE_B 0x2B
71#define DAC33_DAC_CTRL_A 0x2C
72#define DAC33_DAC_CTRL_B 0x2D
73#define DAC33_DAC_CTRL_C 0x2E
74#define DAC33_LDAC_DIG_VOL_CTRL 0x2F
75#define DAC33_RDAC_DIG_VOL_CTRL 0x30
76#define DAC33_DAC_STATUS_FLAGS 0x31
77#define DAC33_ASRC_CTRL_A 0x32
78#define DAC33_ASRC_CTRL_B 0x33
79#define DAC33_SRC_REF_CLK_RATIO_A 0x34
80#define DAC33_SRC_REF_CLK_RATIO_B 0x35
81#define DAC33_SRC_EST_REF_CLK_RATIO_A 0x36
82#define DAC33_SRC_EST_REF_CLK_RATIO_B 0x37
83#define DAC33_INTP_CTRL_A 0x38
84#define DAC33_INTP_CTRL_B 0x39
85/* Registers 0x3A - 0x3F Reserved */
86#define DAC33_LDAC_PWR_CTRL 0x40
87#define DAC33_RDAC_PWR_CTRL 0x41
88#define DAC33_OUT_AMP_CM_CTRL 0x42
89#define DAC33_OUT_AMP_PWR_CTRL 0x43
90#define DAC33_OUT_AMP_CTRL 0x44
91#define DAC33_LINEL_TO_LLO_VOL 0x45
92/* Registers 0x45 - 0x47 Reserved */
93#define DAC33_LINER_TO_RLO_VOL 0x48
94#define DAC33_ANA_VOL_SOFT_STEP_CTRL 0x49
95#define DAC33_OSC_TRIM 0x4A
96/* Registers 0x4B - 0x7C Reserved */
97#define DAC33_DEVICE_ID_MSB 0x7D
98#define DAC33_DEVICE_ID_LSB 0x7E
99#define DAC33_DEVICE_REV_ID 0x7F
100
101#define DAC33_CACHEREGNUM 128
102
103/* Bit definitions */
104
105/* DAC33_PWR_CTRL (0x01) */
106#define DAC33_DACRPDNB (0x01 << 0)
107#define DAC33_DACLPDNB (0x01 << 1)
108#define DAC33_OSCPDNB (0x01 << 2)
109#define DAC33_PLLPDNB (0x01 << 3)
110#define DAC33_PDNALLB (0x01 << 4)
111#define DAC33_SOFT_RESET (0x01 << 7)
112
113/* DAC33_INT_OSC_CTRL (0x07) */
114#define DAC33_REFSEL (0x01 << 1)
115
116/* DAC33_INT_OSC_CTRL_B (0x0C) */
117#define DAC33_ADJSTEP(x) (x << 0)
118#define DAC33_ADJTHRSHLD(x) (x << 4)
119
120/* DAC33_INT_OSC_CTRL_C (0x0D) */
121#define DAC33_REFDIV(x) (x << 4)
122
123/* DAC33_INT_OSC_STATUS (0x0E) */
124#define DAC33_OSCSTATUS_IDLE_CALIB (0x00)
125#define DAC33_OSCSTATUS_NORMAL (0x01)
126#define DAC33_OSCSTATUS_ADJUSTMENT (0x03)
127#define DAC33_OSCSTATUS_NOT_USED (0x02)
128
129/* DAC33_SER_AUDIOIF_CTRL_A (0x12) */
130#define DAC33_MSWCLK (0x01 << 0)
131#define DAC33_MSBCLK (0x01 << 1)
132#define DAC33_AFMT_MASK (0x03 << 2)
133#define DAC33_AFMT_I2S (0x00 << 2)
134#define DAC33_AFMT_DSP (0x01 << 2)
135#define DAC33_AFMT_RIGHT_J (0x02 << 2)
136#define DAC33_AFMT_LEFT_J (0x03 << 2)
137#define DAC33_WLEN_MASK (0x03 << 4)
138#define DAC33_WLEN_16 (0x00 << 4)
139#define DAC33_WLEN_20 (0x01 << 4)
140#define DAC33_WLEN_24 (0x02 << 4)
141#define DAC33_WLEN_32 (0x03 << 4)
142#define DAC33_NCYCL_MASK (0x03 << 6)
143#define DAC33_NCYCL_16 (0x00 << 6)
144#define DAC33_NCYCL_20 (0x01 << 6)
145#define DAC33_NCYCL_24 (0x02 << 6)
146#define DAC33_NCYCL_32 (0x03 << 6)
147
148/* DAC33_SER_AUDIOIF_CTRL_B (0x13) */
149#define DAC33_DATA_DELAY_MASK (0x03 << 2)
150#define DAC33_DATA_DELAY(x) (x << 2)
151#define DAC33_BCLKON (0x01 << 5)
152
153/* DAC33_FIFO_CTRL_A (0x15) */
154#define DAC33_WIDTH (0x01 << 0)
155#define DAC33_FBYPAS (0x01 << 1)
156#define DAC33_FAUTO (0x01 << 2)
157#define DAC33_FIFOFLUSH (0x01 << 3)
158
159/*
160 * UTHR, ATHR, LTHR, PREFILL, NSAMPLE (0x16 - 0x1F)
161 * 13-bit values
162*/
163#define DAC33_THRREG(x) (((x) & 0x1FFF) << 3)
164
165/* DAC33_FIFO_IRQ_MASK (0x29) */
166#define DAC33_MNS (0x01 << 0)
167#define DAC33_MPS (0x01 << 1)
168#define DAC33_MAT (0x01 << 2)
169#define DAC33_MLT (0x01 << 3)
170#define DAC33_MUT (0x01 << 4)
171#define DAC33_MUF (0x01 << 5)
172#define DAC33_MOF (0x01 << 6)
173
174#define DAC33_FIFO_IRQ_MODE_MASK (0x03)
175#define DAC33_FIFO_IRQ_MODE_RISING (0x00)
176#define DAC33_FIFO_IRQ_MODE_FALLING (0x01)
177#define DAC33_FIFO_IRQ_MODE_LEVEL (0x02)
178#define DAC33_FIFO_IRQ_MODE_EDGE (0x03)
179
180/* DAC33_FIFO_IRQ_MODE_A (0x2A) */
181#define DAC33_UTM(x) (x << 0)
182#define DAC33_UFM(x) (x << 2)
183#define DAC33_OFM(x) (x << 4)
184
185/* DAC33_FIFO_IRQ_MODE_B (0x2B) */
186#define DAC33_NSM(x) (x << 0)
187#define DAC33_PSM(x) (x << 2)
188#define DAC33_ATM(x) (x << 4)
189#define DAC33_LTM(x) (x << 6)
190
191/* DAC33_DAC_CTRL_A (0x2C) */
192#define DAC33_DACRATE(x) (x << 0)
193#define DAC33_DACDUAL (0x01 << 4)
194#define DAC33_DACLKSEL_MASK (0x03 << 5)
195#define DAC33_DACLKSEL_INTSOC (0x00 << 5)
196#define DAC33_DACLKSEL_PLL (0x01 << 5)
197#define DAC33_DACLKSEL_MCLK (0x02 << 5)
198#define DAC33_DACLKSEL_BCLK (0x03 << 5)
199
200/* DAC33_DAC_CTRL_B (0x2D) */
201#define DAC33_DACSRCR_MASK (0x03 << 0)
202#define DAC33_DACSRCR_MUTE (0x00 << 0)
203#define DAC33_DACSRCR_RIGHT (0x01 << 0)
204#define DAC33_DACSRCR_LEFT (0x02 << 0)
205#define DAC33_DACSRCR_MONOMIX (0x03 << 0)
206#define DAC33_DACSRCL_MASK (0x03 << 2)
207#define DAC33_DACSRCL_MUTE (0x00 << 2)
208#define DAC33_DACSRCL_LEFT (0x01 << 2)
209#define DAC33_DACSRCL_RIGHT (0x02 << 2)
210#define DAC33_DACSRCL_MONOMIX (0x03 << 2)
211#define DAC33_DVOLSTEP_MASK (0x03 << 4)
212#define DAC33_DVOLSTEP_SS_PERFS (0x00 << 4)
213#define DAC33_DVOLSTEP_SS_PER2FS (0x01 << 4)
214#define DAC33_DVOLSTEP_SS_DISABLED (0x02 << 4)
215#define DAC33_DVOLCTRL_MASK (0x03 << 6)
216#define DAC33_DVOLCTRL_LR_INDEPENDENT1 (0x00 << 6)
217#define DAC33_DVOLCTRL_LR_RIGHT_CONTROL (0x01 << 6)
218#define DAC33_DVOLCTRL_LR_LEFT_CONTROL (0x02 << 6)
219#define DAC33_DVOLCTRL_LR_INDEPENDENT2 (0x03 << 6)
220
221/* DAC33_DAC_CTRL_C (0x2E) */
222#define DAC33_DEEMENR (0x01 << 0)
223#define DAC33_EFFENR (0x01 << 1)
224#define DAC33_DEEMENL (0x01 << 2)
225#define DAC33_EFFENL (0x01 << 3)
226#define DAC33_EN3D (0x01 << 4)
227#define DAC33_RESYNMUTE (0x01 << 5)
228#define DAC33_RESYNEN (0x01 << 6)
229
230/* DAC33_ASRC_CTRL_A (0x32) */
231#define DAC33_SRCBYP (0x01 << 0)
232#define DAC33_SRCLKSEL_MASK (0x03 << 1)
233#define DAC33_SRCLKSEL_INTSOC (0x00 << 1)
234#define DAC33_SRCLKSEL_PLL (0x01 << 1)
235#define DAC33_SRCLKSEL_MCLK (0x02 << 1)
236#define DAC33_SRCLKSEL_BCLK (0x03 << 1)
237#define DAC33_SRCLKDIV(x) (x << 3)
238
239/* DAC33_ASRC_CTRL_B (0x33) */
240#define DAC33_SRCSETUP(x) (x << 0)
241#define DAC33_SRCREFSEL (0x01 << 4)
242#define DAC33_SRCREFDIV(x) (x << 5)
243
244/* DAC33_INTP_CTRL_A (0x38) */
245#define DAC33_INTPSEL (0x01 << 0)
246#define DAC33_INTPM_MASK (0x03 << 1)
247#define DAC33_INTPM_ALOW_OPENDRAIN (0x00 << 1)
248#define DAC33_INTPM_ALOW (0x01 << 1)
249#define DAC33_INTPM_AHIGH (0x02 << 1)
250
251/* DAC33_LDAC_PWR_CTRL (0x40) */
252/* DAC33_RDAC_PWR_CTRL (0x41) */
253#define DAC33_DACLRNUM (0x01 << 2)
254#define DAC33_LROUT_GAIN(x) (x << 0)
255
256/* DAC33_ANA_VOL_SOFT_STEP_CTRL (0x49) */
257#define DAC33_VOLCLKSEL (0x01 << 0)
258#define DAC33_VOLCLKEN (0x01 << 1)
259#define DAC33_VOLBYPASS (0x01 << 2)
260
261#define TLV320DAC33_MCLK 0
262#define TLV320DAC33_SLEEPCLK 1
263
264extern struct snd_soc_dai dac33_dai;
265extern struct snd_soc_codec_device soc_codec_dev_tlv320dac33;
266
267#endif /* __TLV320DAC33_H */
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
new file mode 100644
index 000000000000..6b650c1aa3d1
--- /dev/null
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -0,0 +1,463 @@
1/*
2 * ALSA SoC Texas Instruments TPA6130A2 headset stereo amplifier driver
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 */
22
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/device.h>
26#include <linux/i2c.h>
27#include <linux/gpio.h>
28#include <sound/tpa6130a2-plat.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/tlv.h>
32
33#include "tpa6130a2.h"
34
35static struct i2c_client *tpa6130a2_client;
36
37/* This struct is used to save the context */
38struct tpa6130a2_data {
39 struct mutex mutex;
40 unsigned char regs[TPA6130A2_CACHEREGNUM];
41 int power_gpio;
42 unsigned char power_state;
43};
44
45static int tpa6130a2_i2c_read(int reg)
46{
47 struct tpa6130a2_data *data;
48 int val;
49
50 BUG_ON(tpa6130a2_client == NULL);
51 data = i2c_get_clientdata(tpa6130a2_client);
52
53 /* If powered off, return the cached value */
54 if (data->power_state) {
55 val = i2c_smbus_read_byte_data(tpa6130a2_client, reg);
56 if (val < 0)
57 dev_err(&tpa6130a2_client->dev, "Read failed\n");
58 else
59 data->regs[reg] = val;
60 } else {
61 val = data->regs[reg];
62 }
63
64 return val;
65}
66
67static int tpa6130a2_i2c_write(int reg, u8 value)
68{
69 struct tpa6130a2_data *data;
70 int val = 0;
71
72 BUG_ON(tpa6130a2_client == NULL);
73 data = i2c_get_clientdata(tpa6130a2_client);
74
75 if (data->power_state) {
76 val = i2c_smbus_write_byte_data(tpa6130a2_client, reg, value);
77 if (val < 0)
78 dev_err(&tpa6130a2_client->dev, "Write failed\n");
79 }
80
81 /* Either powered on or off, we save the context */
82 data->regs[reg] = value;
83
84 return val;
85}
86
87static u8 tpa6130a2_read(int reg)
88{
89 struct tpa6130a2_data *data;
90
91 BUG_ON(tpa6130a2_client == NULL);
92 data = i2c_get_clientdata(tpa6130a2_client);
93
94 return data->regs[reg];
95}
96
97static void tpa6130a2_initialize(void)
98{
99 struct tpa6130a2_data *data;
100 int i;
101
102 BUG_ON(tpa6130a2_client == NULL);
103 data = i2c_get_clientdata(tpa6130a2_client);
104
105 for (i = 1; i < TPA6130A2_REG_VERSION; i++)
106 tpa6130a2_i2c_write(i, data->regs[i]);
107}
108
109static void tpa6130a2_power(int power)
110{
111 struct tpa6130a2_data *data;
112 u8 val;
113
114 BUG_ON(tpa6130a2_client == NULL);
115 data = i2c_get_clientdata(tpa6130a2_client);
116
117 mutex_lock(&data->mutex);
118 if (power) {
119 /* Power on */
120 if (data->power_gpio >= 0) {
121 gpio_set_value(data->power_gpio, 1);
122 data->power_state = 1;
123 tpa6130a2_initialize();
124 }
125 /* Clear SWS */
126 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
127 val &= ~TPA6130A2_SWS;
128 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
129 } else {
130 /* set SWS */
131 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
132 val |= TPA6130A2_SWS;
133 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
134 /* Power off */
135 if (data->power_gpio >= 0) {
136 gpio_set_value(data->power_gpio, 0);
137 data->power_state = 0;
138 }
139 }
140 mutex_unlock(&data->mutex);
141}
142
143static int tpa6130a2_get_reg(struct snd_kcontrol *kcontrol,
144 struct snd_ctl_elem_value *ucontrol)
145{
146 struct soc_mixer_control *mc =
147 (struct soc_mixer_control *)kcontrol->private_value;
148 struct tpa6130a2_data *data;
149 unsigned int reg = mc->reg;
150 unsigned int shift = mc->shift;
151 unsigned int mask = mc->max;
152 unsigned int invert = mc->invert;
153
154 BUG_ON(tpa6130a2_client == NULL);
155 data = i2c_get_clientdata(tpa6130a2_client);
156
157 mutex_lock(&data->mutex);
158
159 ucontrol->value.integer.value[0] =
160 (tpa6130a2_read(reg) >> shift) & mask;
161
162 if (invert)
163 ucontrol->value.integer.value[0] =
164 mask - ucontrol->value.integer.value[0];
165
166 mutex_unlock(&data->mutex);
167 return 0;
168}
169
170static int tpa6130a2_set_reg(struct snd_kcontrol *kcontrol,
171 struct snd_ctl_elem_value *ucontrol)
172{
173 struct soc_mixer_control *mc =
174 (struct soc_mixer_control *)kcontrol->private_value;
175 struct tpa6130a2_data *data;
176 unsigned int reg = mc->reg;
177 unsigned int shift = mc->shift;
178 unsigned int mask = mc->max;
179 unsigned int invert = mc->invert;
180 unsigned int val = (ucontrol->value.integer.value[0] & mask);
181 unsigned int val_reg;
182
183 BUG_ON(tpa6130a2_client == NULL);
184 data = i2c_get_clientdata(tpa6130a2_client);
185
186 if (invert)
187 val = mask - val;
188
189 mutex_lock(&data->mutex);
190
191 val_reg = tpa6130a2_read(reg);
192 if (((val_reg >> shift) & mask) == val) {
193 mutex_unlock(&data->mutex);
194 return 0;
195 }
196
197 val_reg &= ~(mask << shift);
198 val_reg |= val << shift;
199 tpa6130a2_i2c_write(reg, val_reg);
200
201 mutex_unlock(&data->mutex);
202
203 return 1;
204}
205
206/*
207 * TPA6130 volume. From -59.5 to 4 dB with increasing step size when going
208 * down in gain.
209 */
210static const unsigned int tpa6130_tlv[] = {
211 TLV_DB_RANGE_HEAD(10),
212 0, 1, TLV_DB_SCALE_ITEM(-5950, 600, 0),
213 2, 3, TLV_DB_SCALE_ITEM(-5000, 250, 0),
214 4, 5, TLV_DB_SCALE_ITEM(-4550, 160, 0),
215 6, 7, TLV_DB_SCALE_ITEM(-4140, 190, 0),
216 8, 9, TLV_DB_SCALE_ITEM(-3650, 120, 0),
217 10, 11, TLV_DB_SCALE_ITEM(-3330, 160, 0),
218 12, 13, TLV_DB_SCALE_ITEM(-3040, 180, 0),
219 14, 20, TLV_DB_SCALE_ITEM(-2710, 110, 0),
220 21, 37, TLV_DB_SCALE_ITEM(-1960, 74, 0),
221 38, 63, TLV_DB_SCALE_ITEM(-720, 45, 0),
222};
223
224static const struct snd_kcontrol_new tpa6130a2_controls[] = {
225 SOC_SINGLE_EXT_TLV("TPA6130A2 Headphone Playback Volume",
226 TPA6130A2_REG_VOL_MUTE, 0, 0x3f, 0,
227 tpa6130a2_get_reg, tpa6130a2_set_reg,
228 tpa6130_tlv),
229};
230
231/*
232 * Enable or disable channel (left or right)
233 * The bit number for mute and amplifier are the same per channel:
234 * bit 6: Right channel
235 * bit 7: Left channel
236 * in both registers.
237 */
238static void tpa6130a2_channel_enable(u8 channel, int enable)
239{
240 struct tpa6130a2_data *data;
241 u8 val;
242
243 BUG_ON(tpa6130a2_client == NULL);
244 data = i2c_get_clientdata(tpa6130a2_client);
245
246 if (enable) {
247 /* Enable channel */
248 /* Enable amplifier */
249 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
250 val |= channel;
251 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
252
253 /* Unmute channel */
254 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
255 val &= ~channel;
256 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
257 } else {
258 /* Disable channel */
259 /* Mute channel */
260 val = tpa6130a2_read(TPA6130A2_REG_VOL_MUTE);
261 val |= channel;
262 tpa6130a2_i2c_write(TPA6130A2_REG_VOL_MUTE, val);
263
264 /* Disable amplifier */
265 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
266 val &= ~channel;
267 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
268 }
269}
270
271static int tpa6130a2_left_event(struct snd_soc_dapm_widget *w,
272 struct snd_kcontrol *kcontrol, int event)
273{
274 switch (event) {
275 case SND_SOC_DAPM_POST_PMU:
276 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 1);
277 break;
278 case SND_SOC_DAPM_POST_PMD:
279 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 0);
280 break;
281 }
282 return 0;
283}
284
285static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
286 struct snd_kcontrol *kcontrol, int event)
287{
288 switch (event) {
289 case SND_SOC_DAPM_POST_PMU:
290 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 1);
291 break;
292 case SND_SOC_DAPM_POST_PMD:
293 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 0);
294 break;
295 }
296 return 0;
297}
298
299static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
300 struct snd_kcontrol *kcontrol, int event)
301{
302 switch (event) {
303 case SND_SOC_DAPM_POST_PMU:
304 tpa6130a2_power(1);
305 break;
306 case SND_SOC_DAPM_POST_PMD:
307 tpa6130a2_power(0);
308 break;
309 }
310 return 0;
311}
312
313static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
314 SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM,
315 0, 0, NULL, 0, tpa6130a2_left_event,
316 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
317 SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM,
318 0, 0, NULL, 0, tpa6130a2_right_event,
319 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
320 SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM,
321 0, 0, tpa6130a2_supply_event,
322 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
323 /* Outputs */
324 SND_SOC_DAPM_HP("TPA6130A2 Headphone Left", NULL),
325 SND_SOC_DAPM_HP("TPA6130A2 Headphone Right", NULL),
326};
327
328static const struct snd_soc_dapm_route audio_map[] = {
329 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"},
330 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"},
331
332 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"},
333 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"},
334};
335
336int tpa6130a2_add_controls(struct snd_soc_codec *codec)
337{
338 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
339 ARRAY_SIZE(tpa6130a2_dapm_widgets));
340
341 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
342
343 return snd_soc_add_controls(codec, tpa6130a2_controls,
344 ARRAY_SIZE(tpa6130a2_controls));
345
346}
347EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
348
349static int tpa6130a2_probe(struct i2c_client *client,
350 const struct i2c_device_id *id)
351{
352 struct device *dev;
353 struct tpa6130a2_data *data;
354 struct tpa6130a2_platform_data *pdata;
355 int ret;
356
357 dev = &client->dev;
358
359 if (client->dev.platform_data == NULL) {
360 dev_err(dev, "Platform data not set\n");
361 dump_stack();
362 return -ENODEV;
363 }
364
365 data = kzalloc(sizeof(*data), GFP_KERNEL);
366 if (data == NULL) {
367 dev_err(dev, "Can not allocate memory\n");
368 return -ENOMEM;
369 }
370
371 tpa6130a2_client = client;
372
373 i2c_set_clientdata(tpa6130a2_client, data);
374
375 pdata = client->dev.platform_data;
376 data->power_gpio = pdata->power_gpio;
377
378 mutex_init(&data->mutex);
379
380 /* Set default register values */
381 data->regs[TPA6130A2_REG_CONTROL] = TPA6130A2_SWS;
382 data->regs[TPA6130A2_REG_VOL_MUTE] = TPA6130A2_MUTE_R |
383 TPA6130A2_MUTE_L;
384
385 if (data->power_gpio >= 0) {
386 ret = gpio_request(data->power_gpio, "tpa6130a2 enable");
387 if (ret < 0) {
388 dev_err(dev, "Failed to request power GPIO (%d)\n",
389 data->power_gpio);
390 goto fail;
391 }
392 gpio_direction_output(data->power_gpio, 0);
393 } else {
394 data->power_state = 1;
395 tpa6130a2_initialize();
396 }
397
398 tpa6130a2_power(1);
399
400 /* Read version */
401 ret = tpa6130a2_i2c_read(TPA6130A2_REG_VERSION) &
402 TPA6130A2_VERSION_MASK;
403 if ((ret != 1) && (ret != 2))
404 dev_warn(dev, "UNTESTED version detected (%d)\n", ret);
405
406 /* Disable the chip */
407 tpa6130a2_power(0);
408
409 return 0;
410fail:
411 kfree(data);
412 i2c_set_clientdata(tpa6130a2_client, NULL);
413 tpa6130a2_client = NULL;
414
415 return ret;
416}
417
418static int tpa6130a2_remove(struct i2c_client *client)
419{
420 struct tpa6130a2_data *data = i2c_get_clientdata(client);
421
422 tpa6130a2_power(0);
423
424 if (data->power_gpio >= 0)
425 gpio_free(data->power_gpio);
426 kfree(data);
427 tpa6130a2_client = NULL;
428
429 return 0;
430}
431
432static const struct i2c_device_id tpa6130a2_id[] = {
433 { "tpa6130a2", 0 },
434 { }
435};
436MODULE_DEVICE_TABLE(i2c, tpa6130a2_id);
437
438static struct i2c_driver tpa6130a2_i2c_driver = {
439 .driver = {
440 .name = "tpa6130a2",
441 .owner = THIS_MODULE,
442 },
443 .probe = tpa6130a2_probe,
444 .remove = __devexit_p(tpa6130a2_remove),
445 .id_table = tpa6130a2_id,
446};
447
448static int __init tpa6130a2_init(void)
449{
450 return i2c_add_driver(&tpa6130a2_i2c_driver);
451}
452
453static void __exit tpa6130a2_exit(void)
454{
455 i2c_del_driver(&tpa6130a2_i2c_driver);
456}
457
458MODULE_AUTHOR("Peter Ujfalusi");
459MODULE_DESCRIPTION("TPA6130A2 Headphone amplifier driver");
460MODULE_LICENSE("GPL");
461
462module_init(tpa6130a2_init);
463module_exit(tpa6130a2_exit);
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
new file mode 100644
index 000000000000..57e867fd86d1
--- /dev/null
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -0,0 +1,61 @@
1/*
2 * ALSA SoC TPA6130A2 amplifier driver
3 *
4 * Copyright (C) Nokia Corporation
5 *
6 * Author: Peter Ujfalusi <peter.ujfalusi@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#ifndef __TPA6130A2_H__
25#define __TPA6130A2_H__
26
27/* Register addresses */
28#define TPA6130A2_REG_CONTROL 0x01
29#define TPA6130A2_REG_VOL_MUTE 0x02
30#define TPA6130A2_REG_OUT_IMPEDANCE 0x03
31#define TPA6130A2_REG_VERSION 0x04
32
33#define TPA6130A2_CACHEREGNUM (TPA6130A2_REG_VERSION + 1)
34
35/* Register bits */
36/* TPA6130A2_REG_CONTROL (0x01) */
37#define TPA6130A2_SWS (0x01 << 0)
38#define TPA6130A2_TERMAL (0x01 << 1)
39#define TPA6130A2_MODE(x) (x << 4)
40#define TPA6130A2_MODE_STEREO (0x00)
41#define TPA6130A2_MODE_DUAL_MONO (0x01)
42#define TPA6130A2_MODE_BRIDGE (0x02)
43#define TPA6130A2_MODE_MASK (0x03)
44#define TPA6130A2_HP_EN_R (0x01 << 6)
45#define TPA6130A2_HP_EN_L (0x01 << 7)
46
47/* TPA6130A2_REG_VOL_MUTE (0x02) */
48#define TPA6130A2_VOLUME(x) ((x & 0x3f) << 0)
49#define TPA6130A2_MUTE_R (0x01 << 6)
50#define TPA6130A2_MUTE_L (0x01 << 7)
51
52/* TPA6130A2_REG_OUT_IMPEDANCE (0x03) */
53#define TPA6130A2_HIZ_R (0x01 << 0)
54#define TPA6130A2_HIZ_L (0x01 << 1)
55
56/* TPA6130A2_REG_VERSION (0x04) */
57#define TPA6130A2_VERSION_MASK (0x0f)
58
59extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
60
61#endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 4df7c6c61c76..5f1681f6ca76 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -120,9 +120,10 @@ static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
120 120
121/* codec private data */ 121/* codec private data */
122struct twl4030_priv { 122struct twl4030_priv {
123 unsigned int bypass_state; 123 struct snd_soc_codec codec;
124
124 unsigned int codec_powered; 125 unsigned int codec_powered;
125 unsigned int codec_muted; 126 unsigned int apll_enabled;
126 127
127 struct snd_pcm_substream *master_substream; 128 struct snd_pcm_substream *master_substream;
128 struct snd_pcm_substream *slave_substream; 129 struct snd_pcm_substream *slave_substream;
@@ -183,19 +184,20 @@ static int twl4030_write(struct snd_soc_codec *codec,
183static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 184static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
184{ 185{
185 struct twl4030_priv *twl4030 = codec->private_data; 186 struct twl4030_priv *twl4030 = codec->private_data;
186 u8 mode; 187 int mode;
187 188
188 if (enable == twl4030->codec_powered) 189 if (enable == twl4030->codec_powered)
189 return; 190 return;
190 191
191 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
192 if (enable) 192 if (enable)
193 mode |= TWL4030_CODECPDZ; 193 mode = twl4030_codec_enable_resource(TWL4030_CODEC_RES_POWER);
194 else 194 else
195 mode &= ~TWL4030_CODECPDZ; 195 mode = twl4030_codec_disable_resource(TWL4030_CODEC_RES_POWER);
196 196
197 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); 197 if (mode >= 0) {
198 twl4030->codec_powered = enable; 198 twl4030_write_reg_cache(codec, TWL4030_REG_CODEC_MODE, mode);
199 twl4030->codec_powered = enable;
200 }
199 201
200 /* REVISIT: this delay is present in TI sample drivers */ 202 /* REVISIT: this delay is present in TI sample drivers */
201 /* but there seems to be no TRM requirement for it */ 203 /* but there seems to be no TRM requirement for it */
@@ -212,31 +214,30 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
212 214
213 /* set all audio section registers to reasonable defaults */ 215 /* set all audio section registers to reasonable defaults */
214 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++) 216 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
215 twl4030_write(codec, i, cache[i]); 217 if (i != TWL4030_REG_APLL_CTL)
218 twl4030_write(codec, i, cache[i]);
216 219
217} 220}
218 221
219static void twl4030_codec_mute(struct snd_soc_codec *codec, int mute) 222static void twl4030_apll_enable(struct snd_soc_codec *codec, int enable)
220{ 223{
221 struct twl4030_priv *twl4030 = codec->private_data; 224 struct twl4030_priv *twl4030 = codec->private_data;
222 u8 reg_val; 225 int status;
223 226
224 if (mute == twl4030->codec_muted) 227 if (enable == twl4030->apll_enabled)
225 return; 228 return;
226 229
227 if (mute) { 230 if (enable)
228 /* Disable PLL */
229 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL);
230 reg_val &= ~TWL4030_APLL_EN;
231 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val);
232 } else {
233 /* Enable PLL */ 231 /* Enable PLL */
234 reg_val = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL); 232 status = twl4030_codec_enable_resource(TWL4030_CODEC_RES_APLL);
235 reg_val |= TWL4030_APLL_EN; 233 else
236 twl4030_write(codec, TWL4030_REG_APLL_CTL, reg_val); 234 /* Disable PLL */
237 } 235 status = twl4030_codec_disable_resource(TWL4030_CODEC_RES_APLL);
236
237 if (status >= 0)
238 twl4030_write_reg_cache(codec, TWL4030_REG_APLL_CTL, status);
238 239
239 twl4030->codec_muted = mute; 240 twl4030->apll_enabled = enable;
240} 241}
241 242
242static void twl4030_power_up(struct snd_soc_codec *codec) 243static void twl4030_power_up(struct snd_soc_codec *codec)
@@ -613,6 +614,27 @@ static int handsfreerpga_event(struct snd_soc_dapm_widget *w,
613 return 0; 614 return 0;
614} 615}
615 616
617static int vibramux_event(struct snd_soc_dapm_widget *w,
618 struct snd_kcontrol *kcontrol, int event)
619{
620 twl4030_write(w->codec, TWL4030_REG_VIBRA_SET, 0xff);
621 return 0;
622}
623
624static int apll_event(struct snd_soc_dapm_widget *w,
625 struct snd_kcontrol *kcontrol, int event)
626{
627 switch (event) {
628 case SND_SOC_DAPM_PRE_PMU:
629 twl4030_apll_enable(w->codec, 1);
630 break;
631 case SND_SOC_DAPM_POST_PMD:
632 twl4030_apll_enable(w->codec, 0);
633 break;
634 }
635 return 0;
636}
637
616static void headset_ramp(struct snd_soc_codec *codec, int ramp) 638static void headset_ramp(struct snd_soc_codec *codec, int ramp)
617{ 639{
618 struct snd_soc_device *socdev = codec->socdev; 640 struct snd_soc_device *socdev = codec->socdev;
@@ -724,67 +746,6 @@ static int headsetrpga_event(struct snd_soc_dapm_widget *w,
724 return 0; 746 return 0;
725} 747}
726 748
727static int bypass_event(struct snd_soc_dapm_widget *w,
728 struct snd_kcontrol *kcontrol, int event)
729{
730 struct soc_mixer_control *m =
731 (struct soc_mixer_control *)w->kcontrols->private_value;
732 struct twl4030_priv *twl4030 = w->codec->private_data;
733 unsigned char reg, misc;
734
735 reg = twl4030_read_reg_cache(w->codec, m->reg);
736
737 /*
738 * bypass_state[0:3] - analog HiFi bypass
739 * bypass_state[4] - analog voice bypass
740 * bypass_state[5] - digital voice bypass
741 * bypass_state[6:7] - digital HiFi bypass
742 */
743 if (m->reg == TWL4030_REG_VSTPGA) {
744 /* Voice digital bypass */
745 if (reg)
746 twl4030->bypass_state |= (1 << 5);
747 else
748 twl4030->bypass_state &= ~(1 << 5);
749 } else if (m->reg <= TWL4030_REG_ARXR2_APGA_CTL) {
750 /* Analog bypass */
751 if (reg & (1 << m->shift))
752 twl4030->bypass_state |=
753 (1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
754 else
755 twl4030->bypass_state &=
756 ~(1 << (m->reg - TWL4030_REG_ARXL1_APGA_CTL));
757 } else if (m->reg == TWL4030_REG_VDL_APGA_CTL) {
758 /* Analog voice bypass */
759 if (reg & (1 << m->shift))
760 twl4030->bypass_state |= (1 << 4);
761 else
762 twl4030->bypass_state &= ~(1 << 4);
763 } else {
764 /* Digital bypass */
765 if (reg & (0x7 << m->shift))
766 twl4030->bypass_state |= (1 << (m->shift ? 7 : 6));
767 else
768 twl4030->bypass_state &= ~(1 << (m->shift ? 7 : 6));
769 }
770
771 /* Enable master analog loopback mode if any analog switch is enabled*/
772 misc = twl4030_read_reg_cache(w->codec, TWL4030_REG_MISC_SET_1);
773 if (twl4030->bypass_state & 0x1F)
774 misc |= TWL4030_FMLOOP_EN;
775 else
776 misc &= ~TWL4030_FMLOOP_EN;
777 twl4030_write(w->codec, TWL4030_REG_MISC_SET_1, misc);
778
779 if (w->codec->bias_level == SND_SOC_BIAS_STANDBY) {
780 if (twl4030->bypass_state)
781 twl4030_codec_mute(w->codec, 0);
782 else
783 twl4030_codec_mute(w->codec, 1);
784 }
785 return 0;
786}
787
788/* 749/*
789 * Some of the gain controls in TWL (mostly those which are associated with 750 * Some of the gain controls in TWL (mostly those which are associated with
790 * the outputs) are implemented in an interesting way: 751 * the outputs) are implemented in an interesting way:
@@ -1192,32 +1153,28 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1192 SND_SOC_NOPM, 0, 0), 1153 SND_SOC_NOPM, 0, 0),
1193 1154
1194 /* Analog bypasses */ 1155 /* Analog bypasses */
1195 SND_SOC_DAPM_SWITCH_E("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1156 SND_SOC_DAPM_SWITCH("Right1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1196 &twl4030_dapm_abypassr1_control, bypass_event, 1157 &twl4030_dapm_abypassr1_control),
1197 SND_SOC_DAPM_POST_REG), 1158 SND_SOC_DAPM_SWITCH("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0,
1198 SND_SOC_DAPM_SWITCH_E("Left1 Analog Loopback", SND_SOC_NOPM, 0, 0, 1159 &twl4030_dapm_abypassl1_control),
1199 &twl4030_dapm_abypassl1_control, 1160 SND_SOC_DAPM_SWITCH("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1200 bypass_event, SND_SOC_DAPM_POST_REG), 1161 &twl4030_dapm_abypassr2_control),
1201 SND_SOC_DAPM_SWITCH_E("Right2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1162 SND_SOC_DAPM_SWITCH("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0,
1202 &twl4030_dapm_abypassr2_control, 1163 &twl4030_dapm_abypassl2_control),
1203 bypass_event, SND_SOC_DAPM_POST_REG), 1164 SND_SOC_DAPM_SWITCH("Voice Analog Loopback", SND_SOC_NOPM, 0, 0,
1204 SND_SOC_DAPM_SWITCH_E("Left2 Analog Loopback", SND_SOC_NOPM, 0, 0, 1165 &twl4030_dapm_abypassv_control),
1205 &twl4030_dapm_abypassl2_control, 1166
1206 bypass_event, SND_SOC_DAPM_POST_REG), 1167 /* Master analog loopback switch */
1207 SND_SOC_DAPM_SWITCH_E("Voice Analog Loopback", SND_SOC_NOPM, 0, 0, 1168 SND_SOC_DAPM_SUPPLY("FM Loop Enable", TWL4030_REG_MISC_SET_1, 5, 0,
1208 &twl4030_dapm_abypassv_control, 1169 NULL, 0),
1209 bypass_event, SND_SOC_DAPM_POST_REG),
1210 1170
1211 /* Digital bypasses */ 1171 /* Digital bypasses */
1212 SND_SOC_DAPM_SWITCH_E("Left Digital Loopback", SND_SOC_NOPM, 0, 0, 1172 SND_SOC_DAPM_SWITCH("Left Digital Loopback", SND_SOC_NOPM, 0, 0,
1213 &twl4030_dapm_dbypassl_control, bypass_event, 1173 &twl4030_dapm_dbypassl_control),
1214 SND_SOC_DAPM_POST_REG), 1174 SND_SOC_DAPM_SWITCH("Right Digital Loopback", SND_SOC_NOPM, 0, 0,
1215 SND_SOC_DAPM_SWITCH_E("Right Digital Loopback", SND_SOC_NOPM, 0, 0, 1175 &twl4030_dapm_dbypassr_control),
1216 &twl4030_dapm_dbypassr_control, bypass_event, 1176 SND_SOC_DAPM_SWITCH("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1217 SND_SOC_DAPM_POST_REG), 1177 &twl4030_dapm_dbypassv_control),
1218 SND_SOC_DAPM_SWITCH_E("Voice Digital Loopback", SND_SOC_NOPM, 0, 0,
1219 &twl4030_dapm_dbypassv_control, bypass_event,
1220 SND_SOC_DAPM_POST_REG),
1221 1178
1222 /* Digital mixers, power control for the physical DACs */ 1179 /* Digital mixers, power control for the physical DACs */
1223 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer", 1180 SND_SOC_DAPM_MIXER("Digital R1 Playback Mixer",
@@ -1243,6 +1200,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1243 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer", 1200 SND_SOC_DAPM_MIXER("Analog Voice Playback Mixer",
1244 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0), 1201 TWL4030_REG_VDL_APGA_CTL, 0, 0, NULL, 0),
1245 1202
1203 SND_SOC_DAPM_SUPPLY("APLL Enable", SND_SOC_NOPM, 0, 0, apll_event,
1204 SND_SOC_DAPM_PRE_PMU|SND_SOC_DAPM_POST_PMD),
1205
1246 /* Output MIXER controls */ 1206 /* Output MIXER controls */
1247 /* Earpiece */ 1207 /* Earpiece */
1248 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0, 1208 SND_SOC_DAPM_MIXER("Earpiece Mixer", SND_SOC_NOPM, 0, 0,
@@ -1308,8 +1268,9 @@ static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
1308 0, 0, NULL, 0, handsfreerpga_event, 1268 0, 0, NULL, 0, handsfreerpga_event,
1309 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), 1269 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
1310 /* Vibra */ 1270 /* Vibra */
1311 SND_SOC_DAPM_MUX("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0, 1271 SND_SOC_DAPM_MUX_E("Vibra Mux", TWL4030_REG_VIBRA_CTL, 0, 0,
1312 &twl4030_dapm_vibra_control), 1272 &twl4030_dapm_vibra_control, vibramux_event,
1273 SND_SOC_DAPM_PRE_PMU),
1313 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0, 1274 SND_SOC_DAPM_MUX("Vibra Route", SND_SOC_NOPM, 0, 0,
1314 &twl4030_dapm_vibrapath_control), 1275 &twl4030_dapm_vibrapath_control),
1315 1276
@@ -1369,6 +1330,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1369 {"Digital R2 Playback Mixer", NULL, "DAC Right2"}, 1330 {"Digital R2 Playback Mixer", NULL, "DAC Right2"},
1370 {"Digital Voice Playback Mixer", NULL, "DAC Voice"}, 1331 {"Digital Voice Playback Mixer", NULL, "DAC Voice"},
1371 1332
1333 /* Supply for the digital part (APLL) */
1334 {"Digital R1 Playback Mixer", NULL, "APLL Enable"},
1335 {"Digital L1 Playback Mixer", NULL, "APLL Enable"},
1336 {"Digital R2 Playback Mixer", NULL, "APLL Enable"},
1337 {"Digital L2 Playback Mixer", NULL, "APLL Enable"},
1338 {"Digital Voice Playback Mixer", NULL, "APLL Enable"},
1339
1372 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"}, 1340 {"Analog L1 Playback Mixer", NULL, "Digital L1 Playback Mixer"},
1373 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"}, 1341 {"Analog R1 Playback Mixer", NULL, "Digital R1 Playback Mixer"},
1374 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"}, 1342 {"Analog L2 Playback Mixer", NULL, "Digital L2 Playback Mixer"},
@@ -1482,6 +1450,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1482 {"ADC Virtual Left2", NULL, "TX2 Capture Route"}, 1450 {"ADC Virtual Left2", NULL, "TX2 Capture Route"},
1483 {"ADC Virtual Right2", NULL, "TX2 Capture Route"}, 1451 {"ADC Virtual Right2", NULL, "TX2 Capture Route"},
1484 1452
1453 {"ADC Virtual Left1", NULL, "APLL Enable"},
1454 {"ADC Virtual Right1", NULL, "APLL Enable"},
1455 {"ADC Virtual Left2", NULL, "APLL Enable"},
1456 {"ADC Virtual Right2", NULL, "APLL Enable"},
1457
1485 /* Analog bypass routes */ 1458 /* Analog bypass routes */
1486 {"Right1 Analog Loopback", "Switch", "Analog Right"}, 1459 {"Right1 Analog Loopback", "Switch", "Analog Right"},
1487 {"Left1 Analog Loopback", "Switch", "Analog Left"}, 1460 {"Left1 Analog Loopback", "Switch", "Analog Left"},
@@ -1489,6 +1462,13 @@ static const struct snd_soc_dapm_route intercon[] = {
1489 {"Left2 Analog Loopback", "Switch", "Analog Left"}, 1462 {"Left2 Analog Loopback", "Switch", "Analog Left"},
1490 {"Voice Analog Loopback", "Switch", "Analog Left"}, 1463 {"Voice Analog Loopback", "Switch", "Analog Left"},
1491 1464
1465 /* Supply for the Analog loopbacks */
1466 {"Right1 Analog Loopback", NULL, "FM Loop Enable"},
1467 {"Left1 Analog Loopback", NULL, "FM Loop Enable"},
1468 {"Right2 Analog Loopback", NULL, "FM Loop Enable"},
1469 {"Left2 Analog Loopback", NULL, "FM Loop Enable"},
1470 {"Voice Analog Loopback", NULL, "FM Loop Enable"},
1471
1492 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"}, 1472 {"Analog R1 Playback Mixer", NULL, "Right1 Analog Loopback"},
1493 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"}, 1473 {"Analog L1 Playback Mixer", NULL, "Left1 Analog Loopback"},
1494 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"}, 1474 {"Analog R2 Playback Mixer", NULL, "Right2 Analog Loopback"},
@@ -1513,32 +1493,20 @@ static int twl4030_add_widgets(struct snd_soc_codec *codec)
1513 1493
1514 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 1494 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
1515 1495
1516 snd_soc_dapm_new_widgets(codec);
1517 return 0; 1496 return 0;
1518} 1497}
1519 1498
1520static int twl4030_set_bias_level(struct snd_soc_codec *codec, 1499static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1521 enum snd_soc_bias_level level) 1500 enum snd_soc_bias_level level)
1522{ 1501{
1523 struct twl4030_priv *twl4030 = codec->private_data;
1524
1525 switch (level) { 1502 switch (level) {
1526 case SND_SOC_BIAS_ON: 1503 case SND_SOC_BIAS_ON:
1527 twl4030_codec_mute(codec, 0);
1528 break; 1504 break;
1529 case SND_SOC_BIAS_PREPARE: 1505 case SND_SOC_BIAS_PREPARE:
1530 twl4030_power_up(codec);
1531 if (twl4030->bypass_state)
1532 twl4030_codec_mute(codec, 0);
1533 else
1534 twl4030_codec_mute(codec, 1);
1535 break; 1506 break;
1536 case SND_SOC_BIAS_STANDBY: 1507 case SND_SOC_BIAS_STANDBY:
1537 twl4030_power_up(codec); 1508 if (codec->bias_level == SND_SOC_BIAS_OFF)
1538 if (twl4030->bypass_state) 1509 twl4030_power_up(codec);
1539 twl4030_codec_mute(codec, 0);
1540 else
1541 twl4030_codec_mute(codec, 1);
1542 break; 1510 break;
1543 case SND_SOC_BIAS_OFF: 1511 case SND_SOC_BIAS_OFF:
1544 twl4030_power_down(codec); 1512 twl4030_power_down(codec);
@@ -1785,29 +1753,23 @@ static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1785{ 1753{
1786 struct snd_soc_codec *codec = codec_dai->codec; 1754 struct snd_soc_codec *codec = codec_dai->codec;
1787 struct twl4030_priv *twl4030 = codec->private_data; 1755 struct twl4030_priv *twl4030 = codec->private_data;
1788 u8 infreq;
1789 1756
1790 switch (freq) { 1757 switch (freq) {
1791 case 19200000: 1758 case 19200000:
1792 infreq = TWL4030_APLL_INFREQ_19200KHZ;
1793 twl4030->sysclk = 19200;
1794 break;
1795 case 26000000: 1759 case 26000000:
1796 infreq = TWL4030_APLL_INFREQ_26000KHZ;
1797 twl4030->sysclk = 26000;
1798 break;
1799 case 38400000: 1760 case 38400000:
1800 infreq = TWL4030_APLL_INFREQ_38400KHZ;
1801 twl4030->sysclk = 38400;
1802 break; 1761 break;
1803 default: 1762 default:
1804 printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n", 1763 dev_err(codec->dev, "Unsupported APLL mclk: %u\n", freq);
1805 freq);
1806 return -EINVAL; 1764 return -EINVAL;
1807 } 1765 }
1808 1766
1809 infreq |= TWL4030_APLL_EN; 1767 if ((freq / 1000) != twl4030->sysclk) {
1810 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq); 1768 dev_err(codec->dev,
1769 "Mismatch in APLL mclk: %u (configured: %u)\n",
1770 freq, twl4030->sysclk * 1000);
1771 return -EINVAL;
1772 }
1811 1773
1812 return 0; 1774 return 0;
1813} 1775}
@@ -1905,18 +1867,16 @@ static int twl4030_voice_startup(struct snd_pcm_substream *substream,
1905 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1867 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1906 struct snd_soc_device *socdev = rtd->socdev; 1868 struct snd_soc_device *socdev = rtd->socdev;
1907 struct snd_soc_codec *codec = socdev->card->codec; 1869 struct snd_soc_codec *codec = socdev->card->codec;
1908 u8 infreq; 1870 struct twl4030_priv *twl4030 = codec->private_data;
1909 u8 mode; 1871 u8 mode;
1910 1872
1911 /* If the system master clock is not 26MHz, the voice PCM interface is 1873 /* If the system master clock is not 26MHz, the voice PCM interface is
1912 * not avilable. 1874 * not avilable.
1913 */ 1875 */
1914 infreq = twl4030_read_reg_cache(codec, TWL4030_REG_APLL_CTL) 1876 if (twl4030->sysclk != 26000) {
1915 & TWL4030_APLL_INFREQ; 1877 dev_err(codec->dev, "The board is configured for %u Hz, while"
1916 1878 "the Voice interface needs 26MHz APLL mclk\n",
1917 if (infreq != TWL4030_APLL_INFREQ_26000KHZ) { 1879 twl4030->sysclk * 1000);
1918 printk(KERN_ERR "TWL4030 voice startup: "
1919 "MCLK is not 26MHz, call set_sysclk() on init\n");
1920 return -EINVAL; 1880 return -EINVAL;
1921 } 1881 }
1922 1882
@@ -1989,21 +1949,19 @@ static int twl4030_voice_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1989 int clk_id, unsigned int freq, int dir) 1949 int clk_id, unsigned int freq, int dir)
1990{ 1950{
1991 struct snd_soc_codec *codec = codec_dai->codec; 1951 struct snd_soc_codec *codec = codec_dai->codec;
1992 u8 infreq; 1952 struct twl4030_priv *twl4030 = codec->private_data;
1993 1953
1994 switch (freq) { 1954 if (freq != 26000000) {
1995 case 26000000: 1955 dev_err(codec->dev, "Unsupported APLL mclk: %u, the Voice"
1996 infreq = TWL4030_APLL_INFREQ_26000KHZ; 1956 "interface needs 26MHz APLL mclk\n", freq);
1997 break; 1957 return -EINVAL;
1998 default: 1958 }
1999 printk(KERN_ERR "TWL4030 voice set sysclk: unknown rate %d\n", 1959 if ((freq / 1000) != twl4030->sysclk) {
2000 freq); 1960 dev_err(codec->dev,
1961 "Mismatch in APLL mclk: %u (configured: %u)\n",
1962 freq, twl4030->sysclk * 1000);
2001 return -EINVAL; 1963 return -EINVAL;
2002 } 1964 }
2003
2004 infreq |= TWL4030_APLL_EN;
2005 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
2006
2007 return 0; 1965 return 0;
2008} 1966}
2009 1967
@@ -2121,7 +2079,7 @@ struct snd_soc_dai twl4030_dai[] = {
2121}; 2079};
2122EXPORT_SYMBOL_GPL(twl4030_dai); 2080EXPORT_SYMBOL_GPL(twl4030_dai);
2123 2081
2124static int twl4030_suspend(struct platform_device *pdev, pm_message_t state) 2082static int twl4030_soc_suspend(struct platform_device *pdev, pm_message_t state)
2125{ 2083{
2126 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2084 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2127 struct snd_soc_codec *codec = socdev->card->codec; 2085 struct snd_soc_codec *codec = socdev->card->codec;
@@ -2131,7 +2089,7 @@ static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
2131 return 0; 2089 return 0;
2132} 2090}
2133 2091
2134static int twl4030_resume(struct platform_device *pdev) 2092static int twl4030_soc_resume(struct platform_device *pdev)
2135{ 2093{
2136 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2094 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2137 struct snd_soc_codec *codec = socdev->card->codec; 2095 struct snd_soc_codec *codec = socdev->card->codec;
@@ -2141,147 +2099,181 @@ static int twl4030_resume(struct platform_device *pdev)
2141 return 0; 2099 return 0;
2142} 2100}
2143 2101
2144/* 2102static struct snd_soc_codec *twl4030_codec;
2145 * initialize the driver
2146 * register the mixer and dsp interfaces with the kernel
2147 */
2148 2103
2149static int twl4030_init(struct snd_soc_device *socdev) 2104static int twl4030_soc_probe(struct platform_device *pdev)
2150{ 2105{
2151 struct snd_soc_codec *codec = socdev->card->codec; 2106 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2152 struct twl4030_setup_data *setup = socdev->codec_data; 2107 struct twl4030_setup_data *setup = socdev->codec_data;
2153 struct twl4030_priv *twl4030 = codec->private_data; 2108 struct snd_soc_codec *codec;
2154 int ret = 0; 2109 struct twl4030_priv *twl4030;
2110 int ret;
2155 2111
2156 printk(KERN_INFO "TWL4030 Audio Codec init \n"); 2112 BUG_ON(!twl4030_codec);
2157 2113
2158 codec->name = "twl4030"; 2114 codec = twl4030_codec;
2159 codec->owner = THIS_MODULE; 2115 twl4030 = codec->private_data;
2160 codec->read = twl4030_read_reg_cache; 2116 socdev->card->codec = codec;
2161 codec->write = twl4030_write;
2162 codec->set_bias_level = twl4030_set_bias_level;
2163 codec->dai = twl4030_dai;
2164 codec->num_dai = ARRAY_SIZE(twl4030_dai),
2165 codec->reg_cache_size = sizeof(twl4030_reg);
2166 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2167 GFP_KERNEL);
2168 if (codec->reg_cache == NULL)
2169 return -ENOMEM;
2170 2117
2171 /* Configuration for headset ramp delay from setup data */ 2118 /* Configuration for headset ramp delay from setup data */
2172 if (setup) { 2119 if (setup) {
2173 unsigned char hs_pop; 2120 unsigned char hs_pop;
2174 2121
2175 if (setup->sysclk) 2122 if (setup->sysclk != twl4030->sysclk)
2176 twl4030->sysclk = setup->sysclk; 2123 dev_warn(&pdev->dev,
2177 else 2124 "Mismatch in APLL mclk: %u (configured: %u)\n",
2178 twl4030->sysclk = 26000; 2125 setup->sysclk, twl4030->sysclk);
2179 2126
2180 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 2127 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
2181 hs_pop &= ~TWL4030_RAMP_DELAY; 2128 hs_pop &= ~TWL4030_RAMP_DELAY;
2182 hs_pop |= (setup->ramp_delay_value << 2); 2129 hs_pop |= (setup->ramp_delay_value << 2);
2183 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 2130 twl4030_write_reg_cache(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
2184 } else {
2185 twl4030->sysclk = 26000;
2186 } 2131 }
2187 2132
2188 /* register pcms */ 2133 /* register pcms */
2189 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 2134 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
2190 if (ret < 0) { 2135 if (ret < 0) {
2191 printk(KERN_ERR "twl4030: failed to create pcms\n"); 2136 dev_err(&pdev->dev, "failed to create pcms\n");
2192 goto pcm_err; 2137 return ret;
2193 } 2138 }
2194 2139
2195 twl4030_init_chip(codec);
2196
2197 /* power on device */
2198 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2199
2200 snd_soc_add_controls(codec, twl4030_snd_controls, 2140 snd_soc_add_controls(codec, twl4030_snd_controls,
2201 ARRAY_SIZE(twl4030_snd_controls)); 2141 ARRAY_SIZE(twl4030_snd_controls));
2202 twl4030_add_widgets(codec); 2142 twl4030_add_widgets(codec);
2203 2143
2204 ret = snd_soc_init_card(socdev); 2144 return 0;
2205 if (ret < 0) { 2145}
2206 printk(KERN_ERR "twl4030: failed to register card\n");
2207 goto card_err;
2208 }
2209 2146
2210 return ret; 2147static int twl4030_soc_remove(struct platform_device *pdev)
2148{
2149 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
2150 struct snd_soc_codec *codec = socdev->card->codec;
2211 2151
2212card_err: 2152 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2213 snd_soc_free_pcms(socdev); 2153 snd_soc_free_pcms(socdev);
2214 snd_soc_dapm_free(socdev); 2154 snd_soc_dapm_free(socdev);
2215pcm_err: 2155 kfree(codec->private_data);
2216 kfree(codec->reg_cache); 2156 kfree(codec);
2217 return ret;
2218}
2219 2157
2220static struct snd_soc_device *twl4030_socdev; 2158 return 0;
2159}
2221 2160
2222static int twl4030_probe(struct platform_device *pdev) 2161static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2223{ 2162{
2224 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2163 struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data;
2225 struct snd_soc_codec *codec; 2164 struct snd_soc_codec *codec;
2226 struct twl4030_priv *twl4030; 2165 struct twl4030_priv *twl4030;
2166 int ret;
2227 2167
2228 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 2168 if (!pdata) {
2229 if (codec == NULL) 2169 dev_err(&pdev->dev, "platform_data is missing\n");
2230 return -ENOMEM; 2170 return -EINVAL;
2171 }
2231 2172
2232 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL); 2173 twl4030 = kzalloc(sizeof(struct twl4030_priv), GFP_KERNEL);
2233 if (twl4030 == NULL) { 2174 if (twl4030 == NULL) {
2234 kfree(codec); 2175 dev_err(&pdev->dev, "Can not allocate memroy\n");
2235 return -ENOMEM; 2176 return -ENOMEM;
2236 } 2177 }
2237 2178
2179 codec = &twl4030->codec;
2238 codec->private_data = twl4030; 2180 codec->private_data = twl4030;
2239 socdev->card->codec = codec; 2181 codec->dev = &pdev->dev;
2182 twl4030_dai[0].dev = &pdev->dev;
2183 twl4030_dai[1].dev = &pdev->dev;
2184
2240 mutex_init(&codec->mutex); 2185 mutex_init(&codec->mutex);
2241 INIT_LIST_HEAD(&codec->dapm_widgets); 2186 INIT_LIST_HEAD(&codec->dapm_widgets);
2242 INIT_LIST_HEAD(&codec->dapm_paths); 2187 INIT_LIST_HEAD(&codec->dapm_paths);
2243 2188
2244 twl4030_socdev = socdev; 2189 codec->name = "twl4030";
2245 twl4030_init(socdev); 2190 codec->owner = THIS_MODULE;
2191 codec->read = twl4030_read_reg_cache;
2192 codec->write = twl4030_write;
2193 codec->set_bias_level = twl4030_set_bias_level;
2194 codec->dai = twl4030_dai;
2195 codec->num_dai = ARRAY_SIZE(twl4030_dai),
2196 codec->reg_cache_size = sizeof(twl4030_reg);
2197 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
2198 GFP_KERNEL);
2199 if (codec->reg_cache == NULL) {
2200 ret = -ENOMEM;
2201 goto error_cache;
2202 }
2203
2204 platform_set_drvdata(pdev, twl4030);
2205 twl4030_codec = codec;
2206
2207 /* Set the defaults, and power up the codec */
2208 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2209 twl4030_init_chip(codec);
2210 codec->bias_level = SND_SOC_BIAS_OFF;
2211 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2212
2213 ret = snd_soc_register_codec(codec);
2214 if (ret != 0) {
2215 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
2216 goto error_codec;
2217 }
2218
2219 ret = snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai));
2220 if (ret != 0) {
2221 dev_err(codec->dev, "Failed to register DAIs: %d\n", ret);
2222 snd_soc_unregister_codec(codec);
2223 goto error_codec;
2224 }
2246 2225
2247 return 0; 2226 return 0;
2227
2228error_codec:
2229 twl4030_power_down(codec);
2230 kfree(codec->reg_cache);
2231error_cache:
2232 kfree(twl4030);
2233 return ret;
2248} 2234}
2249 2235
2250static int twl4030_remove(struct platform_device *pdev) 2236static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2251{ 2237{
2252 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 2238 struct twl4030_priv *twl4030 = platform_get_drvdata(pdev);
2253 struct snd_soc_codec *codec = socdev->card->codec;
2254 2239
2255 printk(KERN_INFO "TWL4030 Audio Codec remove\n"); 2240 kfree(twl4030);
2256 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2257 snd_soc_free_pcms(socdev);
2258 snd_soc_dapm_free(socdev);
2259 kfree(codec->private_data);
2260 kfree(codec);
2261 2241
2242 twl4030_codec = NULL;
2262 return 0; 2243 return 0;
2263} 2244}
2264 2245
2265struct snd_soc_codec_device soc_codec_dev_twl4030 = { 2246MODULE_ALIAS("platform:twl4030_codec_audio");
2266 .probe = twl4030_probe, 2247
2267 .remove = twl4030_remove, 2248static struct platform_driver twl4030_codec_driver = {
2268 .suspend = twl4030_suspend, 2249 .probe = twl4030_codec_probe,
2269 .resume = twl4030_resume, 2250 .remove = __devexit_p(twl4030_codec_remove),
2251 .driver = {
2252 .name = "twl4030_codec_audio",
2253 .owner = THIS_MODULE,
2254 },
2270}; 2255};
2271EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2272 2256
2273static int __init twl4030_modinit(void) 2257static int __init twl4030_modinit(void)
2274{ 2258{
2275 return snd_soc_register_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2259 return platform_driver_register(&twl4030_codec_driver);
2276} 2260}
2277module_init(twl4030_modinit); 2261module_init(twl4030_modinit);
2278 2262
2279static void __exit twl4030_exit(void) 2263static void __exit twl4030_exit(void)
2280{ 2264{
2281 snd_soc_unregister_dais(&twl4030_dai[0], ARRAY_SIZE(twl4030_dai)); 2265 platform_driver_unregister(&twl4030_codec_driver);
2282} 2266}
2283module_exit(twl4030_exit); 2267module_exit(twl4030_exit);
2284 2268
2269struct snd_soc_codec_device soc_codec_dev_twl4030 = {
2270 .probe = twl4030_soc_probe,
2271 .remove = twl4030_soc_remove,
2272 .suspend = twl4030_soc_suspend,
2273 .resume = twl4030_soc_resume,
2274};
2275EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
2276
2285MODULE_DESCRIPTION("ASoC TWL4030 codec driver"); 2277MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
2286MODULE_AUTHOR("Steve Sakoman"); 2278MODULE_AUTHOR("Steve Sakoman");
2287MODULE_LICENSE("GPL"); 2279MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
index 2b4bfa23f985..dd6396ec9c79 100644
--- a/sound/soc/codecs/twl4030.h
+++ b/sound/soc/codecs/twl4030.h
@@ -22,245 +22,13 @@
22#ifndef __TWL4030_AUDIO_H__ 22#ifndef __TWL4030_AUDIO_H__
23#define __TWL4030_AUDIO_H__ 23#define __TWL4030_AUDIO_H__
24 24
25#define TWL4030_REG_CODEC_MODE 0x1 25/* Register descriptions are here */
26#define TWL4030_REG_OPTION 0x2 26#include <linux/mfd/twl4030-codec.h>
27#define TWL4030_REG_UNKNOWN 0x3
28#define TWL4030_REG_MICBIAS_CTL 0x4
29#define TWL4030_REG_ANAMICL 0x5
30#define TWL4030_REG_ANAMICR 0x6
31#define TWL4030_REG_AVADC_CTL 0x7
32#define TWL4030_REG_ADCMICSEL 0x8
33#define TWL4030_REG_DIGMIXING 0x9
34#define TWL4030_REG_ATXL1PGA 0xA
35#define TWL4030_REG_ATXR1PGA 0xB
36#define TWL4030_REG_AVTXL2PGA 0xC
37#define TWL4030_REG_AVTXR2PGA 0xD
38#define TWL4030_REG_AUDIO_IF 0xE
39#define TWL4030_REG_VOICE_IF 0xF
40#define TWL4030_REG_ARXR1PGA 0x10
41#define TWL4030_REG_ARXL1PGA 0x11
42#define TWL4030_REG_ARXR2PGA 0x12
43#define TWL4030_REG_ARXL2PGA 0x13
44#define TWL4030_REG_VRXPGA 0x14
45#define TWL4030_REG_VSTPGA 0x15
46#define TWL4030_REG_VRX2ARXPGA 0x16
47#define TWL4030_REG_AVDAC_CTL 0x17
48#define TWL4030_REG_ARX2VTXPGA 0x18
49#define TWL4030_REG_ARXL1_APGA_CTL 0x19
50#define TWL4030_REG_ARXR1_APGA_CTL 0x1A
51#define TWL4030_REG_ARXL2_APGA_CTL 0x1B
52#define TWL4030_REG_ARXR2_APGA_CTL 0x1C
53#define TWL4030_REG_ATX2ARXPGA 0x1D
54#define TWL4030_REG_BT_IF 0x1E
55#define TWL4030_REG_BTPGA 0x1F
56#define TWL4030_REG_BTSTPGA 0x20
57#define TWL4030_REG_EAR_CTL 0x21
58#define TWL4030_REG_HS_SEL 0x22
59#define TWL4030_REG_HS_GAIN_SET 0x23
60#define TWL4030_REG_HS_POPN_SET 0x24
61#define TWL4030_REG_PREDL_CTL 0x25
62#define TWL4030_REG_PREDR_CTL 0x26
63#define TWL4030_REG_PRECKL_CTL 0x27
64#define TWL4030_REG_PRECKR_CTL 0x28
65#define TWL4030_REG_HFL_CTL 0x29
66#define TWL4030_REG_HFR_CTL 0x2A
67#define TWL4030_REG_ALC_CTL 0x2B
68#define TWL4030_REG_ALC_SET1 0x2C
69#define TWL4030_REG_ALC_SET2 0x2D
70#define TWL4030_REG_BOOST_CTL 0x2E
71#define TWL4030_REG_SOFTVOL_CTL 0x2F
72#define TWL4030_REG_DTMF_FREQSEL 0x30
73#define TWL4030_REG_DTMF_TONEXT1H 0x31
74#define TWL4030_REG_DTMF_TONEXT1L 0x32
75#define TWL4030_REG_DTMF_TONEXT2H 0x33
76#define TWL4030_REG_DTMF_TONEXT2L 0x34
77#define TWL4030_REG_DTMF_TONOFF 0x35
78#define TWL4030_REG_DTMF_WANONOFF 0x36
79#define TWL4030_REG_I2S_RX_SCRAMBLE_H 0x37
80#define TWL4030_REG_I2S_RX_SCRAMBLE_M 0x38
81#define TWL4030_REG_I2S_RX_SCRAMBLE_L 0x39
82#define TWL4030_REG_APLL_CTL 0x3A
83#define TWL4030_REG_DTMF_CTL 0x3B
84#define TWL4030_REG_DTMF_PGA_CTL2 0x3C
85#define TWL4030_REG_DTMF_PGA_CTL1 0x3D
86#define TWL4030_REG_MISC_SET_1 0x3E
87#define TWL4030_REG_PCMBTMUX 0x3F
88#define TWL4030_REG_RX_PATH_SEL 0x43
89#define TWL4030_REG_VDL_APGA_CTL 0x44
90#define TWL4030_REG_VIBRA_CTL 0x45
91#define TWL4030_REG_VIBRA_SET 0x46
92#define TWL4030_REG_VIBRA_PWM_SET 0x47
93#define TWL4030_REG_ANAMIC_GAIN 0x48
94#define TWL4030_REG_MISC_SET_2 0x49
95#define TWL4030_REG_SW_SHADOW 0x4A
96 27
28/* Sgadow register used by the audio driver */
29#define TWL4030_REG_SW_SHADOW 0x4A
97#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1) 30#define TWL4030_CACHEREGNUM (TWL4030_REG_SW_SHADOW + 1)
98 31
99/* Bitfield Definitions */
100
101/* TWL4030_CODEC_MODE (0x01) Fields */
102
103#define TWL4030_APLL_RATE 0xF0
104#define TWL4030_APLL_RATE_8000 0x00
105#define TWL4030_APLL_RATE_11025 0x10
106#define TWL4030_APLL_RATE_12000 0x20
107#define TWL4030_APLL_RATE_16000 0x40
108#define TWL4030_APLL_RATE_22050 0x50
109#define TWL4030_APLL_RATE_24000 0x60
110#define TWL4030_APLL_RATE_32000 0x80
111#define TWL4030_APLL_RATE_44100 0x90
112#define TWL4030_APLL_RATE_48000 0xA0
113#define TWL4030_APLL_RATE_96000 0xE0
114#define TWL4030_SEL_16K 0x08
115#define TWL4030_CODECPDZ 0x02
116#define TWL4030_OPT_MODE 0x01
117#define TWL4030_OPTION_1 (1 << 0)
118#define TWL4030_OPTION_2 (0 << 0)
119
120/* TWL4030_OPTION (0x02) Fields */
121
122#define TWL4030_ATXL1_EN (1 << 0)
123#define TWL4030_ATXR1_EN (1 << 1)
124#define TWL4030_ATXL2_VTXL_EN (1 << 2)
125#define TWL4030_ATXR2_VTXR_EN (1 << 3)
126#define TWL4030_ARXL1_VRX_EN (1 << 4)
127#define TWL4030_ARXR1_EN (1 << 5)
128#define TWL4030_ARXL2_EN (1 << 6)
129#define TWL4030_ARXR2_EN (1 << 7)
130
131/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
132
133#define TWL4030_MICBIAS2_CTL 0x40
134#define TWL4030_MICBIAS1_CTL 0x20
135#define TWL4030_HSMICBIAS_EN 0x04
136#define TWL4030_MICBIAS2_EN 0x02
137#define TWL4030_MICBIAS1_EN 0x01
138
139/* ANAMICL (0x05) Fields */
140
141#define TWL4030_CNCL_OFFSET_START 0x80
142#define TWL4030_OFFSET_CNCL_SEL 0x60
143#define TWL4030_OFFSET_CNCL_SEL_ARX1 0x00
144#define TWL4030_OFFSET_CNCL_SEL_ARX2 0x20
145#define TWL4030_OFFSET_CNCL_SEL_VRX 0x40
146#define TWL4030_OFFSET_CNCL_SEL_ALL 0x60
147#define TWL4030_MICAMPL_EN 0x10
148#define TWL4030_CKMIC_EN 0x08
149#define TWL4030_AUXL_EN 0x04
150#define TWL4030_HSMIC_EN 0x02
151#define TWL4030_MAINMIC_EN 0x01
152
153/* ANAMICR (0x06) Fields */
154
155#define TWL4030_MICAMPR_EN 0x10
156#define TWL4030_AUXR_EN 0x04
157#define TWL4030_SUBMIC_EN 0x01
158
159/* AVADC_CTL (0x07) Fields */
160
161#define TWL4030_ADCL_EN 0x08
162#define TWL4030_AVADC_CLK_PRIORITY 0x04
163#define TWL4030_ADCR_EN 0x02
164
165/* TWL4030_REG_ADCMICSEL (0x08) Fields */
166
167#define TWL4030_DIGMIC1_EN 0x08
168#define TWL4030_TX2IN_SEL 0x04
169#define TWL4030_DIGMIC0_EN 0x02
170#define TWL4030_TX1IN_SEL 0x01
171
172/* AUDIO_IF (0x0E) Fields */
173
174#define TWL4030_AIF_SLAVE_EN 0x80
175#define TWL4030_DATA_WIDTH 0x60
176#define TWL4030_DATA_WIDTH_16S_16W 0x00
177#define TWL4030_DATA_WIDTH_32S_16W 0x40
178#define TWL4030_DATA_WIDTH_32S_24W 0x60
179#define TWL4030_AIF_FORMAT 0x18
180#define TWL4030_AIF_FORMAT_CODEC 0x00
181#define TWL4030_AIF_FORMAT_LEFT 0x08
182#define TWL4030_AIF_FORMAT_RIGHT 0x10
183#define TWL4030_AIF_FORMAT_TDM 0x18
184#define TWL4030_AIF_TRI_EN 0x04
185#define TWL4030_CLK256FS_EN 0x02
186#define TWL4030_AIF_EN 0x01
187
188/* VOICE_IF (0x0F) Fields */
189
190#define TWL4030_VIF_SLAVE_EN 0x80
191#define TWL4030_VIF_DIN_EN 0x40
192#define TWL4030_VIF_DOUT_EN 0x20
193#define TWL4030_VIF_SWAP 0x10
194#define TWL4030_VIF_FORMAT 0x08
195#define TWL4030_VIF_TRI_EN 0x04
196#define TWL4030_VIF_SUB_EN 0x02
197#define TWL4030_VIF_EN 0x01
198
199/* EAR_CTL (0x21) */
200#define TWL4030_EAR_GAIN 0x30
201
202/* HS_GAIN_SET (0x23) Fields */
203
204#define TWL4030_HSR_GAIN 0x0C
205#define TWL4030_HSR_GAIN_PWR_DOWN 0x00
206#define TWL4030_HSR_GAIN_PLUS_6DB 0x04
207#define TWL4030_HSR_GAIN_0DB 0x08
208#define TWL4030_HSR_GAIN_MINUS_6DB 0x0C
209#define TWL4030_HSL_GAIN 0x03
210#define TWL4030_HSL_GAIN_PWR_DOWN 0x00
211#define TWL4030_HSL_GAIN_PLUS_6DB 0x01
212#define TWL4030_HSL_GAIN_0DB 0x02
213#define TWL4030_HSL_GAIN_MINUS_6DB 0x03
214
215/* HS_POPN_SET (0x24) Fields */
216
217#define TWL4030_VMID_EN 0x40
218#define TWL4030_EXTMUTE 0x20
219#define TWL4030_RAMP_DELAY 0x1C
220#define TWL4030_RAMP_DELAY_20MS 0x00
221#define TWL4030_RAMP_DELAY_40MS 0x04
222#define TWL4030_RAMP_DELAY_81MS 0x08
223#define TWL4030_RAMP_DELAY_161MS 0x0C
224#define TWL4030_RAMP_DELAY_323MS 0x10
225#define TWL4030_RAMP_DELAY_645MS 0x14
226#define TWL4030_RAMP_DELAY_1291MS 0x18
227#define TWL4030_RAMP_DELAY_2581MS 0x1C
228#define TWL4030_RAMP_EN 0x02
229
230/* PREDL_CTL (0x25) */
231#define TWL4030_PREDL_GAIN 0x30
232
233/* PREDR_CTL (0x26) */
234#define TWL4030_PREDR_GAIN 0x30
235
236/* PRECKL_CTL (0x27) */
237#define TWL4030_PRECKL_GAIN 0x30
238
239/* PRECKR_CTL (0x28) */
240#define TWL4030_PRECKR_GAIN 0x30
241
242/* HFL_CTL (0x29, 0x2A) Fields */
243#define TWL4030_HF_CTL_HB_EN 0x04
244#define TWL4030_HF_CTL_LOOP_EN 0x08
245#define TWL4030_HF_CTL_RAMP_EN 0x10
246#define TWL4030_HF_CTL_REF_EN 0x20
247
248/* APLL_CTL (0x3A) Fields */
249
250#define TWL4030_APLL_EN 0x10
251#define TWL4030_APLL_INFREQ 0x0F
252#define TWL4030_APLL_INFREQ_19200KHZ 0x05
253#define TWL4030_APLL_INFREQ_26000KHZ 0x06
254#define TWL4030_APLL_INFREQ_38400KHZ 0x0F
255
256/* REG_MISC_SET_1 (0x3E) Fields */
257
258#define TWL4030_CLK64_EN 0x80
259#define TWL4030_SCRAMBLE_EN 0x40
260#define TWL4030_FMLOOP_EN 0x20
261#define TWL4030_SMOOTH_ANAVOL_EN 0x02
262#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
263
264/* TWL4030_REG_SW_SHADOW (0x4A) Fields */ 32/* TWL4030_REG_SW_SHADOW (0x4A) Fields */
265#define TWL4030_HFL_EN 0x01 33#define TWL4030_HFL_EN 0x01
266#define TWL4030_HFR_EN 0x02 34#define TWL4030_HFR_EN 0x02
@@ -279,3 +47,5 @@ struct twl4030_setup_data {
279}; 47};
280 48
281#endif /* End of __TWL4030_AUDIO_H__ */ 49#endif /* End of __TWL4030_AUDIO_H__ */
50
51
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index c33b92edbded..3e99fe5131dd 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -101,7 +101,7 @@ static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value); 101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
102 102
103 if (reg >= UDA134X_REGS_NUM) { 103 if (reg >= UDA134X_REGS_NUM) {
104 printk(KERN_ERR "%s unkown register: reg: %u", 104 printk(KERN_ERR "%s unknown register: reg: %u",
105 __func__, reg); 105 __func__, reg);
106 return -EINVAL; 106 return -EINVAL;
107 } 107 }
@@ -552,7 +552,7 @@ static int uda134x_soc_probe(struct platform_device *pdev)
552 ARRAY_SIZE(uda1341_snd_controls)); 552 ARRAY_SIZE(uda1341_snd_controls));
553 break; 553 break;
554 default: 554 default:
555 printk(KERN_ERR "%s unkown codec type: %d", 555 printk(KERN_ERR "%s unknown codec type: %d",
556 __func__, pd->model); 556 __func__, pd->model);
557 return -EINVAL; 557 return -EINVAL;
558 } 558 }
@@ -562,17 +562,8 @@ static int uda134x_soc_probe(struct platform_device *pdev)
562 goto pcm_err; 562 goto pcm_err;
563 } 563 }
564 564
565 ret = snd_soc_init_card(socdev);
566 if (ret < 0) {
567 printk(KERN_ERR "UDA134X: failed to register card\n");
568 goto card_err;
569 }
570
571 return 0; 565 return 0;
572 566
573card_err:
574 snd_soc_free_pcms(socdev);
575 snd_soc_dapm_free(socdev);
576pcm_err: 567pcm_err:
577 kfree(codec->reg_cache); 568 kfree(codec->reg_cache);
578reg_err: 569reg_err:
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 92ec03442154..a2763c2e7348 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -378,7 +378,6 @@ static int uda1380_add_widgets(struct snd_soc_codec *codec)
378 378
379 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 379 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
380 380
381 snd_soc_dapm_new_widgets(codec);
382 return 0; 381 return 0;
383} 382}
384 383
@@ -713,17 +712,9 @@ static int uda1380_probe(struct platform_device *pdev)
713 snd_soc_add_controls(codec, uda1380_snd_controls, 712 snd_soc_add_controls(codec, uda1380_snd_controls,
714 ARRAY_SIZE(uda1380_snd_controls)); 713 ARRAY_SIZE(uda1380_snd_controls));
715 uda1380_add_widgets(codec); 714 uda1380_add_widgets(codec);
716 ret = snd_soc_init_card(socdev);
717 if (ret < 0) {
718 dev_err(codec->dev, "failed to register card: %d\n", ret);
719 goto card_err;
720 }
721 715
722 return ret; 716 return ret;
723 717
724card_err:
725 snd_soc_free_pcms(socdev);
726 snd_soc_dapm_free(socdev);
727pcm_err: 718pcm_err:
728 return ret; 719 return ret;
729} 720}
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 593d5b9c9f03..f82125d9e85a 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -800,7 +800,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec)
800 return ret; 800 return ret;
801 } 801 }
802 802
803 return snd_soc_dapm_new_widgets(codec); 803 return 0;
804} 804}
805 805
806static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai, 806static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
@@ -1101,7 +1101,7 @@ static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
1101} 1101}
1102 1102
1103static int wm8350_set_fll(struct snd_soc_dai *codec_dai, 1103static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1104 int pll_id, unsigned int freq_in, 1104 int pll_id, int source, unsigned int freq_in,
1105 unsigned int freq_out) 1105 unsigned int freq_out)
1106{ 1106{
1107 struct snd_soc_codec *codec = codec_dai->codec; 1107 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1501,18 +1501,7 @@ static int wm8350_probe(struct platform_device *pdev)
1501 1501
1502 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1502 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1503 1503
1504 ret = snd_soc_init_card(socdev);
1505 if (ret < 0) {
1506 dev_err(&pdev->dev, "failed to register card\n");
1507 goto card_err;
1508 }
1509
1510 return 0; 1504 return 0;
1511
1512card_err:
1513 snd_soc_free_pcms(socdev);
1514 snd_soc_dapm_free(socdev);
1515 return ret;
1516} 1505}
1517 1506
1518static int wm8350_remove(struct platform_device *pdev) 1507static int wm8350_remove(struct platform_device *pdev)
@@ -1680,21 +1669,6 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1680 return 0; 1669 return 0;
1681} 1670}
1682 1671
1683#ifdef CONFIG_PM
1684static int wm8350_codec_suspend(struct platform_device *pdev, pm_message_t m)
1685{
1686 return snd_soc_suspend_device(&pdev->dev);
1687}
1688
1689static int wm8350_codec_resume(struct platform_device *pdev)
1690{
1691 return snd_soc_resume_device(&pdev->dev);
1692}
1693#else
1694#define wm8350_codec_suspend NULL
1695#define wm8350_codec_resume NULL
1696#endif
1697
1698static struct platform_driver wm8350_codec_driver = { 1672static struct platform_driver wm8350_codec_driver = {
1699 .driver = { 1673 .driver = {
1700 .name = "wm8350-codec", 1674 .name = "wm8350-codec",
@@ -1702,8 +1676,6 @@ static struct platform_driver wm8350_codec_driver = {
1702 }, 1676 },
1703 .probe = wm8350_codec_probe, 1677 .probe = wm8350_codec_probe,
1704 .remove = __devexit_p(wm8350_codec_remove), 1678 .remove = __devexit_p(wm8350_codec_remove),
1705 .suspend = wm8350_codec_suspend,
1706 .resume = wm8350_codec_resume,
1707}; 1679};
1708 1680
1709static __init int wm8350_init(void) 1681static __init int wm8350_init(void)
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index b9ef4d915221..b432f4d4a324 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -915,7 +915,6 @@ static int wm8400_add_widgets(struct snd_soc_codec *codec)
915 915
916 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 916 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
917 917
918 snd_soc_dapm_new_widgets(codec);
919 return 0; 918 return 0;
920} 919}
921 920
@@ -1011,7 +1010,8 @@ static int fll_factors(struct wm8400_priv *wm8400, struct fll_factors *factors,
1011} 1010}
1012 1011
1013static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, 1012static int wm8400_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
1014 unsigned int freq_in, unsigned int freq_out) 1013 int source, unsigned int freq_in,
1014 unsigned int freq_out)
1015{ 1015{
1016 struct snd_soc_codec *codec = codec_dai->codec; 1016 struct snd_soc_codec *codec = codec_dai->codec;
1017 struct wm8400_priv *wm8400 = codec->private_data; 1017 struct wm8400_priv *wm8400 = codec->private_data;
@@ -1399,17 +1399,6 @@ static int wm8400_probe(struct platform_device *pdev)
1399 wm8400_add_controls(codec); 1399 wm8400_add_controls(codec);
1400 wm8400_add_widgets(codec); 1400 wm8400_add_widgets(codec);
1401 1401
1402 ret = snd_soc_init_card(socdev);
1403 if (ret < 0) {
1404 dev_err(&pdev->dev, "failed to register card\n");
1405 goto card_err;
1406 }
1407
1408 return ret;
1409
1410card_err:
1411 snd_soc_free_pcms(socdev);
1412 snd_soc_dapm_free(socdev);
1413pcm_err: 1402pcm_err:
1414 return ret; 1403 return ret;
1415} 1404}
@@ -1558,21 +1547,6 @@ static int __exit wm8400_codec_remove(struct platform_device *dev)
1558 return 0; 1547 return 0;
1559} 1548}
1560 1549
1561#ifdef CONFIG_PM
1562static int wm8400_pdev_suspend(struct platform_device *pdev, pm_message_t msg)
1563{
1564 return snd_soc_suspend_device(&pdev->dev);
1565}
1566
1567static int wm8400_pdev_resume(struct platform_device *pdev)
1568{
1569 return snd_soc_resume_device(&pdev->dev);
1570}
1571#else
1572#define wm8400_pdev_suspend NULL
1573#define wm8400_pdev_resume NULL
1574#endif
1575
1576static struct platform_driver wm8400_codec_driver = { 1550static struct platform_driver wm8400_codec_driver = {
1577 .driver = { 1551 .driver = {
1578 .name = "wm8400-codec", 1552 .name = "wm8400-codec",
@@ -1580,8 +1554,6 @@ static struct platform_driver wm8400_codec_driver = {
1580 }, 1554 },
1581 .probe = wm8400_codec_probe, 1555 .probe = wm8400_codec_probe,
1582 .remove = __exit_p(wm8400_codec_remove), 1556 .remove = __exit_p(wm8400_codec_remove),
1583 .suspend = wm8400_pdev_suspend,
1584 .resume = wm8400_pdev_resume,
1585}; 1557};
1586 1558
1587static int __init wm8400_codec_init(void) 1559static int __init wm8400_codec_init(void)
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 060d5d06ba95..265e68c75df8 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -219,7 +219,6 @@ static int wm8510_add_widgets(struct snd_soc_codec *codec)
219 219
220 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 220 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
221 221
222 snd_soc_dapm_new_widgets(codec);
223 return 0; 222 return 0;
224} 223}
225 224
@@ -271,8 +270,8 @@ static void pll_factors(unsigned int target, unsigned int source)
271 pll_div.k = K; 270 pll_div.k = K;
272} 271}
273 272
274static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, 273static int wm8510_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
275 int pll_id, unsigned int freq_in, unsigned int freq_out) 274 int source, unsigned int freq_in, unsigned int freq_out)
276{ 275{
277 struct snd_soc_codec *codec = codec_dai->codec; 276 struct snd_soc_codec *codec = codec_dai->codec;
278 u16 reg; 277 u16 reg;
@@ -604,16 +603,9 @@ static int wm8510_init(struct snd_soc_device *socdev,
604 snd_soc_add_controls(codec, wm8510_snd_controls, 603 snd_soc_add_controls(codec, wm8510_snd_controls,
605 ARRAY_SIZE(wm8510_snd_controls)); 604 ARRAY_SIZE(wm8510_snd_controls));
606 wm8510_add_widgets(codec); 605 wm8510_add_widgets(codec);
607 ret = snd_soc_init_card(socdev); 606
608 if (ret < 0) {
609 printk(KERN_ERR "wm8510: failed to register card\n");
610 goto card_err;
611 }
612 return ret; 607 return ret;
613 608
614card_err:
615 snd_soc_free_pcms(socdev);
616 snd_soc_dapm_free(socdev);
617err: 609err:
618 kfree(codec->reg_cache); 610 kfree(codec->reg_cache);
619 return ret; 611 return ret;
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index 25870a4652fb..d3a61d7ea0c5 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -117,7 +117,6 @@ static int wm8523_add_widgets(struct snd_soc_codec *codec)
117 117
118 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 118 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
119 119
120 snd_soc_dapm_new_widgets(codec);
121 return 0; 120 return 0;
122} 121}
123 122
@@ -448,17 +447,9 @@ static int wm8523_probe(struct platform_device *pdev)
448 snd_soc_add_controls(codec, wm8523_snd_controls, 447 snd_soc_add_controls(codec, wm8523_snd_controls,
449 ARRAY_SIZE(wm8523_snd_controls)); 448 ARRAY_SIZE(wm8523_snd_controls));
450 wm8523_add_widgets(codec); 449 wm8523_add_widgets(codec);
451 ret = snd_soc_init_card(socdev);
452 if (ret < 0) {
453 dev_err(codec->dev, "failed to register card: %d\n", ret);
454 goto card_err;
455 }
456 450
457 return ret; 451 return ret;
458 452
459card_err:
460 snd_soc_free_pcms(socdev);
461 snd_soc_dapm_free(socdev);
462pcm_err: 453pcm_err:
463 return ret; 454 return ret;
464} 455}
@@ -638,21 +629,6 @@ static __devexit int wm8523_i2c_remove(struct i2c_client *client)
638 return 0; 629 return 0;
639} 630}
640 631
641#ifdef CONFIG_PM
642static int wm8523_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
643{
644 return snd_soc_suspend_device(&i2c->dev);
645}
646
647static int wm8523_i2c_resume(struct i2c_client *i2c)
648{
649 return snd_soc_resume_device(&i2c->dev);
650}
651#else
652#define wm8523_i2c_suspend NULL
653#define wm8523_i2c_resume NULL
654#endif
655
656static const struct i2c_device_id wm8523_i2c_id[] = { 632static const struct i2c_device_id wm8523_i2c_id[] = {
657 { "wm8523", 0 }, 633 { "wm8523", 0 },
658 { } 634 { }
@@ -666,8 +642,6 @@ static struct i2c_driver wm8523_i2c_driver = {
666 }, 642 },
667 .probe = wm8523_i2c_probe, 643 .probe = wm8523_i2c_probe,
668 .remove = __devexit_p(wm8523_i2c_remove), 644 .remove = __devexit_p(wm8523_i2c_remove),
669 .suspend = wm8523_i2c_suspend,
670 .resume = wm8523_i2c_resume,
671 .id_table = wm8523_i2c_id, 645 .id_table = wm8523_i2c_id,
672}; 646};
673#endif 647#endif
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 6bded8c78150..d077df6f5e75 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -315,7 +315,6 @@ static int wm8580_add_widgets(struct snd_soc_codec *codec)
315 315
316 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 316 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
317 317
318 snd_soc_dapm_new_widgets(codec);
319 return 0; 318 return 0;
320} 319}
321 320
@@ -407,8 +406,8 @@ static int pll_factors(struct _pll_div *pll_div, unsigned int target,
407 return 0; 406 return 0;
408} 407}
409 408
410static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, 409static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
411 int pll_id, unsigned int freq_in, unsigned int freq_out) 410 int source, unsigned int freq_in, unsigned int freq_out)
412{ 411{
413 int offset; 412 int offset;
414 struct snd_soc_codec *codec = codec_dai->codec; 413 struct snd_soc_codec *codec = codec_dai->codec;
@@ -800,17 +799,9 @@ static int wm8580_probe(struct platform_device *pdev)
800 snd_soc_add_controls(codec, wm8580_snd_controls, 799 snd_soc_add_controls(codec, wm8580_snd_controls,
801 ARRAY_SIZE(wm8580_snd_controls)); 800 ARRAY_SIZE(wm8580_snd_controls));
802 wm8580_add_widgets(codec); 801 wm8580_add_widgets(codec);
803 ret = snd_soc_init_card(socdev);
804 if (ret < 0) {
805 dev_err(codec->dev, "failed to register card: %d\n", ret);
806 goto card_err;
807 }
808 802
809 return ret; 803 return ret;
810 804
811card_err:
812 snd_soc_free_pcms(socdev);
813 snd_soc_dapm_free(socdev);
814pcm_err: 805pcm_err:
815 return ret; 806 return ret;
816} 807}
@@ -961,21 +952,6 @@ static int wm8580_i2c_remove(struct i2c_client *client)
961 return 0; 952 return 0;
962} 953}
963 954
964#ifdef CONFIG_PM
965static int wm8580_i2c_suspend(struct i2c_client *client, pm_message_t msg)
966{
967 return snd_soc_suspend_device(&client->dev);
968}
969
970static int wm8580_i2c_resume(struct i2c_client *client)
971{
972 return snd_soc_resume_device(&client->dev);
973}
974#else
975#define wm8580_i2c_suspend NULL
976#define wm8580_i2c_resume NULL
977#endif
978
979static const struct i2c_device_id wm8580_i2c_id[] = { 955static const struct i2c_device_id wm8580_i2c_id[] = {
980 { "wm8580", 0 }, 956 { "wm8580", 0 },
981 { } 957 { }
@@ -989,8 +965,6 @@ static struct i2c_driver wm8580_i2c_driver = {
989 }, 965 },
990 .probe = wm8580_i2c_probe, 966 .probe = wm8580_i2c_probe,
991 .remove = wm8580_i2c_remove, 967 .remove = wm8580_i2c_remove,
992 .suspend = wm8580_i2c_suspend,
993 .resume = wm8580_i2c_resume,
994 .id_table = wm8580_i2c_id, 968 .id_table = wm8580_i2c_id,
995}; 969};
996#endif 970#endif
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
new file mode 100644
index 000000000000..24a35603bcf7
--- /dev/null
+++ b/sound/soc/codecs/wm8711.c
@@ -0,0 +1,633 @@
1/*
2 * wm8711.c -- WM8711 ALSA SoC Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics
5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com>
7 *
8 * Based on wm8731.c by Richard Purdie
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/platform_device.h>
22#include <linux/spi/spi.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/tlv.h>
29#include <sound/initval.h>
30
31#include "wm8711.h"
32
33static struct snd_soc_codec *wm8711_codec;
34
35/* codec private data */
36struct wm8711_priv {
37 struct snd_soc_codec codec;
38 u16 reg_cache[WM8711_CACHEREGNUM];
39 unsigned int sysclk;
40};
41
42/*
43 * wm8711 register cache
44 * We can't read the WM8711 register space when we are
45 * using 2 wire for device control, so we cache them instead.
46 * There is no point in caching the reset register
47 */
48static const u16 wm8711_reg[WM8711_CACHEREGNUM] = {
49 0x0079, 0x0079, 0x000a, 0x0008,
50 0x009f, 0x000a, 0x0000, 0x0000
51};
52
53#define wm8711_reset(c) snd_soc_write(c, WM8711_RESET, 0)
54
55static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
56
57static const struct snd_kcontrol_new wm8711_snd_controls[] = {
58
59SOC_DOUBLE_R_TLV("Master Playback Volume", WM8711_LOUT1V, WM8711_ROUT1V,
60 0, 127, 0, out_tlv),
61SOC_DOUBLE_R("Master Playback ZC Switch", WM8711_LOUT1V, WM8711_ROUT1V,
62 7, 1, 0),
63
64};
65
66/* Output Mixer */
67static const struct snd_kcontrol_new wm8711_output_mixer_controls[] = {
68SOC_DAPM_SINGLE("Line Bypass Switch", WM8711_APANA, 3, 1, 0),
69SOC_DAPM_SINGLE("HiFi Playback Switch", WM8711_APANA, 4, 1, 0),
70};
71
72static const struct snd_soc_dapm_widget wm8711_dapm_widgets[] = {
73SND_SOC_DAPM_MIXER("Output Mixer", WM8711_PWR, 4, 1,
74 &wm8711_output_mixer_controls[0],
75 ARRAY_SIZE(wm8711_output_mixer_controls)),
76SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8711_PWR, 3, 1),
77SND_SOC_DAPM_OUTPUT("LOUT"),
78SND_SOC_DAPM_OUTPUT("LHPOUT"),
79SND_SOC_DAPM_OUTPUT("ROUT"),
80SND_SOC_DAPM_OUTPUT("RHPOUT"),
81};
82
83static const struct snd_soc_dapm_route intercon[] = {
84 /* output mixer */
85 {"Output Mixer", "Line Bypass Switch", "Line Input"},
86 {"Output Mixer", "HiFi Playback Switch", "DAC"},
87
88 /* outputs */
89 {"RHPOUT", NULL, "Output Mixer"},
90 {"ROUT", NULL, "Output Mixer"},
91 {"LHPOUT", NULL, "Output Mixer"},
92 {"LOUT", NULL, "Output Mixer"},
93};
94
95static int wm8711_add_widgets(struct snd_soc_codec *codec)
96{
97 snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets,
98 ARRAY_SIZE(wm8711_dapm_widgets));
99
100 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
101
102 return 0;
103}
104
105struct _coeff_div {
106 u32 mclk;
107 u32 rate;
108 u16 fs;
109 u8 sr:4;
110 u8 bosr:1;
111 u8 usb:1;
112};
113
114/* codec mclk clock divider coefficients */
115static const struct _coeff_div coeff_div[] = {
116 /* 48k */
117 {12288000, 48000, 256, 0x0, 0x0, 0x0},
118 {18432000, 48000, 384, 0x0, 0x1, 0x0},
119 {12000000, 48000, 250, 0x0, 0x0, 0x1},
120
121 /* 32k */
122 {12288000, 32000, 384, 0x6, 0x0, 0x0},
123 {18432000, 32000, 576, 0x6, 0x1, 0x0},
124 {12000000, 32000, 375, 0x6, 0x0, 0x1},
125
126 /* 8k */
127 {12288000, 8000, 1536, 0x3, 0x0, 0x0},
128 {18432000, 8000, 2304, 0x3, 0x1, 0x0},
129 {11289600, 8000, 1408, 0xb, 0x0, 0x0},
130 {16934400, 8000, 2112, 0xb, 0x1, 0x0},
131 {12000000, 8000, 1500, 0x3, 0x0, 0x1},
132
133 /* 96k */
134 {12288000, 96000, 128, 0x7, 0x0, 0x0},
135 {18432000, 96000, 192, 0x7, 0x1, 0x0},
136 {12000000, 96000, 125, 0x7, 0x0, 0x1},
137
138 /* 44.1k */
139 {11289600, 44100, 256, 0x8, 0x0, 0x0},
140 {16934400, 44100, 384, 0x8, 0x1, 0x0},
141 {12000000, 44100, 272, 0x8, 0x1, 0x1},
142
143 /* 88.2k */
144 {11289600, 88200, 128, 0xf, 0x0, 0x0},
145 {16934400, 88200, 192, 0xf, 0x1, 0x0},
146 {12000000, 88200, 136, 0xf, 0x1, 0x1},
147};
148
149static inline int get_coeff(int mclk, int rate)
150{
151 int i;
152
153 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
154 if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk)
155 return i;
156 }
157 return 0;
158}
159
160static int wm8711_hw_params(struct snd_pcm_substream *substream,
161 struct snd_pcm_hw_params *params,
162 struct snd_soc_dai *dai)
163{
164 struct snd_soc_codec *codec = dai->codec;
165 struct wm8711_priv *wm8711 = codec->private_data;
166 u16 iface = snd_soc_read(codec, WM8711_IFACE) & 0xfffc;
167 int i = get_coeff(wm8711->sysclk, params_rate(params));
168 u16 srate = (coeff_div[i].sr << 2) |
169 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
170
171 snd_soc_write(codec, WM8711_SRATE, srate);
172
173 /* bit size */
174 switch (params_format(params)) {
175 case SNDRV_PCM_FORMAT_S16_LE:
176 break;
177 case SNDRV_PCM_FORMAT_S20_3LE:
178 iface |= 0x0004;
179 break;
180 case SNDRV_PCM_FORMAT_S24_LE:
181 iface |= 0x0008;
182 break;
183 }
184
185 snd_soc_write(codec, WM8711_IFACE, iface);
186 return 0;
187}
188
189static int wm8711_pcm_prepare(struct snd_pcm_substream *substream,
190 struct snd_soc_dai *dai)
191{
192 struct snd_soc_codec *codec = dai->codec;
193
194 /* set active */
195 snd_soc_write(codec, WM8711_ACTIVE, 0x0001);
196
197 return 0;
198}
199
200static void wm8711_shutdown(struct snd_pcm_substream *substream,
201 struct snd_soc_dai *dai)
202{
203 struct snd_soc_codec *codec = dai->codec;
204
205 /* deactivate */
206 if (!codec->active) {
207 udelay(50);
208 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
209 }
210}
211
212static int wm8711_mute(struct snd_soc_dai *dai, int mute)
213{
214 struct snd_soc_codec *codec = dai->codec;
215 u16 mute_reg = snd_soc_read(codec, WM8711_APDIGI) & 0xfff7;
216
217 if (mute)
218 snd_soc_write(codec, WM8711_APDIGI, mute_reg | 0x8);
219 else
220 snd_soc_write(codec, WM8711_APDIGI, mute_reg);
221
222 return 0;
223}
224
225static int wm8711_set_dai_sysclk(struct snd_soc_dai *codec_dai,
226 int clk_id, unsigned int freq, int dir)
227{
228 struct snd_soc_codec *codec = codec_dai->codec;
229 struct wm8711_priv *wm8711 = codec->private_data;
230
231 switch (freq) {
232 case 11289600:
233 case 12000000:
234 case 12288000:
235 case 16934400:
236 case 18432000:
237 wm8711->sysclk = freq;
238 return 0;
239 }
240 return -EINVAL;
241}
242
243static int wm8711_set_dai_fmt(struct snd_soc_dai *codec_dai,
244 unsigned int fmt)
245{
246 struct snd_soc_codec *codec = codec_dai->codec;
247 u16 iface = 0;
248
249 /* set master/slave audio interface */
250 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
251 case SND_SOC_DAIFMT_CBM_CFM:
252 iface |= 0x0040;
253 break;
254 case SND_SOC_DAIFMT_CBS_CFS:
255 break;
256 default:
257 return -EINVAL;
258 }
259
260 /* interface format */
261 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
262 case SND_SOC_DAIFMT_I2S:
263 iface |= 0x0002;
264 break;
265 case SND_SOC_DAIFMT_RIGHT_J:
266 break;
267 case SND_SOC_DAIFMT_LEFT_J:
268 iface |= 0x0001;
269 break;
270 case SND_SOC_DAIFMT_DSP_A:
271 iface |= 0x0003;
272 break;
273 case SND_SOC_DAIFMT_DSP_B:
274 iface |= 0x0013;
275 break;
276 default:
277 return -EINVAL;
278 }
279
280 /* clock inversion */
281 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
282 case SND_SOC_DAIFMT_NB_NF:
283 break;
284 case SND_SOC_DAIFMT_IB_IF:
285 iface |= 0x0090;
286 break;
287 case SND_SOC_DAIFMT_IB_NF:
288 iface |= 0x0080;
289 break;
290 case SND_SOC_DAIFMT_NB_IF:
291 iface |= 0x0010;
292 break;
293 default:
294 return -EINVAL;
295 }
296
297 /* set iface */
298 snd_soc_write(codec, WM8711_IFACE, iface);
299 return 0;
300}
301
302
303static int wm8711_set_bias_level(struct snd_soc_codec *codec,
304 enum snd_soc_bias_level level)
305{
306 u16 reg = snd_soc_read(codec, WM8711_PWR) & 0xff7f;
307
308 switch (level) {
309 case SND_SOC_BIAS_ON:
310 snd_soc_write(codec, WM8711_PWR, reg);
311 break;
312 case SND_SOC_BIAS_PREPARE:
313 break;
314 case SND_SOC_BIAS_STANDBY:
315 snd_soc_write(codec, WM8711_PWR, reg | 0x0040);
316 break;
317 case SND_SOC_BIAS_OFF:
318 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
319 snd_soc_write(codec, WM8711_PWR, 0xffff);
320 break;
321 }
322 codec->bias_level = level;
323 return 0;
324}
325
326#define WM8711_RATES SNDRV_PCM_RATE_8000_96000
327
328#define WM8711_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
329 SNDRV_PCM_FMTBIT_S24_LE)
330
331static struct snd_soc_dai_ops wm8711_ops = {
332 .prepare = wm8711_pcm_prepare,
333 .hw_params = wm8711_hw_params,
334 .shutdown = wm8711_shutdown,
335 .digital_mute = wm8711_mute,
336 .set_sysclk = wm8711_set_dai_sysclk,
337 .set_fmt = wm8711_set_dai_fmt,
338};
339
340struct snd_soc_dai wm8711_dai = {
341 .name = "WM8711",
342 .playback = {
343 .stream_name = "Playback",
344 .channels_min = 1,
345 .channels_max = 2,
346 .rates = WM8711_RATES,
347 .formats = WM8711_FORMATS,
348 },
349 .ops = &wm8711_ops,
350};
351EXPORT_SYMBOL_GPL(wm8711_dai);
352
353static int wm8711_suspend(struct platform_device *pdev, pm_message_t state)
354{
355 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
356 struct snd_soc_codec *codec = socdev->card->codec;
357
358 snd_soc_write(codec, WM8711_ACTIVE, 0x0);
359 wm8711_set_bias_level(codec, SND_SOC_BIAS_OFF);
360 return 0;
361}
362
363static int wm8711_resume(struct platform_device *pdev)
364{
365 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
366 struct snd_soc_codec *codec = socdev->card->codec;
367 int i;
368 u8 data[2];
369 u16 *cache = codec->reg_cache;
370
371 /* Sync reg_cache with the hardware */
372 for (i = 0; i < ARRAY_SIZE(wm8711_reg); i++) {
373 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
374 data[1] = cache[i] & 0x00ff;
375 codec->hw_write(codec->control_data, data, 2);
376 }
377 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
378 wm8711_set_bias_level(codec, codec->suspend_bias_level);
379 return 0;
380}
381
382static int wm8711_probe(struct platform_device *pdev)
383{
384 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
385 struct snd_soc_codec *codec;
386 int ret = 0;
387
388 if (wm8711_codec == NULL) {
389 dev_err(&pdev->dev, "Codec device not registered\n");
390 return -ENODEV;
391 }
392
393 socdev->card->codec = wm8711_codec;
394 codec = wm8711_codec;
395
396 /* register pcms */
397 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
398 if (ret < 0) {
399 dev_err(codec->dev, "failed to create pcms: %d\n", ret);
400 goto pcm_err;
401 }
402
403 snd_soc_add_controls(codec, wm8711_snd_controls,
404 ARRAY_SIZE(wm8711_snd_controls));
405 wm8711_add_widgets(codec);
406
407 return ret;
408
409pcm_err:
410 return ret;
411}
412
413/* power down chip */
414static int wm8711_remove(struct platform_device *pdev)
415{
416 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
417
418 snd_soc_free_pcms(socdev);
419 snd_soc_dapm_free(socdev);
420
421 return 0;
422}
423
424struct snd_soc_codec_device soc_codec_dev_wm8711 = {
425 .probe = wm8711_probe,
426 .remove = wm8711_remove,
427 .suspend = wm8711_suspend,
428 .resume = wm8711_resume,
429};
430EXPORT_SYMBOL_GPL(soc_codec_dev_wm8711);
431
432static int wm8711_register(struct wm8711_priv *wm8711,
433 enum snd_soc_control_type control)
434{
435 int ret;
436 struct snd_soc_codec *codec = &wm8711->codec;
437 u16 reg;
438
439 if (wm8711_codec) {
440 dev_err(codec->dev, "Another WM8711 is registered\n");
441 return -EINVAL;
442 }
443
444 mutex_init(&codec->mutex);
445 INIT_LIST_HEAD(&codec->dapm_widgets);
446 INIT_LIST_HEAD(&codec->dapm_paths);
447
448 codec->private_data = wm8711;
449 codec->name = "WM8711";
450 codec->owner = THIS_MODULE;
451 codec->bias_level = SND_SOC_BIAS_OFF;
452 codec->set_bias_level = wm8711_set_bias_level;
453 codec->dai = &wm8711_dai;
454 codec->num_dai = 1;
455 codec->reg_cache_size = WM8711_CACHEREGNUM;
456 codec->reg_cache = &wm8711->reg_cache;
457
458 memcpy(codec->reg_cache, wm8711_reg, sizeof(wm8711_reg));
459
460 ret = snd_soc_codec_set_cache_io(codec, 7, 9, control);
461 if (ret < 0) {
462 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
463 goto err;
464 }
465
466 ret = wm8711_reset(codec);
467 if (ret < 0) {
468 dev_err(codec->dev, "Failed to issue reset\n");
469 goto err;
470 }
471
472 wm8711_dai.dev = codec->dev;
473
474 wm8711_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
475
476 /* Latch the update bits */
477 reg = snd_soc_read(codec, WM8711_LOUT1V);
478 snd_soc_write(codec, WM8711_LOUT1V, reg | 0x0100);
479 reg = snd_soc_read(codec, WM8711_ROUT1V);
480 snd_soc_write(codec, WM8711_ROUT1V, reg | 0x0100);
481
482 wm8711_codec = codec;
483
484 ret = snd_soc_register_codec(codec);
485 if (ret != 0) {
486 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
487 goto err;
488 }
489
490 ret = snd_soc_register_dai(&wm8711_dai);
491 if (ret != 0) {
492 dev_err(codec->dev, "Failed to register DAI: %d\n", ret);
493 goto err_codec;
494 }
495
496 return 0;
497
498err_codec:
499 snd_soc_unregister_codec(codec);
500err:
501 kfree(wm8711);
502 return ret;
503}
504
505static void wm8711_unregister(struct wm8711_priv *wm8711)
506{
507 wm8711_set_bias_level(&wm8711->codec, SND_SOC_BIAS_OFF);
508 snd_soc_unregister_dai(&wm8711_dai);
509 snd_soc_unregister_codec(&wm8711->codec);
510 kfree(wm8711);
511 wm8711_codec = NULL;
512}
513
514#if defined(CONFIG_SPI_MASTER)
515static int __devinit wm8711_spi_probe(struct spi_device *spi)
516{
517 struct snd_soc_codec *codec;
518 struct wm8711_priv *wm8711;
519
520 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
521 if (wm8711 == NULL)
522 return -ENOMEM;
523
524 codec = &wm8711->codec;
525 codec->control_data = spi;
526 codec->dev = &spi->dev;
527
528 dev_set_drvdata(&spi->dev, wm8711);
529
530 return wm8711_register(wm8711, SND_SOC_SPI);
531}
532
533static int __devexit wm8711_spi_remove(struct spi_device *spi)
534{
535 struct wm8711_priv *wm8711 = dev_get_drvdata(&spi->dev);
536
537 wm8711_unregister(wm8711);
538
539 return 0;
540}
541
542static struct spi_driver wm8711_spi_driver = {
543 .driver = {
544 .name = "wm8711",
545 .bus = &spi_bus_type,
546 .owner = THIS_MODULE,
547 },
548 .probe = wm8711_spi_probe,
549 .remove = __devexit_p(wm8711_spi_remove),
550};
551#endif /* CONFIG_SPI_MASTER */
552
553#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
554static __devinit int wm8711_i2c_probe(struct i2c_client *i2c,
555 const struct i2c_device_id *id)
556{
557 struct wm8711_priv *wm8711;
558 struct snd_soc_codec *codec;
559
560 wm8711 = kzalloc(sizeof(struct wm8711_priv), GFP_KERNEL);
561 if (wm8711 == NULL)
562 return -ENOMEM;
563
564 codec = &wm8711->codec;
565 codec->hw_write = (hw_write_t)i2c_master_send;
566
567 i2c_set_clientdata(i2c, wm8711);
568 codec->control_data = i2c;
569
570 codec->dev = &i2c->dev;
571
572 return wm8711_register(wm8711, SND_SOC_I2C);
573}
574
575static __devexit int wm8711_i2c_remove(struct i2c_client *client)
576{
577 struct wm8711_priv *wm8711 = i2c_get_clientdata(client);
578 wm8711_unregister(wm8711);
579 return 0;
580}
581
582static const struct i2c_device_id wm8711_i2c_id[] = {
583 { "wm8711", 0 },
584 { }
585};
586MODULE_DEVICE_TABLE(i2c, wm8711_i2c_id);
587
588static struct i2c_driver wm8711_i2c_driver = {
589 .driver = {
590 .name = "WM8711 I2C Codec",
591 .owner = THIS_MODULE,
592 },
593 .probe = wm8711_i2c_probe,
594 .remove = __devexit_p(wm8711_i2c_remove),
595 .id_table = wm8711_i2c_id,
596};
597#endif
598
599static int __init wm8711_modinit(void)
600{
601 int ret;
602#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
603 ret = i2c_add_driver(&wm8711_i2c_driver);
604 if (ret != 0) {
605 printk(KERN_ERR "Failed to register WM8711 I2C driver: %d\n",
606 ret);
607 }
608#endif
609#if defined(CONFIG_SPI_MASTER)
610 ret = spi_register_driver(&wm8711_spi_driver);
611 if (ret != 0) {
612 printk(KERN_ERR "Failed to register WM8711 SPI driver: %d\n",
613 ret);
614 }
615#endif
616 return 0;
617}
618module_init(wm8711_modinit);
619
620static void __exit wm8711_exit(void)
621{
622#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
623 i2c_del_driver(&wm8711_i2c_driver);
624#endif
625#if defined(CONFIG_SPI_MASTER)
626 spi_unregister_driver(&wm8711_spi_driver);
627#endif
628}
629module_exit(wm8711_exit);
630
631MODULE_DESCRIPTION("ASoC WM8711 driver");
632MODULE_AUTHOR("Mike Arthur");
633MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8711.h b/sound/soc/codecs/wm8711.h
new file mode 100644
index 000000000000..381e84a43816
--- /dev/null
+++ b/sound/soc/codecs/wm8711.h
@@ -0,0 +1,42 @@
1/*
2 * wm8711.h -- WM8711 Soc Audio driver
3 *
4 * Copyright 2006 Wolfson Microelectronics
5 *
6 * Author: Mike Arthur <linux@wolfsonmicro.com>
7 *
8 * Based on wm8731.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef _WM8711_H
16#define _WM8711_H
17
18/* WM8711 register space */
19
20#define WM8711_LOUT1V 0x02
21#define WM8711_ROUT1V 0x03
22#define WM8711_APANA 0x04
23#define WM8711_APDIGI 0x05
24#define WM8711_PWR 0x06
25#define WM8711_IFACE 0x07
26#define WM8711_SRATE 0x08
27#define WM8711_ACTIVE 0x09
28#define WM8711_RESET 0x0f
29
30#define WM8711_CACHEREGNUM 8
31
32#define WM8711_SYSCLK 0
33#define WM8711_DAI 0
34
35struct wm8711_setup_data {
36 unsigned short i2c_address;
37};
38
39extern struct snd_soc_dai wm8711_dai;
40extern struct snd_soc_codec_device soc_codec_dev_wm8711;
41
42#endif
diff --git a/sound/soc/codecs/wm8727.c b/sound/soc/codecs/wm8727.c
new file mode 100644
index 000000000000..d8ffbd641d71
--- /dev/null
+++ b/sound/soc/codecs/wm8727.c
@@ -0,0 +1,135 @@
1/*
2 * wm8727.c
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/device.h>
19#include <sound/core.h>
20#include <sound/pcm.h>
21#include <sound/ac97_codec.h>
22#include <sound/initval.h>
23#include <sound/soc.h>
24
25#include "wm8727.h"
26/*
27 * Note this is a simple chip with no configuration interface, sample rate is
28 * determined automatically by examining the Master clock and Bit clock ratios
29 */
30#define WM8727_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
31 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 |\
32 SNDRV_PCM_RATE_192000)
33
34
35struct snd_soc_dai wm8727_dai = {
36 .name = "WM8727",
37 .playback = {
38 .stream_name = "Playback",
39 .channels_min = 2,
40 .channels_max = 2,
41 .rates = WM8727_RATES,
42 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
43 },
44};
45EXPORT_SYMBOL_GPL(wm8727_dai);
46
47static int wm8727_soc_probe(struct platform_device *pdev)
48{
49 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
50 struct snd_soc_codec *codec;
51 int ret = 0;
52
53 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
54 if (codec == NULL)
55 return -ENOMEM;
56 mutex_init(&codec->mutex);
57 codec->name = "WM8727";
58 codec->owner = THIS_MODULE;
59 codec->dai = &wm8727_dai;
60 codec->num_dai = 1;
61 socdev->card->codec = codec;
62 INIT_LIST_HEAD(&codec->dapm_widgets);
63 INIT_LIST_HEAD(&codec->dapm_paths);
64
65 /* register pcms */
66 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
67 if (ret < 0) {
68 printk(KERN_ERR "wm8727: failed to create pcms\n");
69 goto pcm_err;
70 }
71
72 return ret;
73
74pcm_err:
75 kfree(socdev->card->codec);
76 socdev->card->codec = NULL;
77 return ret;
78}
79
80static int wm8727_soc_remove(struct platform_device *pdev)
81{
82 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
83 struct snd_soc_codec *codec = socdev->card->codec;
84
85 if (codec == NULL)
86 return 0;
87 snd_soc_free_pcms(socdev);
88 kfree(codec);
89 return 0;
90}
91
92struct snd_soc_codec_device soc_codec_dev_wm8727 = {
93 .probe = wm8727_soc_probe,
94 .remove = wm8727_soc_remove,
95};
96EXPORT_SYMBOL_GPL(soc_codec_dev_wm8727);
97
98
99static __devinit int wm8727_platform_probe(struct platform_device *pdev)
100{
101 wm8727_dai.dev = &pdev->dev;
102 return snd_soc_register_dai(&wm8727_dai);
103}
104
105static int __devexit wm8727_platform_remove(struct platform_device *pdev)
106{
107 snd_soc_unregister_dai(&wm8727_dai);
108 return 0;
109}
110
111static struct platform_driver wm8727_codec_driver = {
112 .driver = {
113 .name = "wm8727-codec",
114 .owner = THIS_MODULE,
115 },
116
117 .probe = wm8727_platform_probe,
118 .remove = __devexit_p(wm8727_platform_remove),
119};
120
121static int __init wm8727_init(void)
122{
123 return platform_driver_register(&wm8727_codec_driver);
124}
125module_init(wm8727_init);
126
127static void __exit wm8727_exit(void)
128{
129 platform_driver_unregister(&wm8727_codec_driver);
130}
131module_exit(wm8727_exit);
132
133MODULE_DESCRIPTION("ASoC wm8727 driver");
134MODULE_AUTHOR("Neil Jones");
135MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8727.h b/sound/soc/codecs/wm8727.h
new file mode 100644
index 000000000000..ee19aa71bcdc
--- /dev/null
+++ b/sound/soc/codecs/wm8727.h
@@ -0,0 +1,21 @@
1/*
2 * wm8727.h
3 *
4 * Created on: 15-Oct-2009
5 * Author: neil.jones@imgtec.com
6 *
7 * Copyright (C) 2009 Imagination Technologies Ltd.
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 */
14
15#ifndef WM8727_H_
16#define WM8727_H_
17
18extern struct snd_soc_dai wm8727_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8727;
20
21#endif /* WM8727_H_ */
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 16e969a762c3..3fb653ba363a 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -74,8 +74,6 @@ static int wm8728_add_widgets(struct snd_soc_codec *codec)
74 74
75 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 75 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
76 76
77 snd_soc_dapm_new_widgets(codec);
78
79 return 0; 77 return 0;
80} 78}
81 79
@@ -287,17 +285,9 @@ static int wm8728_init(struct snd_soc_device *socdev,
287 snd_soc_add_controls(codec, wm8728_snd_controls, 285 snd_soc_add_controls(codec, wm8728_snd_controls,
288 ARRAY_SIZE(wm8728_snd_controls)); 286 ARRAY_SIZE(wm8728_snd_controls));
289 wm8728_add_widgets(codec); 287 wm8728_add_widgets(codec);
290 ret = snd_soc_init_card(socdev);
291 if (ret < 0) {
292 printk(KERN_ERR "wm8728: failed to register card\n");
293 goto card_err;
294 }
295 288
296 return ret; 289 return ret;
297 290
298card_err:
299 snd_soc_free_pcms(socdev);
300 snd_soc_dapm_free(socdev);
301err: 291err:
302 kfree(codec->reg_cache); 292 kfree(codec->reg_cache);
303 return ret; 293 return ret;
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index d3fd4f28d96e..3a497810f939 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -19,6 +19,7 @@
19#include <linux/pm.h> 19#include <linux/pm.h>
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/regulator/consumer.h>
22#include <linux/spi/spi.h> 23#include <linux/spi/spi.h>
23#include <sound/core.h> 24#include <sound/core.h>
24#include <sound/pcm.h> 25#include <sound/pcm.h>
@@ -33,9 +34,18 @@
33static struct snd_soc_codec *wm8731_codec; 34static struct snd_soc_codec *wm8731_codec;
34struct snd_soc_codec_device soc_codec_dev_wm8731; 35struct snd_soc_codec_device soc_codec_dev_wm8731;
35 36
37#define WM8731_NUM_SUPPLIES 4
38static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
39 "AVDD",
40 "HPVDD",
41 "DCVDD",
42 "DBVDD",
43};
44
36/* codec private data */ 45/* codec private data */
37struct wm8731_priv { 46struct wm8731_priv {
38 struct snd_soc_codec codec; 47 struct snd_soc_codec codec;
48 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
39 u16 reg_cache[WM8731_CACHEREGNUM]; 49 u16 reg_cache[WM8731_CACHEREGNUM];
40 unsigned int sysclk; 50 unsigned int sysclk;
41}; 51};
@@ -149,7 +159,6 @@ static int wm8731_add_widgets(struct snd_soc_codec *codec)
149 159
150 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 160 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
151 161
152 snd_soc_dapm_new_widgets(codec);
153 return 0; 162 return 0;
154} 163}
155 164
@@ -422,9 +431,12 @@ static int wm8731_suspend(struct platform_device *pdev, pm_message_t state)
422{ 431{
423 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 432 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
424 struct snd_soc_codec *codec = socdev->card->codec; 433 struct snd_soc_codec *codec = socdev->card->codec;
434 struct wm8731_priv *wm8731 = codec->private_data;
425 435
426 snd_soc_write(codec, WM8731_ACTIVE, 0x0); 436 snd_soc_write(codec, WM8731_ACTIVE, 0x0);
427 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); 437 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF);
438 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies),
439 wm8731->supplies);
428 return 0; 440 return 0;
429} 441}
430 442
@@ -432,10 +444,16 @@ static int wm8731_resume(struct platform_device *pdev)
432{ 444{
433 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 445 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
434 struct snd_soc_codec *codec = socdev->card->codec; 446 struct snd_soc_codec *codec = socdev->card->codec;
435 int i; 447 struct wm8731_priv *wm8731 = codec->private_data;
448 int i, ret;
436 u8 data[2]; 449 u8 data[2];
437 u16 *cache = codec->reg_cache; 450 u16 *cache = codec->reg_cache;
438 451
452 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
453 wm8731->supplies);
454 if (ret != 0)
455 return ret;
456
439 /* Sync reg_cache with the hardware */ 457 /* Sync reg_cache with the hardware */
440 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { 458 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) {
441 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001); 459 data[0] = (i << 1) | ((cache[i] >> 8) & 0x0001);
@@ -444,6 +462,7 @@ static int wm8731_resume(struct platform_device *pdev)
444 } 462 }
445 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 463 wm8731_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
446 wm8731_set_bias_level(codec, codec->suspend_bias_level); 464 wm8731_set_bias_level(codec, codec->suspend_bias_level);
465
447 return 0; 466 return 0;
448} 467}
449#else 468#else
@@ -475,17 +494,9 @@ static int wm8731_probe(struct platform_device *pdev)
475 snd_soc_add_controls(codec, wm8731_snd_controls, 494 snd_soc_add_controls(codec, wm8731_snd_controls,
476 ARRAY_SIZE(wm8731_snd_controls)); 495 ARRAY_SIZE(wm8731_snd_controls));
477 wm8731_add_widgets(codec); 496 wm8731_add_widgets(codec);
478 ret = snd_soc_init_card(socdev);
479 if (ret < 0) {
480 dev_err(codec->dev, "failed to register card: %d\n", ret);
481 goto card_err;
482 }
483 497
484 return ret; 498 return ret;
485 499
486card_err:
487 snd_soc_free_pcms(socdev);
488 snd_soc_dapm_free(socdev);
489pcm_err: 500pcm_err:
490 return ret; 501 return ret;
491} 502}
@@ -512,7 +523,7 @@ EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
512static int wm8731_register(struct wm8731_priv *wm8731, 523static int wm8731_register(struct wm8731_priv *wm8731,
513 enum snd_soc_control_type control) 524 enum snd_soc_control_type control)
514{ 525{
515 int ret; 526 int ret, i;
516 struct snd_soc_codec *codec = &wm8731->codec; 527 struct snd_soc_codec *codec = &wm8731->codec;
517 528
518 if (wm8731_codec) { 529 if (wm8731_codec) {
@@ -543,10 +554,27 @@ static int wm8731_register(struct wm8731_priv *wm8731,
543 goto err; 554 goto err;
544 } 555 }
545 556
557 for (i = 0; i < ARRAY_SIZE(wm8731->supplies); i++)
558 wm8731->supplies[i].supply = wm8731_supply_names[i];
559
560 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8731->supplies),
561 wm8731->supplies);
562 if (ret != 0) {
563 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
564 goto err;
565 }
566
567 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
568 wm8731->supplies);
569 if (ret != 0) {
570 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
571 goto err_regulator_get;
572 }
573
546 ret = wm8731_reset(codec); 574 ret = wm8731_reset(codec);
547 if (ret < 0) { 575 if (ret < 0) {
548 dev_err(codec->dev, "Failed to issue reset: %d\n", ret); 576 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
549 goto err; 577 goto err_regulator_enable;
550 } 578 }
551 579
552 wm8731_dai.dev = codec->dev; 580 wm8731_dai.dev = codec->dev;
@@ -567,7 +595,7 @@ static int wm8731_register(struct wm8731_priv *wm8731,
567 ret = snd_soc_register_codec(codec); 595 ret = snd_soc_register_codec(codec);
568 if (ret != 0) { 596 if (ret != 0) {
569 dev_err(codec->dev, "Failed to register codec: %d\n", ret); 597 dev_err(codec->dev, "Failed to register codec: %d\n", ret);
570 goto err; 598 goto err_regulator_enable;
571 } 599 }
572 600
573 ret = snd_soc_register_dai(&wm8731_dai); 601 ret = snd_soc_register_dai(&wm8731_dai);
@@ -581,6 +609,10 @@ static int wm8731_register(struct wm8731_priv *wm8731,
581 609
582err_codec: 610err_codec:
583 snd_soc_unregister_codec(codec); 611 snd_soc_unregister_codec(codec);
612err_regulator_enable:
613 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
614err_regulator_get:
615 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
584err: 616err:
585 kfree(wm8731); 617 kfree(wm8731);
586 return ret; 618 return ret;
@@ -591,6 +623,8 @@ static void wm8731_unregister(struct wm8731_priv *wm8731)
591 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF); 623 wm8731_set_bias_level(&wm8731->codec, SND_SOC_BIAS_OFF);
592 snd_soc_unregister_dai(&wm8731_dai); 624 snd_soc_unregister_dai(&wm8731_dai);
593 snd_soc_unregister_codec(&wm8731->codec); 625 snd_soc_unregister_codec(&wm8731->codec);
626 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
627 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
594 kfree(wm8731); 628 kfree(wm8731);
595 wm8731_codec = NULL; 629 wm8731_codec = NULL;
596} 630}
@@ -623,21 +657,6 @@ static int __devexit wm8731_spi_remove(struct spi_device *spi)
623 return 0; 657 return 0;
624} 658}
625 659
626#ifdef CONFIG_PM
627static int wm8731_spi_suspend(struct spi_device *spi, pm_message_t msg)
628{
629 return snd_soc_suspend_device(&spi->dev);
630}
631
632static int wm8731_spi_resume(struct spi_device *spi)
633{
634 return snd_soc_resume_device(&spi->dev);
635}
636#else
637#define wm8731_spi_suspend NULL
638#define wm8731_spi_resume NULL
639#endif
640
641static struct spi_driver wm8731_spi_driver = { 660static struct spi_driver wm8731_spi_driver = {
642 .driver = { 661 .driver = {
643 .name = "wm8731", 662 .name = "wm8731",
@@ -645,8 +664,6 @@ static struct spi_driver wm8731_spi_driver = {
645 .owner = THIS_MODULE, 664 .owner = THIS_MODULE,
646 }, 665 },
647 .probe = wm8731_spi_probe, 666 .probe = wm8731_spi_probe,
648 .suspend = wm8731_spi_suspend,
649 .resume = wm8731_spi_resume,
650 .remove = __devexit_p(wm8731_spi_remove), 667 .remove = __devexit_p(wm8731_spi_remove),
651}; 668};
652#endif /* CONFIG_SPI_MASTER */ 669#endif /* CONFIG_SPI_MASTER */
@@ -679,21 +696,6 @@ static __devexit int wm8731_i2c_remove(struct i2c_client *client)
679 return 0; 696 return 0;
680} 697}
681 698
682#ifdef CONFIG_PM
683static int wm8731_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
684{
685 return snd_soc_suspend_device(&i2c->dev);
686}
687
688static int wm8731_i2c_resume(struct i2c_client *i2c)
689{
690 return snd_soc_resume_device(&i2c->dev);
691}
692#else
693#define wm8731_i2c_suspend NULL
694#define wm8731_i2c_resume NULL
695#endif
696
697static const struct i2c_device_id wm8731_i2c_id[] = { 699static const struct i2c_device_id wm8731_i2c_id[] = {
698 { "wm8731", 0 }, 700 { "wm8731", 0 },
699 { } 701 { }
@@ -707,8 +709,6 @@ static struct i2c_driver wm8731_i2c_driver = {
707 }, 709 },
708 .probe = wm8731_i2c_probe, 710 .probe = wm8731_i2c_probe,
709 .remove = __devexit_p(wm8731_i2c_remove), 711 .remove = __devexit_p(wm8731_i2c_remove),
710 .suspend = wm8731_i2c_suspend,
711 .resume = wm8731_i2c_resume,
712 .id_table = wm8731_i2c_id, 712 .id_table = wm8731_i2c_id,
713}; 713};
714#endif 714#endif
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 4ba1e7e93fb4..475c67ac7818 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -403,7 +403,6 @@ static int wm8750_add_widgets(struct snd_soc_codec *codec)
403 403
404 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 404 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
405 405
406 snd_soc_dapm_new_widgets(codec);
407 return 0; 406 return 0;
408} 407}
409 408
@@ -772,16 +771,8 @@ static int wm8750_init(struct snd_soc_device *socdev,
772 snd_soc_add_controls(codec, wm8750_snd_controls, 771 snd_soc_add_controls(codec, wm8750_snd_controls,
773 ARRAY_SIZE(wm8750_snd_controls)); 772 ARRAY_SIZE(wm8750_snd_controls));
774 wm8750_add_widgets(codec); 773 wm8750_add_widgets(codec);
775 ret = snd_soc_init_card(socdev);
776 if (ret < 0) {
777 printk(KERN_ERR "wm8750: failed to register card\n");
778 goto card_err;
779 }
780 return ret; 774 return ret;
781 775
782card_err:
783 snd_soc_free_pcms(socdev);
784 snd_soc_dapm_free(socdev);
785err: 776err:
786 kfree(codec->reg_cache); 777 kfree(codec->reg_cache);
787 return ret; 778 return ret;
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 5ad677ce80da..d6850dacda29 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -673,7 +673,6 @@ static int wm8753_add_widgets(struct snd_soc_codec *codec)
673 673
674 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 674 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
675 675
676 snd_soc_dapm_new_widgets(codec);
677 return 0; 676 return 0;
678} 677}
679 678
@@ -724,8 +723,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
724 pll_div->k = K; 723 pll_div->k = K;
725} 724}
726 725
727static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, 726static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
728 int pll_id, unsigned int freq_in, unsigned int freq_out) 727 int source, unsigned int freq_in, unsigned int freq_out)
729{ 728{
730 u16 reg, enable; 729 u16 reg, enable;
731 int offset; 730 int offset;
@@ -1583,18 +1582,9 @@ static int wm8753_probe(struct platform_device *pdev)
1583 snd_soc_add_controls(codec, wm8753_snd_controls, 1582 snd_soc_add_controls(codec, wm8753_snd_controls,
1584 ARRAY_SIZE(wm8753_snd_controls)); 1583 ARRAY_SIZE(wm8753_snd_controls));
1585 wm8753_add_widgets(codec); 1584 wm8753_add_widgets(codec);
1586 ret = snd_soc_init_card(socdev);
1587 if (ret < 0) {
1588 printk(KERN_ERR "wm8753: failed to register card\n");
1589 goto card_err;
1590 }
1591 1585
1592 return 0; 1586 return 0;
1593 1587
1594card_err:
1595 snd_soc_free_pcms(socdev);
1596 snd_soc_dapm_free(socdev);
1597
1598pcm_err: 1588pcm_err:
1599 return ret; 1589 return ret;
1600} 1590}
@@ -1767,21 +1757,6 @@ static int wm8753_i2c_remove(struct i2c_client *client)
1767 return 0; 1757 return 0;
1768} 1758}
1769 1759
1770#ifdef CONFIG_PM
1771static int wm8753_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1772{
1773 return snd_soc_suspend_device(&client->dev);
1774}
1775
1776static int wm8753_i2c_resume(struct i2c_client *client)
1777{
1778 return snd_soc_resume_device(&client->dev);
1779}
1780#else
1781#define wm8753_i2c_suspend NULL
1782#define wm8753_i2c_resume NULL
1783#endif
1784
1785static const struct i2c_device_id wm8753_i2c_id[] = { 1760static const struct i2c_device_id wm8753_i2c_id[] = {
1786 { "wm8753", 0 }, 1761 { "wm8753", 0 },
1787 { } 1762 { }
@@ -1795,8 +1770,6 @@ static struct i2c_driver wm8753_i2c_driver = {
1795 }, 1770 },
1796 .probe = wm8753_i2c_probe, 1771 .probe = wm8753_i2c_probe,
1797 .remove = wm8753_i2c_remove, 1772 .remove = wm8753_i2c_remove,
1798 .suspend = wm8753_i2c_suspend,
1799 .resume = wm8753_i2c_resume,
1800 .id_table = wm8753_i2c_id, 1773 .id_table = wm8753_i2c_id,
1801}; 1774};
1802#endif 1775#endif
@@ -1852,22 +1825,6 @@ static int __devexit wm8753_spi_remove(struct spi_device *spi)
1852 return 0; 1825 return 0;
1853} 1826}
1854 1827
1855#ifdef CONFIG_PM
1856static int wm8753_spi_suspend(struct spi_device *spi, pm_message_t msg)
1857{
1858 return snd_soc_suspend_device(&spi->dev);
1859}
1860
1861static int wm8753_spi_resume(struct spi_device *spi)
1862{
1863 return snd_soc_resume_device(&spi->dev);
1864}
1865
1866#else
1867#define wm8753_spi_suspend NULL
1868#define wm8753_spi_resume NULL
1869#endif
1870
1871static struct spi_driver wm8753_spi_driver = { 1828static struct spi_driver wm8753_spi_driver = {
1872 .driver = { 1829 .driver = {
1873 .name = "wm8753", 1830 .name = "wm8753",
@@ -1876,8 +1833,6 @@ static struct spi_driver wm8753_spi_driver = {
1876 }, 1833 },
1877 .probe = wm8753_spi_probe, 1834 .probe = wm8753_spi_probe,
1878 .remove = __devexit_p(wm8753_spi_remove), 1835 .remove = __devexit_p(wm8753_spi_remove),
1879 .suspend = wm8753_spi_suspend,
1880 .resume = wm8753_spi_resume,
1881}; 1836};
1882#endif 1837#endif
1883 1838
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index a9829aa26e53..ab2c0da18091 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -447,17 +447,8 @@ static int wm8776_probe(struct platform_device *pdev)
447 ARRAY_SIZE(wm8776_dapm_widgets)); 447 ARRAY_SIZE(wm8776_dapm_widgets));
448 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); 448 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes));
449 449
450 ret = snd_soc_init_card(socdev);
451 if (ret < 0) {
452 dev_err(codec->dev, "failed to register card: %d\n", ret);
453 goto card_err;
454 }
455
456 return ret; 450 return ret;
457 451
458card_err:
459 snd_soc_free_pcms(socdev);
460 snd_soc_dapm_free(socdev);
461pcm_err: 452pcm_err:
462 return ret; 453 return ret;
463} 454}
@@ -616,21 +607,6 @@ static int __devexit wm8776_spi_remove(struct spi_device *spi)
616 return 0; 607 return 0;
617} 608}
618 609
619#ifdef CONFIG_PM
620static int wm8776_spi_suspend(struct spi_device *spi, pm_message_t msg)
621{
622 return snd_soc_suspend_device(&spi->dev);
623}
624
625static int wm8776_spi_resume(struct spi_device *spi)
626{
627 return snd_soc_resume_device(&spi->dev);
628}
629#else
630#define wm8776_spi_suspend NULL
631#define wm8776_spi_resume NULL
632#endif
633
634static struct spi_driver wm8776_spi_driver = { 610static struct spi_driver wm8776_spi_driver = {
635 .driver = { 611 .driver = {
636 .name = "wm8776", 612 .name = "wm8776",
@@ -638,8 +614,6 @@ static struct spi_driver wm8776_spi_driver = {
638 .owner = THIS_MODULE, 614 .owner = THIS_MODULE,
639 }, 615 },
640 .probe = wm8776_spi_probe, 616 .probe = wm8776_spi_probe,
641 .suspend = wm8776_spi_suspend,
642 .resume = wm8776_spi_resume,
643 .remove = __devexit_p(wm8776_spi_remove), 617 .remove = __devexit_p(wm8776_spi_remove),
644}; 618};
645#endif /* CONFIG_SPI_MASTER */ 619#endif /* CONFIG_SPI_MASTER */
@@ -673,21 +647,6 @@ static __devexit int wm8776_i2c_remove(struct i2c_client *client)
673 return 0; 647 return 0;
674} 648}
675 649
676#ifdef CONFIG_PM
677static int wm8776_i2c_suspend(struct i2c_client *i2c, pm_message_t msg)
678{
679 return snd_soc_suspend_device(&i2c->dev);
680}
681
682static int wm8776_i2c_resume(struct i2c_client *i2c)
683{
684 return snd_soc_resume_device(&i2c->dev);
685}
686#else
687#define wm8776_i2c_suspend NULL
688#define wm8776_i2c_resume NULL
689#endif
690
691static const struct i2c_device_id wm8776_i2c_id[] = { 650static const struct i2c_device_id wm8776_i2c_id[] = {
692 { "wm8776", 0 }, 651 { "wm8776", 0 },
693 { } 652 { }
@@ -701,8 +660,6 @@ static struct i2c_driver wm8776_i2c_driver = {
701 }, 660 },
702 .probe = wm8776_i2c_probe, 661 .probe = wm8776_i2c_probe,
703 .remove = __devexit_p(wm8776_i2c_remove), 662 .remove = __devexit_p(wm8776_i2c_remove),
704 .suspend = wm8776_i2c_suspend,
705 .resume = wm8776_i2c_resume,
706 .id_table = wm8776_i2c_id, 663 .id_table = wm8776_i2c_id,
707}; 664};
708#endif 665#endif
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 5e9c855c0036..c9438dd62df3 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -618,8 +618,6 @@ static int wm8900_add_widgets(struct snd_soc_codec *codec)
618 618
619 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 619 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
620 620
621 snd_soc_dapm_new_widgets(codec);
622
623 return 0; 621 return 0;
624} 622}
625 623
@@ -814,8 +812,8 @@ reenable:
814 return 0; 812 return 0;
815} 813}
816 814
817static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, 815static int wm8900_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
818 int pll_id, unsigned int freq_in, unsigned int freq_out) 816 int source, unsigned int freq_in, unsigned int freq_out)
819{ 817{
820 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out); 818 return wm8900_set_fll(codec_dai->codec, pll_id, freq_in, freq_out);
821} 819}
@@ -1312,21 +1310,6 @@ static __devexit int wm8900_i2c_remove(struct i2c_client *client)
1312 return 0; 1310 return 0;
1313} 1311}
1314 1312
1315#ifdef CONFIG_PM
1316static int wm8900_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1317{
1318 return snd_soc_suspend_device(&client->dev);
1319}
1320
1321static int wm8900_i2c_resume(struct i2c_client *client)
1322{
1323 return snd_soc_resume_device(&client->dev);
1324}
1325#else
1326#define wm8900_i2c_suspend NULL
1327#define wm8900_i2c_resume NULL
1328#endif
1329
1330static const struct i2c_device_id wm8900_i2c_id[] = { 1313static const struct i2c_device_id wm8900_i2c_id[] = {
1331 { "wm8900", 0 }, 1314 { "wm8900", 0 },
1332 { } 1315 { }
@@ -1340,8 +1323,6 @@ static struct i2c_driver wm8900_i2c_driver = {
1340 }, 1323 },
1341 .probe = wm8900_i2c_probe, 1324 .probe = wm8900_i2c_probe,
1342 .remove = __devexit_p(wm8900_i2c_remove), 1325 .remove = __devexit_p(wm8900_i2c_remove),
1343 .suspend = wm8900_i2c_suspend,
1344 .resume = wm8900_i2c_resume,
1345 .id_table = wm8900_i2c_id, 1326 .id_table = wm8900_i2c_id,
1346}; 1327};
1347 1328
@@ -1370,17 +1351,6 @@ static int wm8900_probe(struct platform_device *pdev)
1370 ARRAY_SIZE(wm8900_snd_controls)); 1351 ARRAY_SIZE(wm8900_snd_controls));
1371 wm8900_add_widgets(codec); 1352 wm8900_add_widgets(codec);
1372 1353
1373 ret = snd_soc_init_card(socdev);
1374 if (ret < 0) {
1375 dev_err(&pdev->dev, "Failed to register card\n");
1376 goto card_err;
1377 }
1378
1379 return ret;
1380
1381card_err:
1382 snd_soc_free_pcms(socdev);
1383 snd_soc_dapm_free(socdev);
1384pcm_err: 1354pcm_err:
1385 return ret; 1355 return ret;
1386} 1356}
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index fe1307b500cf..ce5515e3f2b0 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -607,7 +607,7 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
607SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), 607SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
608SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), 608SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
609SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), 609SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
610SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8903_DRC_3, 5, 124, 1, 610SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8903_DRC_3, 5, 124, 1,
611 drc_tlv_thresh), 611 drc_tlv_thresh),
612SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp), 612SOC_SINGLE_TLV("DRC Volume", WM8903_DRC_3, 0, 30, 1, drc_tlv_amp),
613SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min), 613SOC_SINGLE_TLV("DRC Minimum Gain Volume", WM8903_DRC_1, 2, 3, 1, drc_tlv_min),
@@ -617,11 +617,11 @@ SOC_ENUM("DRC Decay Rate", drc_decay),
617SOC_ENUM("DRC FF Delay", drc_ff_delay), 617SOC_ENUM("DRC FF Delay", drc_ff_delay),
618SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0), 618SOC_SINGLE("DRC Anticlip Switch", WM8903_DRC_0, 1, 1, 0),
619SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0), 619SOC_SINGLE("DRC QR Switch", WM8903_DRC_0, 2, 1, 0),
620SOC_SINGLE_TLV("DRC QR Threashold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max), 620SOC_SINGLE_TLV("DRC QR Threshold Volume", WM8903_DRC_0, 6, 3, 0, drc_tlv_max),
621SOC_ENUM("DRC QR Decay Rate", drc_qr_decay), 621SOC_ENUM("DRC QR Decay Rate", drc_qr_decay),
622SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0), 622SOC_SINGLE("DRC Smoothing Switch", WM8903_DRC_0, 3, 1, 0),
623SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0), 623SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8903_DRC_0, 0, 1, 0),
624SOC_ENUM("DRC Smoothing Threashold", drc_smoothing), 624SOC_ENUM("DRC Smoothing Threshold", drc_smoothing),
625SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), 625SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup),
626 626
627SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, 627SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT,
@@ -919,8 +919,6 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
919 919
920 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 920 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
921 921
922 snd_soc_dapm_new_widgets(codec);
923
924 return 0; 922 return 0;
925} 923}
926 924
@@ -1655,21 +1653,6 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
1655 return 0; 1653 return 0;
1656} 1654}
1657 1655
1658#ifdef CONFIG_PM
1659static int wm8903_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1660{
1661 return snd_soc_suspend_device(&client->dev);
1662}
1663
1664static int wm8903_i2c_resume(struct i2c_client *client)
1665{
1666 return snd_soc_resume_device(&client->dev);
1667}
1668#else
1669#define wm8903_i2c_suspend NULL
1670#define wm8903_i2c_resume NULL
1671#endif
1672
1673/* i2c codec control layer */ 1656/* i2c codec control layer */
1674static const struct i2c_device_id wm8903_i2c_id[] = { 1657static const struct i2c_device_id wm8903_i2c_id[] = {
1675 { "wm8903", 0 }, 1658 { "wm8903", 0 },
@@ -1684,8 +1667,6 @@ static struct i2c_driver wm8903_i2c_driver = {
1684 }, 1667 },
1685 .probe = wm8903_i2c_probe, 1668 .probe = wm8903_i2c_probe,
1686 .remove = __devexit_p(wm8903_i2c_remove), 1669 .remove = __devexit_p(wm8903_i2c_remove),
1687 .suspend = wm8903_i2c_suspend,
1688 .resume = wm8903_i2c_resume,
1689 .id_table = wm8903_i2c_id, 1670 .id_table = wm8903_i2c_id,
1690}; 1671};
1691 1672
@@ -1712,17 +1693,8 @@ static int wm8903_probe(struct platform_device *pdev)
1712 ARRAY_SIZE(wm8903_snd_controls)); 1693 ARRAY_SIZE(wm8903_snd_controls));
1713 wm8903_add_widgets(socdev->card->codec); 1694 wm8903_add_widgets(socdev->card->codec);
1714 1695
1715 ret = snd_soc_init_card(socdev);
1716 if (ret < 0) {
1717 dev_err(&pdev->dev, "wm8903: failed to register card\n");
1718 goto card_err;
1719 }
1720
1721 return ret; 1696 return ret;
1722 1697
1723card_err:
1724 snd_soc_free_pcms(socdev);
1725 snd_soc_dapm_free(socdev);
1726err: 1698err:
1727 return ret; 1699 return ret;
1728} 1700}
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 1ef2454c5205..3d850b97037a 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -298,7 +298,6 @@ static int wm8940_add_widgets(struct snd_soc_codec *codec)
298 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 298 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
299 if (ret) 299 if (ret)
300 goto error_ret; 300 goto error_ret;
301 ret = snd_soc_dapm_new_widgets(codec);
302 301
303error_ret: 302error_ret:
304 return ret; 303 return ret;
@@ -536,8 +535,8 @@ static void pll_factors(unsigned int target, unsigned int source)
536} 535}
537 536
538/* Untested at the moment */ 537/* Untested at the moment */
539static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, 538static int wm8940_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
540 int pll_id, unsigned int freq_in, unsigned int freq_out) 539 int source, unsigned int freq_in, unsigned int freq_out)
541{ 540{
542 struct snd_soc_codec *codec = codec_dai->codec; 541 struct snd_soc_codec *codec = codec_dai->codec;
543 u16 reg; 542 u16 reg;
@@ -731,12 +730,6 @@ static int wm8940_probe(struct platform_device *pdev)
731 if (ret) 730 if (ret)
732 goto error_free_pcms; 731 goto error_free_pcms;
733 732
734 ret = snd_soc_init_card(socdev);
735 if (ret < 0) {
736 dev_err(codec->dev, "failed to register card: %d\n", ret);
737 goto error_free_pcms;
738 }
739
740 return ret; 733 return ret;
741 734
742error_free_pcms: 735error_free_pcms:
@@ -877,21 +870,6 @@ static int __devexit wm8940_i2c_remove(struct i2c_client *client)
877 return 0; 870 return 0;
878} 871}
879 872
880#ifdef CONFIG_PM
881static int wm8940_i2c_suspend(struct i2c_client *client, pm_message_t msg)
882{
883 return snd_soc_suspend_device(&client->dev);
884}
885
886static int wm8940_i2c_resume(struct i2c_client *client)
887{
888 return snd_soc_resume_device(&client->dev);
889}
890#else
891#define wm8940_i2c_suspend NULL
892#define wm8940_i2c_resume NULL
893#endif
894
895static const struct i2c_device_id wm8940_i2c_id[] = { 873static const struct i2c_device_id wm8940_i2c_id[] = {
896 { "wm8940", 0 }, 874 { "wm8940", 0 },
897 { } 875 { }
@@ -905,8 +883,6 @@ static struct i2c_driver wm8940_i2c_driver = {
905 }, 883 },
906 .probe = wm8940_i2c_probe, 884 .probe = wm8940_i2c_probe,
907 .remove = __devexit_p(wm8940_i2c_remove), 885 .remove = __devexit_p(wm8940_i2c_remove),
908 .suspend = wm8940_i2c_suspend,
909 .resume = wm8940_i2c_resume,
910 .id_table = wm8940_i2c_id, 886 .id_table = wm8940_i2c_id,
911}; 887};
912 888
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index f59703be61c8..d07bcc1e1c60 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -307,7 +307,6 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
307 307
308 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 308 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
309 309
310 snd_soc_dapm_new_widgets(codec);
311 return 0; 310 return 0;
312} 311}
313 312
@@ -540,8 +539,8 @@ static int pll_factors(unsigned int source, unsigned int target,
540 return 0; 539 return 0;
541} 540}
542 541
543static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, 542static int wm8960_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
544 int pll_id, unsigned int freq_in, unsigned int freq_out) 543 int source, unsigned int freq_in, unsigned int freq_out)
545{ 544{
546 struct snd_soc_codec *codec = codec_dai->codec; 545 struct snd_soc_codec *codec = codec_dai->codec;
547 u16 reg; 546 u16 reg;
@@ -713,17 +712,9 @@ static int wm8960_probe(struct platform_device *pdev)
713 snd_soc_add_controls(codec, wm8960_snd_controls, 712 snd_soc_add_controls(codec, wm8960_snd_controls,
714 ARRAY_SIZE(wm8960_snd_controls)); 713 ARRAY_SIZE(wm8960_snd_controls));
715 wm8960_add_widgets(codec); 714 wm8960_add_widgets(codec);
716 ret = snd_soc_init_card(socdev);
717 if (ret < 0) {
718 dev_err(codec->dev, "failed to register card: %d\n", ret);
719 goto card_err;
720 }
721 715
722 return ret; 716 return ret;
723 717
724card_err:
725 snd_soc_free_pcms(socdev);
726 snd_soc_dapm_free(socdev);
727pcm_err: 718pcm_err:
728 return ret; 719 return ret;
729} 720}
@@ -883,21 +874,6 @@ static __devexit int wm8960_i2c_remove(struct i2c_client *client)
883 return 0; 874 return 0;
884} 875}
885 876
886#ifdef CONFIG_PM
887static int wm8960_i2c_suspend(struct i2c_client *client, pm_message_t msg)
888{
889 return snd_soc_suspend_device(&client->dev);
890}
891
892static int wm8960_i2c_resume(struct i2c_client *client)
893{
894 return snd_soc_resume_device(&client->dev);
895}
896#else
897#define wm8960_i2c_suspend NULL
898#define wm8960_i2c_resume NULL
899#endif
900
901static const struct i2c_device_id wm8960_i2c_id[] = { 877static const struct i2c_device_id wm8960_i2c_id[] = {
902 { "wm8960", 0 }, 878 { "wm8960", 0 },
903 { } 879 { }
@@ -911,8 +887,6 @@ static struct i2c_driver wm8960_i2c_driver = {
911 }, 887 },
912 .probe = wm8960_i2c_probe, 888 .probe = wm8960_i2c_probe,
913 .remove = __devexit_p(wm8960_i2c_remove), 889 .remove = __devexit_p(wm8960_i2c_remove),
914 .suspend = wm8960_i2c_suspend,
915 .resume = wm8960_i2c_resume,
916 .id_table = wm8960_i2c_id, 890 .id_table = wm8960_i2c_id,
917}; 891};
918 892
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 503032085899..a8007d58813f 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -986,19 +986,9 @@ static int wm8961_probe(struct platform_device *pdev)
986 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets, 986 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets,
987 ARRAY_SIZE(wm8961_dapm_widgets)); 987 ARRAY_SIZE(wm8961_dapm_widgets));
988 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 988 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
989 snd_soc_dapm_new_widgets(codec);
990
991 ret = snd_soc_init_card(socdev);
992 if (ret < 0) {
993 dev_err(codec->dev, "failed to register card: %d\n", ret);
994 goto card_err;
995 }
996 989
997 return ret; 990 return ret;
998 991
999card_err:
1000 snd_soc_free_pcms(socdev);
1001 snd_soc_dapm_free(socdev);
1002pcm_err: 992pcm_err:
1003 return ret; 993 return ret;
1004} 994}
@@ -1206,21 +1196,6 @@ static __devexit int wm8961_i2c_remove(struct i2c_client *client)
1206 return 0; 1196 return 0;
1207} 1197}
1208 1198
1209#ifdef CONFIG_PM
1210static int wm8961_i2c_suspend(struct i2c_client *client, pm_message_t state)
1211{
1212 return snd_soc_suspend_device(&client->dev);
1213}
1214
1215static int wm8961_i2c_resume(struct i2c_client *client)
1216{
1217 return snd_soc_resume_device(&client->dev);
1218}
1219#else
1220#define wm8961_i2c_suspend NULL
1221#define wm8961_i2c_resume NULL
1222#endif
1223
1224static const struct i2c_device_id wm8961_i2c_id[] = { 1199static const struct i2c_device_id wm8961_i2c_id[] = {
1225 { "wm8961", 0 }, 1200 { "wm8961", 0 },
1226 { } 1201 { }
@@ -1234,8 +1209,6 @@ static struct i2c_driver wm8961_i2c_driver = {
1234 }, 1209 },
1235 .probe = wm8961_i2c_probe, 1210 .probe = wm8961_i2c_probe,
1236 .remove = __devexit_p(wm8961_i2c_remove), 1211 .remove = __devexit_p(wm8961_i2c_remove),
1237 .suspend = wm8961_i2c_suspend,
1238 .resume = wm8961_i2c_resume,
1239 .id_table = wm8961_i2c_id, 1212 .id_table = wm8961_i2c_id,
1240}; 1213};
1241 1214
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index d66efb0546ea..d9540d55fc89 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -338,8 +338,6 @@ static int wm8971_add_widgets(struct snd_soc_codec *codec)
338 338
339 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 339 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
340 340
341 snd_soc_dapm_new_widgets(codec);
342
343 return 0; 341 return 0;
344} 342}
345 343
@@ -703,16 +701,9 @@ static int wm8971_init(struct snd_soc_device *socdev,
703 snd_soc_add_controls(codec, wm8971_snd_controls, 701 snd_soc_add_controls(codec, wm8971_snd_controls,
704 ARRAY_SIZE(wm8971_snd_controls)); 702 ARRAY_SIZE(wm8971_snd_controls));
705 wm8971_add_widgets(codec); 703 wm8971_add_widgets(codec);
706 ret = snd_soc_init_card(socdev); 704
707 if (ret < 0) {
708 printk(KERN_ERR "wm8971: failed to register card\n");
709 goto card_err;
710 }
711 return ret; 705 return ret;
712 706
713card_err:
714 snd_soc_free_pcms(socdev);
715 snd_soc_dapm_free(socdev);
716err: 707err:
717 kfree(codec->reg_cache); 708 kfree(codec->reg_cache);
718 return ret; 709 return ret;
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index 98d663afc97d..81c57b5c591c 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -276,41 +276,42 @@ static int wm8974_add_widgets(struct snd_soc_codec *codec)
276 276
277 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 277 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
278 278
279 snd_soc_dapm_new_widgets(codec);
280 return 0; 279 return 0;
281} 280}
282 281
283struct pll_ { 282struct pll_ {
284 unsigned int pre_div:4; /* prescale - 1 */ 283 unsigned int pre_div:1;
285 unsigned int n:4; 284 unsigned int n:4;
286 unsigned int k; 285 unsigned int k;
287}; 286};
288 287
289static struct pll_ pll_div;
290
291/* The size in bits of the pll divide multiplied by 10 288/* The size in bits of the pll divide multiplied by 10
292 * to allow rounding later */ 289 * to allow rounding later */
293#define FIXED_PLL_SIZE ((1 << 24) * 10) 290#define FIXED_PLL_SIZE ((1 << 24) * 10)
294 291
295static void pll_factors(unsigned int target, unsigned int source) 292static void pll_factors(struct pll_ *pll_div,
293 unsigned int target, unsigned int source)
296{ 294{
297 unsigned long long Kpart; 295 unsigned long long Kpart;
298 unsigned int K, Ndiv, Nmod; 296 unsigned int K, Ndiv, Nmod;
299 297
298 /* There is a fixed divide by 4 in the output path */
299 target *= 4;
300
300 Ndiv = target / source; 301 Ndiv = target / source;
301 if (Ndiv < 6) { 302 if (Ndiv < 6) {
302 source >>= 1; 303 source /= 2;
303 pll_div.pre_div = 1; 304 pll_div->pre_div = 1;
304 Ndiv = target / source; 305 Ndiv = target / source;
305 } else 306 } else
306 pll_div.pre_div = 0; 307 pll_div->pre_div = 0;
307 308
308 if ((Ndiv < 6) || (Ndiv > 12)) 309 if ((Ndiv < 6) || (Ndiv > 12))
309 printk(KERN_WARNING 310 printk(KERN_WARNING
310 "WM8974 N value %u outwith recommended range!\n", 311 "WM8974 N value %u outwith recommended range!\n",
311 Ndiv); 312 Ndiv);
312 313
313 pll_div.n = Ndiv; 314 pll_div->n = Ndiv;
314 Nmod = target % source; 315 Nmod = target % source;
315 Kpart = FIXED_PLL_SIZE * (long long)Nmod; 316 Kpart = FIXED_PLL_SIZE * (long long)Nmod;
316 317
@@ -325,13 +326,14 @@ static void pll_factors(unsigned int target, unsigned int source)
325 /* Move down to proper range now rounding is done */ 326 /* Move down to proper range now rounding is done */
326 K /= 10; 327 K /= 10;
327 328
328 pll_div.k = K; 329 pll_div->k = K;
329} 330}
330 331
331static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, 332static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
332 int pll_id, unsigned int freq_in, unsigned int freq_out) 333 int source, unsigned int freq_in, unsigned int freq_out)
333{ 334{
334 struct snd_soc_codec *codec = codec_dai->codec; 335 struct snd_soc_codec *codec = codec_dai->codec;
336 struct pll_ pll_div;
335 u16 reg; 337 u16 reg;
336 338
337 if (freq_in == 0 || freq_out == 0) { 339 if (freq_in == 0 || freq_out == 0) {
@@ -345,7 +347,7 @@ static int wm8974_set_dai_pll(struct snd_soc_dai *codec_dai,
345 return 0; 347 return 0;
346 } 348 }
347 349
348 pll_factors(freq_out*4, freq_in); 350 pll_factors(&pll_div, freq_out, freq_in);
349 351
350 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n); 352 snd_soc_write(codec, WM8974_PLLN, (pll_div.pre_div << 4) | pll_div.n);
351 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18); 353 snd_soc_write(codec, WM8974_PLLK1, pll_div.k >> 18);
@@ -638,17 +640,9 @@ static int wm8974_probe(struct platform_device *pdev)
638 snd_soc_add_controls(codec, wm8974_snd_controls, 640 snd_soc_add_controls(codec, wm8974_snd_controls,
639 ARRAY_SIZE(wm8974_snd_controls)); 641 ARRAY_SIZE(wm8974_snd_controls));
640 wm8974_add_widgets(codec); 642 wm8974_add_widgets(codec);
641 ret = snd_soc_init_card(socdev);
642 if (ret < 0) {
643 dev_err(codec->dev, "failed to register card: %d\n", ret);
644 goto card_err;
645 }
646 643
647 return ret; 644 return ret;
648 645
649card_err:
650 snd_soc_free_pcms(socdev);
651 snd_soc_dapm_free(socdev);
652pcm_err: 646pcm_err:
653 return ret; 647 return ret;
654} 648}
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index 3f530f8a972a..2862e4dced27 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -790,19 +790,9 @@ static int wm8988_probe(struct platform_device *pdev)
790 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets, 790 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets,
791 ARRAY_SIZE(wm8988_dapm_widgets)); 791 ARRAY_SIZE(wm8988_dapm_widgets));
792 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 792 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
793 snd_soc_dapm_new_widgets(codec);
794
795 ret = snd_soc_init_card(socdev);
796 if (ret < 0) {
797 dev_err(codec->dev, "failed to register card: %d\n", ret);
798 goto card_err;
799 }
800 793
801 return ret; 794 return ret;
802 795
803card_err:
804 snd_soc_free_pcms(socdev);
805 snd_soc_dapm_free(socdev);
806pcm_err: 796pcm_err:
807 return ret; 797 return ret;
808} 798}
@@ -944,21 +934,6 @@ static int wm8988_i2c_remove(struct i2c_client *client)
944 return 0; 934 return 0;
945} 935}
946 936
947#ifdef CONFIG_PM
948static int wm8988_i2c_suspend(struct i2c_client *client, pm_message_t msg)
949{
950 return snd_soc_suspend_device(&client->dev);
951}
952
953static int wm8988_i2c_resume(struct i2c_client *client)
954{
955 return snd_soc_resume_device(&client->dev);
956}
957#else
958#define wm8988_i2c_suspend NULL
959#define wm8988_i2c_resume NULL
960#endif
961
962static const struct i2c_device_id wm8988_i2c_id[] = { 937static const struct i2c_device_id wm8988_i2c_id[] = {
963 { "wm8988", 0 }, 938 { "wm8988", 0 },
964 { } 939 { }
@@ -972,8 +947,6 @@ static struct i2c_driver wm8988_i2c_driver = {
972 }, 947 },
973 .probe = wm8988_i2c_probe, 948 .probe = wm8988_i2c_probe,
974 .remove = wm8988_i2c_remove, 949 .remove = wm8988_i2c_remove,
975 .suspend = wm8988_i2c_suspend,
976 .resume = wm8988_i2c_resume,
977 .id_table = wm8988_i2c_id, 950 .id_table = wm8988_i2c_id,
978}; 951};
979#endif 952#endif
@@ -1006,21 +979,6 @@ static int __devexit wm8988_spi_remove(struct spi_device *spi)
1006 return 0; 979 return 0;
1007} 980}
1008 981
1009#ifdef CONFIG_PM
1010static int wm8988_spi_suspend(struct spi_device *spi, pm_message_t msg)
1011{
1012 return snd_soc_suspend_device(&spi->dev);
1013}
1014
1015static int wm8988_spi_resume(struct spi_device *spi)
1016{
1017 return snd_soc_resume_device(&spi->dev);
1018}
1019#else
1020#define wm8988_spi_suspend NULL
1021#define wm8988_spi_resume NULL
1022#endif
1023
1024static struct spi_driver wm8988_spi_driver = { 982static struct spi_driver wm8988_spi_driver = {
1025 .driver = { 983 .driver = {
1026 .name = "wm8988", 984 .name = "wm8988",
@@ -1029,8 +987,6 @@ static struct spi_driver wm8988_spi_driver = {
1029 }, 987 },
1030 .probe = wm8988_spi_probe, 988 .probe = wm8988_spi_probe,
1031 .remove = __devexit_p(wm8988_spi_remove), 989 .remove = __devexit_p(wm8988_spi_remove),
1032 .suspend = wm8988_spi_suspend,
1033 .resume = wm8988_spi_resume,
1034}; 990};
1035#endif 991#endif
1036 992
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 2d702db4131d..341481e0e830 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -920,7 +920,6 @@ static int wm8990_add_widgets(struct snd_soc_codec *codec)
920 /* set up the WM8990 audio map */ 920 /* set up the WM8990 audio map */
921 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 921 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
922 922
923 snd_soc_dapm_new_widgets(codec);
924 return 0; 923 return 0;
925} 924}
926 925
@@ -972,8 +971,8 @@ static void pll_factors(struct _pll_div *pll_div, unsigned int target,
972 pll_div->k = K; 971 pll_div->k = K;
973} 972}
974 973
975static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, 974static int wm8990_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
976 int pll_id, unsigned int freq_in, unsigned int freq_out) 975 int source, unsigned int freq_in, unsigned int freq_out)
977{ 976{
978 u16 reg; 977 u16 reg;
979 struct snd_soc_codec *codec = codec_dai->codec; 978 struct snd_soc_codec *codec = codec_dai->codec;
@@ -1409,16 +1408,9 @@ static int wm8990_init(struct snd_soc_device *socdev)
1409 snd_soc_add_controls(codec, wm8990_snd_controls, 1408 snd_soc_add_controls(codec, wm8990_snd_controls,
1410 ARRAY_SIZE(wm8990_snd_controls)); 1409 ARRAY_SIZE(wm8990_snd_controls));
1411 wm8990_add_widgets(codec); 1410 wm8990_add_widgets(codec);
1412 ret = snd_soc_init_card(socdev); 1411
1413 if (ret < 0) {
1414 printk(KERN_ERR "wm8990: failed to register card\n");
1415 goto card_err;
1416 }
1417 return ret; 1412 return ret;
1418 1413
1419card_err:
1420 snd_soc_free_pcms(socdev);
1421 snd_soc_dapm_free(socdev);
1422pcm_err: 1414pcm_err:
1423 kfree(codec->reg_cache); 1415 kfree(codec->reg_cache);
1424 return ret; 1416 return ret;
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index d9987999e92c..2981afae842c 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -422,7 +422,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
422 return 0; 422 return 0;
423} 423}
424 424
425static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, 425static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source,
426 unsigned int Fref, unsigned int Fout) 426 unsigned int Fref, unsigned int Fout)
427{ 427{
428 struct snd_soc_codec *codec = dai->codec; 428 struct snd_soc_codec *codec = dai->codec;
@@ -689,7 +689,7 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8993_DIGITAL_SIDE_TONE,
689 689
690SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0), 690SOC_SINGLE("DRC Switch", WM8993_DRC_CONTROL_1, 15, 1, 0),
691SOC_ENUM("DRC Path", drc_path), 691SOC_ENUM("DRC Path", drc_path),
692SOC_SINGLE_TLV("DRC Compressor Threashold Volume", WM8993_DRC_CONTROL_2, 692SOC_SINGLE_TLV("DRC Compressor Threshold Volume", WM8993_DRC_CONTROL_2,
693 2, 60, 1, drc_comp_threash), 693 2, 60, 1, drc_comp_threash),
694SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3, 694SOC_SINGLE_TLV("DRC Compressor Amplitude Volume", WM8993_DRC_CONTROL_3,
695 11, 30, 1, drc_comp_amp), 695 11, 30, 1, drc_comp_amp),
@@ -709,7 +709,7 @@ SOC_SINGLE_TLV("DRC Quick Release Volume", WM8993_DRC_CONTROL_3, 2, 3, 0,
709SOC_ENUM("DRC Quick Release Rate", drc_qr_rate), 709SOC_ENUM("DRC Quick Release Rate", drc_qr_rate),
710SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0), 710SOC_SINGLE("DRC Smoothing Switch", WM8993_DRC_CONTROL_1, 11, 1, 0),
711SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0), 711SOC_SINGLE("DRC Smoothing Hysteresis Switch", WM8993_DRC_CONTROL_1, 8, 1, 0),
712SOC_ENUM("DRC Smoothing Hysteresis Threashold", drc_smooth), 712SOC_ENUM("DRC Smoothing Hysteresis Threshold", drc_smooth),
713SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0, 713SOC_SINGLE_TLV("DRC Startup Volume", WM8993_DRC_CONTROL_4, 8, 18, 0,
714 drc_startup_tlv), 714 drc_startup_tlv),
715 715
@@ -1464,19 +1464,8 @@ static int wm8993_probe(struct platform_device *pdev)
1464 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, 1464 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1465 wm8993->pdata.lineout2_diff); 1465 wm8993->pdata.lineout2_diff);
1466 1466
1467 snd_soc_dapm_new_widgets(codec);
1468
1469 ret = snd_soc_init_card(socdev);
1470 if (ret < 0) {
1471 dev_err(codec->dev, "failed to register card\n");
1472 goto card_err;
1473 }
1474
1475 return ret; 1467 return ret;
1476 1468
1477card_err:
1478 snd_soc_free_pcms(socdev);
1479 snd_soc_dapm_free(socdev);
1480err: 1469err:
1481 return ret; 1470 return ret;
1482} 1471}
@@ -1572,33 +1561,15 @@ static int wm8993_i2c_probe(struct i2c_client *i2c,
1572 /* Use automatic clock configuration */ 1561 /* Use automatic clock configuration */
1573 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0); 1562 snd_soc_update_bits(codec, WM8993_CLOCKING_4, WM8993_SR_MODE, 0);
1574 1563
1575 if (!wm8993->pdata.lineout1_diff) 1564 wm_hubs_handle_analogue_pdata(codec, wm8993->pdata.lineout1_diff,
1576 snd_soc_update_bits(codec, WM8993_LINE_MIXER1, 1565 wm8993->pdata.lineout2_diff,
1577 WM8993_LINEOUT1_MODE, 1566 wm8993->pdata.lineout1fb,
1578 WM8993_LINEOUT1_MODE); 1567 wm8993->pdata.lineout2fb,
1579 if (!wm8993->pdata.lineout2_diff) 1568 wm8993->pdata.jd_scthr,
1580 snd_soc_update_bits(codec, WM8993_LINE_MIXER2, 1569 wm8993->pdata.jd_thr,
1581 WM8993_LINEOUT2_MODE, 1570 wm8993->pdata.micbias1_lvl,
1582 WM8993_LINEOUT2_MODE); 1571 wm8993->pdata.micbias2_lvl);
1583 1572
1584 if (wm8993->pdata.lineout1fb)
1585 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1586 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
1587
1588 if (wm8993->pdata.lineout2fb)
1589 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
1590 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
1591
1592 /* Apply the microphone bias/detection configuration - the
1593 * platform data is directly applicable to the register. */
1594 snd_soc_update_bits(codec, WM8993_MICBIAS,
1595 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
1596 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
1597 wm8993->pdata.jd_scthr << WM8993_JD_SCTHR_SHIFT |
1598 wm8993->pdata.jd_thr << WM8993_JD_THR_SHIFT |
1599 wm8993->pdata.micbias1_lvl |
1600 wm8993->pdata.micbias1_lvl << 1);
1601
1602 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1573 ret = wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1603 if (ret != 0) 1574 if (ret != 0)
1604 goto err; 1575 goto err;
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 686e5aa97206..c468497314ba 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -1262,19 +1262,9 @@ static int wm9081_probe(struct platform_device *pdev)
1262 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets, 1262 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets,
1263 ARRAY_SIZE(wm9081_dapm_widgets)); 1263 ARRAY_SIZE(wm9081_dapm_widgets));
1264 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 1264 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
1265 snd_soc_dapm_new_widgets(codec);
1266
1267 ret = snd_soc_init_card(socdev);
1268 if (ret < 0) {
1269 dev_err(codec->dev, "failed to register card: %d\n", ret);
1270 goto card_err;
1271 }
1272 1265
1273 return ret; 1266 return ret;
1274 1267
1275card_err:
1276 snd_soc_free_pcms(socdev);
1277 snd_soc_dapm_free(socdev);
1278pcm_err: 1268pcm_err:
1279 return ret; 1269 return ret;
1280} 1270}
@@ -1452,21 +1442,6 @@ static __devexit int wm9081_i2c_remove(struct i2c_client *client)
1452 return 0; 1442 return 0;
1453} 1443}
1454 1444
1455#ifdef CONFIG_PM
1456static int wm9081_i2c_suspend(struct i2c_client *client, pm_message_t msg)
1457{
1458 return snd_soc_suspend_device(&client->dev);
1459}
1460
1461static int wm9081_i2c_resume(struct i2c_client *client)
1462{
1463 return snd_soc_resume_device(&client->dev);
1464}
1465#else
1466#define wm9081_i2c_suspend NULL
1467#define wm9081_i2c_resume NULL
1468#endif
1469
1470static const struct i2c_device_id wm9081_i2c_id[] = { 1445static const struct i2c_device_id wm9081_i2c_id[] = {
1471 { "wm9081", 0 }, 1446 { "wm9081", 0 },
1472 { } 1447 { }
@@ -1480,8 +1455,6 @@ static struct i2c_driver wm9081_i2c_driver = {
1480 }, 1455 },
1481 .probe = wm9081_i2c_probe, 1456 .probe = wm9081_i2c_probe,
1482 .remove = __devexit_p(wm9081_i2c_remove), 1457 .remove = __devexit_p(wm9081_i2c_remove),
1483 .suspend = wm9081_i2c_suspend,
1484 .resume = wm9081_i2c_resume,
1485 .id_table = wm9081_i2c_id, 1458 .id_table = wm9081_i2c_id,
1486}; 1459};
1487 1460
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index e7d2840d9e59..ec54c6da9856 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -205,7 +205,6 @@ static int wm9705_add_widgets(struct snd_soc_codec *codec)
205 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets, 205 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets,
206 ARRAY_SIZE(wm9705_dapm_widgets)); 206 ARRAY_SIZE(wm9705_dapm_widgets));
207 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 207 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
208 snd_soc_dapm_new_widgets(codec);
209 208
210 return 0; 209 return 0;
211} 210}
@@ -403,12 +402,6 @@ static int wm9705_soc_probe(struct platform_device *pdev)
403 ARRAY_SIZE(wm9705_snd_ac97_controls)); 402 ARRAY_SIZE(wm9705_snd_ac97_controls));
404 wm9705_add_widgets(codec); 403 wm9705_add_widgets(codec);
405 404
406 ret = snd_soc_init_card(socdev);
407 if (ret < 0) {
408 printk(KERN_ERR "wm9705: failed to register card\n");
409 goto reset_err;
410 }
411
412 return 0; 405 return 0;
413 406
414reset_err: 407reset_err:
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index 1fd4e88f50cf..0ac1215dcd9b 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -436,7 +436,6 @@ static int wm9712_add_widgets(struct snd_soc_codec *codec)
436 436
437 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 437 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
438 438
439 snd_soc_dapm_new_widgets(codec);
440 return 0; 439 return 0;
441} 440}
442 441
@@ -695,17 +694,11 @@ static int wm9712_soc_probe(struct platform_device *pdev)
695 snd_soc_add_controls(codec, wm9712_snd_ac97_controls, 694 snd_soc_add_controls(codec, wm9712_snd_ac97_controls,
696 ARRAY_SIZE(wm9712_snd_ac97_controls)); 695 ARRAY_SIZE(wm9712_snd_ac97_controls));
697 wm9712_add_widgets(codec); 696 wm9712_add_widgets(codec);
698 ret = snd_soc_init_card(socdev);
699 if (ret < 0) {
700 printk(KERN_ERR "wm9712: failed to register card\n");
701 goto reset_err;
702 }
703 697
704 return 0; 698 return 0;
705 699
706reset_err: 700reset_err:
707 snd_soc_free_pcms(socdev); 701 snd_soc_free_pcms(socdev);
708
709pcm_err: 702pcm_err:
710 snd_soc_free_ac97_codec(codec); 703 snd_soc_free_ac97_codec(codec);
711 704
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 60e360b10468..c58aab375edb 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -625,7 +625,6 @@ static int wm9713_add_widgets(struct snd_soc_codec *codec)
625 625
626 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 626 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
627 627
628 snd_soc_dapm_new_widgets(codec);
629 return 0; 628 return 0;
630} 629}
631 630
@@ -800,8 +799,8 @@ static int wm9713_set_pll(struct snd_soc_codec *codec,
800 return 0; 799 return 0;
801} 800}
802 801
803static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, 802static int wm9713_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
804 int pll_id, unsigned int freq_in, unsigned int freq_out) 803 int source, unsigned int freq_in, unsigned int freq_out)
805{ 804{
806 struct snd_soc_codec *codec = codec_dai->codec; 805 struct snd_soc_codec *codec = codec_dai->codec;
807 return wm9713_set_pll(codec, pll_id, freq_in, freq_out); 806 return wm9713_set_pll(codec, pll_id, freq_in, freq_out);
@@ -1247,14 +1246,11 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1247 snd_soc_add_controls(codec, wm9713_snd_ac97_controls, 1246 snd_soc_add_controls(codec, wm9713_snd_ac97_controls,
1248 ARRAY_SIZE(wm9713_snd_ac97_controls)); 1247 ARRAY_SIZE(wm9713_snd_ac97_controls));
1249 wm9713_add_widgets(codec); 1248 wm9713_add_widgets(codec);
1250 ret = snd_soc_init_card(socdev); 1249
1251 if (ret < 0)
1252 goto reset_err;
1253 return 0; 1250 return 0;
1254 1251
1255reset_err: 1252reset_err:
1256 snd_soc_free_pcms(socdev); 1253 snd_soc_free_pcms(socdev);
1257
1258pcm_err: 1254pcm_err:
1259 snd_soc_free_ac97_codec(codec); 1255 snd_soc_free_ac97_codec(codec);
1260 1256
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index e542027eea89..d73c30536a2c 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -438,11 +438,11 @@ static const struct snd_soc_dapm_widget analogue_dapm_widgets[] = {
438SND_SOC_DAPM_INPUT("IN1LN"), 438SND_SOC_DAPM_INPUT("IN1LN"),
439SND_SOC_DAPM_INPUT("IN1LP"), 439SND_SOC_DAPM_INPUT("IN1LP"),
440SND_SOC_DAPM_INPUT("IN2LN"), 440SND_SOC_DAPM_INPUT("IN2LN"),
441SND_SOC_DAPM_INPUT("IN2LP/VXRN"), 441SND_SOC_DAPM_INPUT("IN2LP:VXRN"),
442SND_SOC_DAPM_INPUT("IN1RN"), 442SND_SOC_DAPM_INPUT("IN1RN"),
443SND_SOC_DAPM_INPUT("IN1RP"), 443SND_SOC_DAPM_INPUT("IN1RP"),
444SND_SOC_DAPM_INPUT("IN2RN"), 444SND_SOC_DAPM_INPUT("IN2RN"),
445SND_SOC_DAPM_INPUT("IN2RP/VXRP"), 445SND_SOC_DAPM_INPUT("IN2RP:VXRP"),
446 446
447SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0), 447SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8993_POWER_MANAGEMENT_1, 5, 0),
448SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0), 448SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8993_POWER_MANAGEMENT_1, 4, 0),
@@ -537,14 +537,14 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
537 { "IN1R PGA", "IN1RP Switch", "IN1RP" }, 537 { "IN1R PGA", "IN1RP Switch", "IN1RP" },
538 { "IN1R PGA", "IN1RN Switch", "IN1RN" }, 538 { "IN1R PGA", "IN1RN Switch", "IN1RN" },
539 539
540 { "IN2L PGA", "IN2LP Switch", "IN2LP/VXRN" }, 540 { "IN2L PGA", "IN2LP Switch", "IN2LP:VXRN" },
541 { "IN2L PGA", "IN2LN Switch", "IN2LN" }, 541 { "IN2L PGA", "IN2LN Switch", "IN2LN" },
542 542
543 { "IN2R PGA", "IN2RP Switch", "IN2RP/VXRP" }, 543 { "IN2R PGA", "IN2RP Switch", "IN2RP:VXRP" },
544 { "IN2R PGA", "IN2RN Switch", "IN2RN" }, 544 { "IN2R PGA", "IN2RN Switch", "IN2RN" },
545 545
546 { "Direct Voice", NULL, "IN2LP/VXRN" }, 546 { "Direct Voice", NULL, "IN2LP:VXRN" },
547 { "Direct Voice", NULL, "IN2RP/VXRP" }, 547 { "Direct Voice", NULL, "IN2RP:VXRP" },
548 548
549 { "MIXINL", "IN1L Switch", "IN1L PGA" }, 549 { "MIXINL", "IN1L Switch", "IN1L PGA" },
550 { "MIXINL", "IN2L Switch", "IN2L PGA" }, 550 { "MIXINL", "IN2L Switch", "IN2L PGA" },
@@ -565,7 +565,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
565 { "Left Output Mixer", "Right Input Switch", "MIXINR" }, 565 { "Left Output Mixer", "Right Input Switch", "MIXINR" },
566 { "Left Output Mixer", "IN2RN Switch", "IN2RN" }, 566 { "Left Output Mixer", "IN2RN Switch", "IN2RN" },
567 { "Left Output Mixer", "IN2LN Switch", "IN2LN" }, 567 { "Left Output Mixer", "IN2LN Switch", "IN2LN" },
568 { "Left Output Mixer", "IN2LP Switch", "IN2LP/VXRN" }, 568 { "Left Output Mixer", "IN2LP Switch", "IN2LP:VXRN" },
569 { "Left Output Mixer", "IN1L Switch", "IN1L PGA" }, 569 { "Left Output Mixer", "IN1L Switch", "IN1L PGA" },
570 { "Left Output Mixer", "IN1R Switch", "IN1R PGA" }, 570 { "Left Output Mixer", "IN1R Switch", "IN1R PGA" },
571 571
@@ -573,7 +573,7 @@ static const struct snd_soc_dapm_route analogue_routes[] = {
573 { "Right Output Mixer", "Right Input Switch", "MIXINR" }, 573 { "Right Output Mixer", "Right Input Switch", "MIXINR" },
574 { "Right Output Mixer", "IN2LN Switch", "IN2LN" }, 574 { "Right Output Mixer", "IN2LN Switch", "IN2LN" },
575 { "Right Output Mixer", "IN2RN Switch", "IN2RN" }, 575 { "Right Output Mixer", "IN2RN Switch", "IN2RN" },
576 { "Right Output Mixer", "IN2RP Switch", "IN2RP/VXRP" }, 576 { "Right Output Mixer", "IN2RP Switch", "IN2RP:VXRP" },
577 { "Right Output Mixer", "IN1L Switch", "IN1L PGA" }, 577 { "Right Output Mixer", "IN1L Switch", "IN1L PGA" },
578 { "Right Output Mixer", "IN1R Switch", "IN1R PGA" }, 578 { "Right Output Mixer", "IN1R Switch", "IN1R PGA" },
579 579
@@ -738,6 +738,41 @@ int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
738} 738}
739EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes); 739EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_routes);
740 740
741int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
742 int lineout1_diff, int lineout2_diff,
743 int lineout1fb, int lineout2fb,
744 int jd_scthr, int jd_thr, int micbias1_lvl,
745 int micbias2_lvl)
746{
747 if (!lineout1_diff)
748 snd_soc_update_bits(codec, WM8993_LINE_MIXER1,
749 WM8993_LINEOUT1_MODE,
750 WM8993_LINEOUT1_MODE);
751 if (!lineout2_diff)
752 snd_soc_update_bits(codec, WM8993_LINE_MIXER2,
753 WM8993_LINEOUT2_MODE,
754 WM8993_LINEOUT2_MODE);
755
756 if (lineout1fb)
757 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
758 WM8993_LINEOUT1_FB, WM8993_LINEOUT1_FB);
759
760 if (lineout2fb)
761 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
762 WM8993_LINEOUT2_FB, WM8993_LINEOUT2_FB);
763
764 snd_soc_update_bits(codec, WM8993_MICBIAS,
765 WM8993_JD_SCTHR_MASK | WM8993_JD_THR_MASK |
766 WM8993_MICB1_LVL | WM8993_MICB2_LVL,
767 jd_scthr << WM8993_JD_SCTHR_SHIFT |
768 jd_thr << WM8993_JD_THR_SHIFT |
769 micbias1_lvl |
770 micbias2_lvl << WM8993_MICB2_LVL_SHIFT);
771
772 return 0;
773}
774EXPORT_SYMBOL_GPL(wm_hubs_handle_analogue_pdata);
775
741MODULE_DESCRIPTION("Shared support for Wolfson hubs products"); 776MODULE_DESCRIPTION("Shared support for Wolfson hubs products");
742MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 777MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
743MODULE_LICENSE("GPL"); 778MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index ec09cb6a2939..36d3fba1de8b 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -20,5 +20,10 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
20 20
21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 21extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int); 22extern int wm_hubs_add_analogue_routes(struct snd_soc_codec *, int, int);
23extern int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *,
24 int lineout1_diff, int lineout2_diff,
25 int lineout1fb, int lineout2fb,
26 int jd_scthr, int jd_thr,
27 int micbias1_lvl, int micbias2_lvl);
23 28
24#endif 29#endif
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 4dfd4ad9d90e..047ee39418c0 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -13,9 +13,9 @@ config SND_DAVINCI_SOC_MCASP
13 tristate 13 tristate
14 14
15config SND_DAVINCI_SOC_EVM 15config SND_DAVINCI_SOC_EVM
16 tristate "SoC Audio support for DaVinci DM6446 or DM355 EVM" 16 tristate "SoC Audio support for DaVinci DM6446, DM355 or DM365 EVM"
17 depends on SND_DAVINCI_SOC 17 depends on SND_DAVINCI_SOC
18 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM 18 depends on MACH_DAVINCI_EVM || MACH_DAVINCI_DM355_EVM || MACH_DAVINCI_DM365_EVM
19 select SND_DAVINCI_SOC_I2S 19 select SND_DAVINCI_SOC_I2S
20 select SND_SOC_TLV320AIC3X 20 select SND_SOC_TLV320AIC3X
21 help 21 help
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 67414f659405..7ccbe6684fc2 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -45,7 +45,8 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
45 unsigned sysclk; 45 unsigned sysclk;
46 46
47 /* ASP1 on DM355 EVM is clocked by an external oscillator */ 47 /* ASP1 on DM355 EVM is clocked by an external oscillator */
48 if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm()) 48 if (machine_is_davinci_dm355_evm() || machine_is_davinci_dm6467_evm() ||
49 machine_is_davinci_dm365_evm())
49 sysclk = 27000000; 50 sysclk = 27000000;
50 51
51 /* ASP0 in DM6446 EVM is clocked by U55, as configured by 52 /* ASP0 in DM6446 EVM is clocked by U55, as configured by
@@ -176,7 +177,7 @@ static struct snd_soc_dai_link da8xx_evm_dai = {
176 .ops = &evm_ops, 177 .ops = &evm_ops,
177}; 178};
178 179
179/* davinci-evm audio machine driver */ 180/* davinci dm6446, dm355 or dm365 evm audio machine driver */
180static struct snd_soc_card snd_soc_card_evm = { 181static struct snd_soc_card snd_soc_card_evm = {
181 .name = "DaVinci EVM", 182 .name = "DaVinci EVM",
182 .platform = &davinci_soc_platform, 183 .platform = &davinci_soc_platform,
@@ -243,7 +244,7 @@ static int __init evm_init(void)
243 int index; 244 int index;
244 int ret; 245 int ret;
245 246
246 if (machine_is_davinci_evm()) { 247 if (machine_is_davinci_evm() || machine_is_davinci_dm365_evm()) {
247 evm_snd_dev_data = &evm_snd_devdata; 248 evm_snd_dev_data = &evm_snd_devdata;
248 index = 0; 249 index = 0;
249 } else if (machine_is_davinci_dm355_evm()) { 250 } else if (machine_is_davinci_dm355_evm()) {
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index 4ae707048021..6362ca05506e 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -97,12 +97,24 @@ enum {
97 DAVINCI_MCBSP_WORD_32, 97 DAVINCI_MCBSP_WORD_32,
98}; 98};
99 99
100static const unsigned char data_type[SNDRV_PCM_FORMAT_S32_LE + 1] = {
101 [SNDRV_PCM_FORMAT_S8] = 1,
102 [SNDRV_PCM_FORMAT_S16_LE] = 2,
103 [SNDRV_PCM_FORMAT_S32_LE] = 4,
104};
105
106static const unsigned char asp_word_length[SNDRV_PCM_FORMAT_S32_LE + 1] = {
107 [SNDRV_PCM_FORMAT_S8] = DAVINCI_MCBSP_WORD_8,
108 [SNDRV_PCM_FORMAT_S16_LE] = DAVINCI_MCBSP_WORD_16,
109 [SNDRV_PCM_FORMAT_S32_LE] = DAVINCI_MCBSP_WORD_32,
110};
111
112static const unsigned char double_fmt[SNDRV_PCM_FORMAT_S32_LE + 1] = {
113 [SNDRV_PCM_FORMAT_S8] = SNDRV_PCM_FORMAT_S16_LE,
114 [SNDRV_PCM_FORMAT_S16_LE] = SNDRV_PCM_FORMAT_S32_LE,
115};
116
100struct davinci_mcbsp_dev { 117struct davinci_mcbsp_dev {
101 /*
102 * dma_params must be first because rtd->dai->cpu_dai->private_data
103 * is cast to a pointer of an array of struct davinci_pcm_dma_params in
104 * davinci_pcm_open.
105 */
106 struct davinci_pcm_dma_params dma_params[2]; 118 struct davinci_pcm_dma_params dma_params[2];
107 void __iomem *base; 119 void __iomem *base;
108#define MOD_DSP_A 0 120#define MOD_DSP_A 0
@@ -110,6 +122,27 @@ struct davinci_mcbsp_dev {
110 int mode; 122 int mode;
111 u32 pcr; 123 u32 pcr;
112 struct clk *clk; 124 struct clk *clk;
125 /*
126 * Combining both channels into 1 element will at least double the
127 * amount of time between servicing the dma channel, increase
128 * effiency, and reduce the chance of overrun/underrun. But,
129 * it will result in the left & right channels being swapped.
130 *
131 * If relabeling the left and right channels is not possible,
132 * you may want to let the codec know to swap them back.
133 *
134 * It may allow x10 the amount of time to service dma requests,
135 * if the codec is master and is using an unnecessarily fast bit clock
136 * (ie. tlvaic23b), independent of the sample rate. So, having an
137 * entire frame at once means it can be serviced at the sample rate
138 * instead of the bit clock rate.
139 *
140 * In the now unlikely case that an underrun still
141 * occurs, both the left and right samples will be repeated
142 * so that no pops are heard, and the left and right channels
143 * won't end up being swapped because of the underrun.
144 */
145 unsigned enable_channel_combine:1;
113}; 146};
114 147
115static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev, 148static inline void davinci_mcbsp_write_reg(struct davinci_mcbsp_dev *dev,
@@ -349,6 +382,8 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
349 int mcbsp_word_length; 382 int mcbsp_word_length;
350 unsigned int rcr, xcr, srgr; 383 unsigned int rcr, xcr, srgr;
351 u32 spcr; 384 u32 spcr;
385 snd_pcm_format_t fmt;
386 unsigned element_cnt = 1;
352 387
353 /* general line settings */ 388 /* general line settings */
354 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 389 spcr = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
@@ -378,27 +413,24 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
378 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1); 413 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
379 } 414 }
380 /* Determine xfer data type */ 415 /* Determine xfer data type */
381 switch (params_format(params)) { 416 fmt = params_format(params);
382 case SNDRV_PCM_FORMAT_S8: 417 if ((fmt > SNDRV_PCM_FORMAT_S32_LE) || !data_type[fmt]) {
383 dma_params->data_type = 1;
384 mcbsp_word_length = DAVINCI_MCBSP_WORD_8;
385 break;
386 case SNDRV_PCM_FORMAT_S16_LE:
387 dma_params->data_type = 2;
388 mcbsp_word_length = DAVINCI_MCBSP_WORD_16;
389 break;
390 case SNDRV_PCM_FORMAT_S32_LE:
391 dma_params->data_type = 4;
392 mcbsp_word_length = DAVINCI_MCBSP_WORD_32;
393 break;
394 default:
395 printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n"); 418 printk(KERN_WARNING "davinci-i2s: unsupported PCM format\n");
396 return -EINVAL; 419 return -EINVAL;
397 } 420 }
398 421
399 dma_params->acnt = dma_params->data_type; 422 if (params_channels(params) == 2) {
400 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(1); 423 element_cnt = 2;
401 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(1); 424 if (double_fmt[fmt] && dev->enable_channel_combine) {
425 element_cnt = 1;
426 fmt = double_fmt[fmt];
427 }
428 }
429 dma_params->acnt = dma_params->data_type = data_type[fmt];
430 dma_params->fifo_level = 0;
431 mcbsp_word_length = asp_word_length[fmt];
432 rcr |= DAVINCI_MCBSP_RCR_RFRLEN1(element_cnt - 1);
433 xcr |= DAVINCI_MCBSP_XCR_XFRLEN1(element_cnt - 1);
402 434
403 rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) | 435 rcr |= DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
404 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length); 436 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length);
@@ -513,7 +545,13 @@ static int davinci_i2s_probe(struct platform_device *pdev)
513 ret = -ENOMEM; 545 ret = -ENOMEM;
514 goto err_release_region; 546 goto err_release_region;
515 } 547 }
516 548 if (pdata) {
549 dev->enable_channel_combine = pdata->enable_channel_combine;
550 dev->dma_params[SNDRV_PCM_STREAM_PLAYBACK].sram_size =
551 pdata->sram_size_playback;
552 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].sram_size =
553 pdata->sram_size_capture;
554 }
517 dev->clk = clk_get(&pdev->dev, NULL); 555 dev->clk = clk_get(&pdev->dev, NULL);
518 if (IS_ERR(dev->clk)) { 556 if (IS_ERR(dev->clk)) {
519 ret = -ENODEV; 557 ret = -ENODEV;
@@ -547,6 +585,7 @@ static int davinci_i2s_probe(struct platform_device *pdev)
547 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; 585 dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
548 586
549 davinci_i2s_dai.private_data = dev; 587 davinci_i2s_dai.private_data = dev;
588 davinci_i2s_dai.dma_data = dev->dma_params;
550 ret = snd_soc_register_dai(&davinci_i2s_dai); 589 ret = snd_soc_register_dai(&davinci_i2s_dai);
551 if (ret != 0) 590 if (ret != 0)
552 goto err_free_mem; 591 goto err_free_mem;
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c
index 5d1f98a4c978..0a302e1080d9 100644
--- a/sound/soc/davinci/davinci-mcasp.c
+++ b/sound/soc/davinci/davinci-mcasp.c
@@ -714,16 +714,13 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
714 struct davinci_pcm_dma_params *dma_params = 714 struct davinci_pcm_dma_params *dma_params =
715 &dev->dma_params[substream->stream]; 715 &dev->dma_params[substream->stream];
716 int word_length; 716 int word_length;
717 u8 numevt; 717 u8 fifo_level;
718 718
719 davinci_hw_common_param(dev, substream->stream); 719 davinci_hw_common_param(dev, substream->stream);
720 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 720 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
721 numevt = dev->txnumevt; 721 fifo_level = dev->txnumevt;
722 else 722 else
723 numevt = dev->rxnumevt; 723 fifo_level = dev->rxnumevt;
724
725 if (!numevt)
726 numevt = 1;
727 724
728 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE) 725 if (dev->op_mode == DAVINCI_MCASP_DIT_MODE)
729 davinci_hw_dit_param(dev); 726 davinci_hw_dit_param(dev);
@@ -751,12 +748,12 @@ static int davinci_mcasp_hw_params(struct snd_pcm_substream *substream,
751 return -EINVAL; 748 return -EINVAL;
752 } 749 }
753 750
754 if (dev->version == MCASP_VERSION_2) { 751 if (dev->version == MCASP_VERSION_2 && !fifo_level)
755 dma_params->data_type *= numevt; 752 dma_params->acnt = 4;
756 dma_params->acnt = 4 * numevt; 753 else
757 } else
758 dma_params->acnt = dma_params->data_type; 754 dma_params->acnt = dma_params->data_type;
759 755
756 dma_params->fifo_level = fifo_level;
760 davinci_config_channel_size(dev, word_length); 757 davinci_config_channel_size(dev, word_length);
761 758
762 return 0; 759 return 0;
@@ -907,6 +904,7 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
907 904
908 dma_data->channel = res->start; 905 dma_data->channel = res->start;
909 davinci_mcasp_dai[pdata->op_mode].private_data = dev; 906 davinci_mcasp_dai[pdata->op_mode].private_data = dev;
907 davinci_mcasp_dai[pdata->op_mode].dma_data = dev->dma_params;
910 davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; 908 davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
911 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); 909 ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
912 910
diff --git a/sound/soc/davinci/davinci-mcasp.h b/sound/soc/davinci/davinci-mcasp.h
index 9d179cc88f7b..582c9249ef09 100644
--- a/sound/soc/davinci/davinci-mcasp.h
+++ b/sound/soc/davinci/davinci-mcasp.h
@@ -39,11 +39,6 @@ enum {
39}; 39};
40 40
41struct davinci_audio_dev { 41struct davinci_audio_dev {
42 /*
43 * dma_params must be first because rtd->dai->cpu_dai->private_data
44 * is cast to a pointer of an array of struct davinci_pcm_dma_params in
45 * davinci_pcm_open.
46 */
47 struct davinci_pcm_dma_params dma_params[2]; 42 struct davinci_pcm_dma_params dma_params[2];
48 void __iomem *base; 43 void __iomem *base;
49 int sample_rate; 44 int sample_rate;
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index c73a915f233f..ad4d7f47a86b 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com> 4 * Author: Vladimir Barinov, <vbarinov@embeddedalley.com>
5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com> 5 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
6 * added SRAM ping/pong (C) 2008 Troy Kisky <troy.kisky@boundarydevices.com>
6 * 7 *
7 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -23,10 +24,29 @@
23 24
24#include <asm/dma.h> 25#include <asm/dma.h>
25#include <mach/edma.h> 26#include <mach/edma.h>
27#include <mach/sram.h>
26 28
27#include "davinci-pcm.h" 29#include "davinci-pcm.h"
28 30
29static struct snd_pcm_hardware davinci_pcm_hardware = { 31#ifdef DEBUG
32static void print_buf_info(int slot, char *name)
33{
34 struct edmacc_param p;
35 if (slot < 0)
36 return;
37 edma_read_slot(slot, &p);
38 printk(KERN_DEBUG "%s: 0x%x, opt=%x, src=%x, a_b_cnt=%x dst=%x\n",
39 name, slot, p.opt, p.src, p.a_b_cnt, p.dst);
40 printk(KERN_DEBUG " src_dst_bidx=%x link_bcntrld=%x src_dst_cidx=%x ccnt=%x\n",
41 p.src_dst_bidx, p.link_bcntrld, p.src_dst_cidx, p.ccnt);
42}
43#else
44static void print_buf_info(int slot, char *name)
45{
46}
47#endif
48
49static struct snd_pcm_hardware pcm_hardware_playback = {
30 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 50 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
31 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 51 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
32 SNDRV_PCM_INFO_PAUSE), 52 SNDRV_PCM_INFO_PAUSE),
@@ -48,102 +68,432 @@ static struct snd_pcm_hardware davinci_pcm_hardware = {
48 .fifo_size = 0, 68 .fifo_size = 0,
49}; 69};
50 70
71static struct snd_pcm_hardware pcm_hardware_capture = {
72 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
73 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
74 SNDRV_PCM_INFO_PAUSE),
75 .formats = (SNDRV_PCM_FMTBIT_S16_LE),
76 .rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |
77 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 |
78 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
79 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
80 SNDRV_PCM_RATE_KNOT),
81 .rate_min = 8000,
82 .rate_max = 96000,
83 .channels_min = 2,
84 .channels_max = 2,
85 .buffer_bytes_max = 128 * 1024,
86 .period_bytes_min = 32,
87 .period_bytes_max = 8 * 1024,
88 .periods_min = 16,
89 .periods_max = 255,
90 .fifo_size = 0,
91};
92
93/*
94 * How ping/pong works....
95 *
96 * Playback:
97 * ram_params - copys 2*ping_size from start of SDRAM to iram,
98 * links to ram_link2
99 * ram_link2 - copys rest of SDRAM to iram in ping_size units,
100 * links to ram_link
101 * ram_link - copys entire SDRAM to iram in ping_size uints,
102 * links to self
103 *
104 * asp_params - same as asp_link[0]
105 * asp_link[0] - copys from lower half of iram to asp port
106 * links to asp_link[1], triggers iram copy event on completion
107 * asp_link[1] - copys from upper half of iram to asp port
108 * links to asp_link[0], triggers iram copy event on completion
109 * triggers interrupt only needed to let upper SOC levels update position
110 * in stream on completion
111 *
112 * When playback is started:
113 * ram_params started
114 * asp_params started
115 *
116 * Capture:
117 * ram_params - same as ram_link,
118 * links to ram_link
119 * ram_link - same as playback
120 * links to self
121 *
122 * asp_params - same as playback
123 * asp_link[0] - same as playback
124 * asp_link[1] - same as playback
125 *
126 * When capture is started:
127 * asp_params started
128 */
51struct davinci_runtime_data { 129struct davinci_runtime_data {
52 spinlock_t lock; 130 spinlock_t lock;
53 int period; /* current DMA period */ 131 int period; /* current DMA period */
54 int master_lch; /* Master DMA channel */ 132 int asp_channel; /* Master DMA channel */
55 int slave_lch; /* linked parameter RAM reload slot */ 133 int asp_link[2]; /* asp parameter link channel, ping/pong */
56 struct davinci_pcm_dma_params *params; /* DMA params */ 134 struct davinci_pcm_dma_params *params; /* DMA params */
135 int ram_channel;
136 int ram_link;
137 int ram_link2;
138 struct edmacc_param asp_params;
139 struct edmacc_param ram_params;
57}; 140};
58 141
142/*
143 * Not used with ping/pong
144 */
59static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream) 145static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
60{ 146{
61 struct davinci_runtime_data *prtd = substream->runtime->private_data; 147 struct davinci_runtime_data *prtd = substream->runtime->private_data;
62 struct snd_pcm_runtime *runtime = substream->runtime; 148 struct snd_pcm_runtime *runtime = substream->runtime;
63 int lch = prtd->slave_lch; 149 int link = prtd->asp_link[0];
64 unsigned int period_size; 150 unsigned int period_size;
65 unsigned int dma_offset; 151 unsigned int dma_offset;
66 dma_addr_t dma_pos; 152 dma_addr_t dma_pos;
67 dma_addr_t src, dst; 153 dma_addr_t src, dst;
68 unsigned short src_bidx, dst_bidx; 154 unsigned short src_bidx, dst_bidx;
155 unsigned short src_cidx, dst_cidx;
69 unsigned int data_type; 156 unsigned int data_type;
70 unsigned short acnt; 157 unsigned short acnt;
71 unsigned int count; 158 unsigned int count;
159 unsigned int fifo_level;
72 160
73 period_size = snd_pcm_lib_period_bytes(substream); 161 period_size = snd_pcm_lib_period_bytes(substream);
74 dma_offset = prtd->period * period_size; 162 dma_offset = prtd->period * period_size;
75 dma_pos = runtime->dma_addr + dma_offset; 163 dma_pos = runtime->dma_addr + dma_offset;
164 fifo_level = prtd->params->fifo_level;
76 165
77 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d " 166 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
78 "dma_ptr = %x period_size=%x\n", lch, dma_pos, period_size); 167 "dma_ptr = %x period_size=%x\n", link, dma_pos, period_size);
79 168
80 data_type = prtd->params->data_type; 169 data_type = prtd->params->data_type;
81 count = period_size / data_type; 170 count = period_size / data_type;
171 if (fifo_level)
172 count /= fifo_level;
82 173
83 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 174 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
84 src = dma_pos; 175 src = dma_pos;
85 dst = prtd->params->dma_addr; 176 dst = prtd->params->dma_addr;
86 src_bidx = data_type; 177 src_bidx = data_type;
87 dst_bidx = 0; 178 dst_bidx = 0;
179 src_cidx = data_type * fifo_level;
180 dst_cidx = 0;
88 } else { 181 } else {
89 src = prtd->params->dma_addr; 182 src = prtd->params->dma_addr;
90 dst = dma_pos; 183 dst = dma_pos;
91 src_bidx = 0; 184 src_bidx = 0;
92 dst_bidx = data_type; 185 dst_bidx = data_type;
186 src_cidx = 0;
187 dst_cidx = data_type * fifo_level;
93 } 188 }
94 189
95 acnt = prtd->params->acnt; 190 acnt = prtd->params->acnt;
96 edma_set_src(lch, src, INCR, W8BIT); 191 edma_set_src(link, src, INCR, W8BIT);
97 edma_set_dest(lch, dst, INCR, W8BIT); 192 edma_set_dest(link, dst, INCR, W8BIT);
98 edma_set_src_index(lch, src_bidx, 0); 193
99 edma_set_dest_index(lch, dst_bidx, 0); 194 edma_set_src_index(link, src_bidx, src_cidx);
100 edma_set_transfer_params(lch, acnt, count, 1, 0, ASYNC); 195 edma_set_dest_index(link, dst_bidx, dst_cidx);
196
197 if (!fifo_level)
198 edma_set_transfer_params(link, acnt, count, 1, 0, ASYNC);
199 else
200 edma_set_transfer_params(link, acnt, fifo_level, count,
201 fifo_level, ABSYNC);
101 202
102 prtd->period++; 203 prtd->period++;
103 if (unlikely(prtd->period >= runtime->periods)) 204 if (unlikely(prtd->period >= runtime->periods))
104 prtd->period = 0; 205 prtd->period = 0;
105} 206}
106 207
107static void davinci_pcm_dma_irq(unsigned lch, u16 ch_status, void *data) 208static void davinci_pcm_dma_irq(unsigned link, u16 ch_status, void *data)
108{ 209{
109 struct snd_pcm_substream *substream = data; 210 struct snd_pcm_substream *substream = data;
110 struct davinci_runtime_data *prtd = substream->runtime->private_data; 211 struct davinci_runtime_data *prtd = substream->runtime->private_data;
111 212
112 pr_debug("davinci_pcm: lch=%d, status=0x%x\n", lch, ch_status); 213 print_buf_info(prtd->ram_channel, "i ram_channel");
214 pr_debug("davinci_pcm: link=%d, status=0x%x\n", link, ch_status);
113 215
114 if (unlikely(ch_status != DMA_COMPLETE)) 216 if (unlikely(ch_status != DMA_COMPLETE))
115 return; 217 return;
116 218
117 if (snd_pcm_running(substream)) { 219 if (snd_pcm_running(substream)) {
220 if (prtd->ram_channel < 0) {
221 /* No ping/pong must fix up link dma data*/
222 spin_lock(&prtd->lock);
223 davinci_pcm_enqueue_dma(substream);
224 spin_unlock(&prtd->lock);
225 }
118 snd_pcm_period_elapsed(substream); 226 snd_pcm_period_elapsed(substream);
227 }
228}
229
230static int allocate_sram(struct snd_pcm_substream *substream, unsigned size,
231 struct snd_pcm_hardware *ppcm)
232{
233 struct snd_dma_buffer *buf = &substream->dma_buffer;
234 struct snd_dma_buffer *iram_dma = NULL;
235 dma_addr_t iram_phys = 0;
236 void *iram_virt = NULL;
237
238 if (buf->private_data || !size)
239 return 0;
240
241 ppcm->period_bytes_max = size;
242 iram_virt = sram_alloc(size, &iram_phys);
243 if (!iram_virt)
244 goto exit1;
245 iram_dma = kzalloc(sizeof(*iram_dma), GFP_KERNEL);
246 if (!iram_dma)
247 goto exit2;
248 iram_dma->area = iram_virt;
249 iram_dma->addr = iram_phys;
250 memset(iram_dma->area, 0, size);
251 iram_dma->bytes = size;
252 buf->private_data = iram_dma;
253 return 0;
254exit2:
255 if (iram_virt)
256 sram_free(iram_virt, size);
257exit1:
258 return -ENOMEM;
259}
260
261/*
262 * Only used with ping/pong.
263 * This is called after runtime->dma_addr, period_bytes and data_type are valid
264 */
265static int ping_pong_dma_setup(struct snd_pcm_substream *substream)
266{
267 unsigned short ram_src_cidx, ram_dst_cidx;
268 struct snd_pcm_runtime *runtime = substream->runtime;
269 struct davinci_runtime_data *prtd = runtime->private_data;
270 struct snd_dma_buffer *iram_dma =
271 (struct snd_dma_buffer *)substream->dma_buffer.private_data;
272 struct davinci_pcm_dma_params *params = prtd->params;
273 unsigned int data_type = params->data_type;
274 unsigned int acnt = params->acnt;
275 /* divide by 2 for ping/pong */
276 unsigned int ping_size = snd_pcm_lib_period_bytes(substream) >> 1;
277 int link = prtd->asp_link[1];
278 unsigned int fifo_level = prtd->params->fifo_level;
279 unsigned int count;
280 if ((data_type == 0) || (data_type > 4)) {
281 printk(KERN_ERR "%s: data_type=%i\n", __func__, data_type);
282 return -EINVAL;
283 }
284 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
285 dma_addr_t asp_src_pong = iram_dma->addr + ping_size;
286 ram_src_cidx = ping_size;
287 ram_dst_cidx = -ping_size;
288 edma_set_src(link, asp_src_pong, INCR, W8BIT);
289
290 link = prtd->asp_link[0];
291 edma_set_src_index(link, data_type, data_type * fifo_level);
292 link = prtd->asp_link[1];
293 edma_set_src_index(link, data_type, data_type * fifo_level);
294
295 link = prtd->ram_link;
296 edma_set_src(link, runtime->dma_addr, INCR, W32BIT);
297 } else {
298 dma_addr_t asp_dst_pong = iram_dma->addr + ping_size;
299 ram_src_cidx = -ping_size;
300 ram_dst_cidx = ping_size;
301 edma_set_dest(link, asp_dst_pong, INCR, W8BIT);
302
303 link = prtd->asp_link[0];
304 edma_set_dest_index(link, data_type, data_type * fifo_level);
305 link = prtd->asp_link[1];
306 edma_set_dest_index(link, data_type, data_type * fifo_level);
307
308 link = prtd->ram_link;
309 edma_set_dest(link, runtime->dma_addr, INCR, W32BIT);
310 }
119 311
120 spin_lock(&prtd->lock); 312 if (!fifo_level) {
121 davinci_pcm_enqueue_dma(substream); 313 count = ping_size / data_type;
122 spin_unlock(&prtd->lock); 314 edma_set_transfer_params(prtd->asp_link[0], acnt, count,
315 1, 0, ASYNC);
316 edma_set_transfer_params(prtd->asp_link[1], acnt, count,
317 1, 0, ASYNC);
318 } else {
319 count = ping_size / (data_type * fifo_level);
320 edma_set_transfer_params(prtd->asp_link[0], acnt, fifo_level,
321 count, fifo_level, ABSYNC);
322 edma_set_transfer_params(prtd->asp_link[1], acnt, fifo_level,
323 count, fifo_level, ABSYNC);
123 } 324 }
325
326 link = prtd->ram_link;
327 edma_set_src_index(link, ping_size, ram_src_cidx);
328 edma_set_dest_index(link, ping_size, ram_dst_cidx);
329 edma_set_transfer_params(link, ping_size, 2,
330 runtime->periods, 2, ASYNC);
331
332 /* init master params */
333 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
334 edma_read_slot(prtd->ram_link, &prtd->ram_params);
335 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
336 struct edmacc_param p_ram;
337 /* Copy entire iram buffer before playback started */
338 prtd->ram_params.a_b_cnt = (1 << 16) | (ping_size << 1);
339 /* 0 dst_bidx */
340 prtd->ram_params.src_dst_bidx = (ping_size << 1);
341 /* 0 dst_cidx */
342 prtd->ram_params.src_dst_cidx = (ping_size << 1);
343 prtd->ram_params.ccnt = 1;
344
345 /* Skip 1st period */
346 edma_read_slot(prtd->ram_link, &p_ram);
347 p_ram.src += (ping_size << 1);
348 p_ram.ccnt -= 1;
349 edma_write_slot(prtd->ram_link2, &p_ram);
350 /*
351 * When 1st started, ram -> iram dma channel will fill the
352 * entire iram. Then, whenever a ping/pong asp buffer finishes,
353 * 1/2 iram will be filled.
354 */
355 prtd->ram_params.link_bcntrld =
356 EDMA_CHAN_SLOT(prtd->ram_link2) << 5;
357 }
358 return 0;
359}
360
361/* 1 asp tx or rx channel using 2 parameter channels
362 * 1 ram to/from iram channel using 1 parameter channel
363 *
364 * Playback
365 * ram copy channel kicks off first,
366 * 1st ram copy of entire iram buffer completion kicks off asp channel
367 * asp tcc always kicks off ram copy of 1/2 iram buffer
368 *
369 * Record
370 * asp channel starts, tcc kicks off ram copy
371 */
372static int request_ping_pong(struct snd_pcm_substream *substream,
373 struct davinci_runtime_data *prtd,
374 struct snd_dma_buffer *iram_dma)
375{
376 dma_addr_t asp_src_ping;
377 dma_addr_t asp_dst_ping;
378 int link;
379 struct davinci_pcm_dma_params *params = prtd->params;
380
381 /* Request ram master channel */
382 link = prtd->ram_channel = edma_alloc_channel(EDMA_CHANNEL_ANY,
383 davinci_pcm_dma_irq, substream,
384 EVENTQ_1);
385 if (link < 0)
386 goto exit1;
387
388 /* Request ram link channel */
389 link = prtd->ram_link = edma_alloc_slot(
390 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
391 if (link < 0)
392 goto exit2;
393
394 link = prtd->asp_link[1] = edma_alloc_slot(
395 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
396 if (link < 0)
397 goto exit3;
398
399 prtd->ram_link2 = -1;
400 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
401 link = prtd->ram_link2 = edma_alloc_slot(
402 EDMA_CTLR(prtd->ram_channel), EDMA_SLOT_ANY);
403 if (link < 0)
404 goto exit4;
405 }
406 /* circle ping-pong buffers */
407 edma_link(prtd->asp_link[0], prtd->asp_link[1]);
408 edma_link(prtd->asp_link[1], prtd->asp_link[0]);
409 /* circle ram buffers */
410 edma_link(prtd->ram_link, prtd->ram_link);
411
412 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
413 asp_src_ping = iram_dma->addr;
414 asp_dst_ping = params->dma_addr; /* fifo */
415 } else {
416 asp_src_ping = params->dma_addr; /* fifo */
417 asp_dst_ping = iram_dma->addr;
418 }
419 /* ping */
420 link = prtd->asp_link[0];
421 edma_set_src(link, asp_src_ping, INCR, W16BIT);
422 edma_set_dest(link, asp_dst_ping, INCR, W16BIT);
423 edma_set_src_index(link, 0, 0);
424 edma_set_dest_index(link, 0, 0);
425
426 edma_read_slot(link, &prtd->asp_params);
427 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f) | TCINTEN);
428 prtd->asp_params.opt |= TCCHEN | EDMA_TCC(prtd->ram_channel & 0x3f);
429 edma_write_slot(link, &prtd->asp_params);
430
431 /* pong */
432 link = prtd->asp_link[1];
433 edma_set_src(link, asp_src_ping, INCR, W16BIT);
434 edma_set_dest(link, asp_dst_ping, INCR, W16BIT);
435 edma_set_src_index(link, 0, 0);
436 edma_set_dest_index(link, 0, 0);
437
438 edma_read_slot(link, &prtd->asp_params);
439 prtd->asp_params.opt &= ~(TCCMODE | EDMA_TCC(0x3f));
440 /* interrupt after every pong completion */
441 prtd->asp_params.opt |= TCINTEN | TCCHEN |
442 EDMA_TCC(EDMA_CHAN_SLOT(prtd->ram_channel));
443 edma_write_slot(link, &prtd->asp_params);
444
445 /* ram */
446 link = prtd->ram_link;
447 edma_set_src(link, iram_dma->addr, INCR, W32BIT);
448 edma_set_dest(link, iram_dma->addr, INCR, W32BIT);
449 pr_debug("%s: audio dma channels/slots in use for ram:%u %u %u,"
450 "for asp:%u %u %u\n", __func__,
451 prtd->ram_channel, prtd->ram_link, prtd->ram_link2,
452 prtd->asp_channel, prtd->asp_link[0],
453 prtd->asp_link[1]);
454 return 0;
455exit4:
456 edma_free_channel(prtd->asp_link[1]);
457 prtd->asp_link[1] = -1;
458exit3:
459 edma_free_channel(prtd->ram_link);
460 prtd->ram_link = -1;
461exit2:
462 edma_free_channel(prtd->ram_channel);
463 prtd->ram_channel = -1;
464exit1:
465 return link;
124} 466}
125 467
126static int davinci_pcm_dma_request(struct snd_pcm_substream *substream) 468static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
127{ 469{
470 struct snd_dma_buffer *iram_dma;
128 struct davinci_runtime_data *prtd = substream->runtime->private_data; 471 struct davinci_runtime_data *prtd = substream->runtime->private_data;
129 struct edmacc_param p_ram; 472 struct davinci_pcm_dma_params *params = prtd->params;
130 int ret; 473 int link;
131 474
132 /* Request master DMA channel */ 475 if (!params)
133 ret = edma_alloc_channel(prtd->params->channel, 476 return -ENODEV;
134 davinci_pcm_dma_irq, substream,
135 EVENTQ_0);
136 if (ret < 0)
137 return ret;
138 prtd->master_lch = ret;
139 477
140 /* Request parameter RAM reload slot */ 478 /* Request asp master DMA channel */
141 ret = edma_alloc_slot(EDMA_CTLR(prtd->master_lch), EDMA_SLOT_ANY); 479 link = prtd->asp_channel = edma_alloc_channel(params->channel,
142 if (ret < 0) { 480 davinci_pcm_dma_irq, substream, EVENTQ_0);
143 edma_free_channel(prtd->master_lch); 481 if (link < 0)
144 return ret; 482 goto exit1;
483
484 /* Request asp link channels */
485 link = prtd->asp_link[0] = edma_alloc_slot(
486 EDMA_CTLR(prtd->asp_channel), EDMA_SLOT_ANY);
487 if (link < 0)
488 goto exit2;
489
490 iram_dma = (struct snd_dma_buffer *)substream->dma_buffer.private_data;
491 if (iram_dma) {
492 if (request_ping_pong(substream, prtd, iram_dma) == 0)
493 return 0;
494 printk(KERN_WARNING "%s: dma channel allocation failed,"
495 "not using sram\n", __func__);
145 } 496 }
146 prtd->slave_lch = ret;
147 497
148 /* Issue transfer completion IRQ when the channel completes a 498 /* Issue transfer completion IRQ when the channel completes a
149 * transfer, then always reload from the same slot (by a kind 499 * transfer, then always reload from the same slot (by a kind
@@ -154,12 +504,17 @@ static int davinci_pcm_dma_request(struct snd_pcm_substream *substream)
154 * the buffer and its length (ccnt) ... use it as a template 504 * the buffer and its length (ccnt) ... use it as a template
155 * so davinci_pcm_enqueue_dma() takes less time in IRQ. 505 * so davinci_pcm_enqueue_dma() takes less time in IRQ.
156 */ 506 */
157 edma_read_slot(prtd->slave_lch, &p_ram); 507 edma_read_slot(link, &prtd->asp_params);
158 p_ram.opt |= TCINTEN | EDMA_TCC(EDMA_CHAN_SLOT(prtd->master_lch)); 508 prtd->asp_params.opt |= TCINTEN |
159 p_ram.link_bcntrld = EDMA_CHAN_SLOT(prtd->slave_lch) << 5; 509 EDMA_TCC(EDMA_CHAN_SLOT(prtd->asp_channel));
160 edma_write_slot(prtd->slave_lch, &p_ram); 510 prtd->asp_params.link_bcntrld = EDMA_CHAN_SLOT(link) << 5;
161 511 edma_write_slot(link, &prtd->asp_params);
162 return 0; 512 return 0;
513exit2:
514 edma_free_channel(prtd->asp_channel);
515 prtd->asp_channel = -1;
516exit1:
517 return link;
163} 518}
164 519
165static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 520static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
@@ -173,12 +528,12 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
173 case SNDRV_PCM_TRIGGER_START: 528 case SNDRV_PCM_TRIGGER_START:
174 case SNDRV_PCM_TRIGGER_RESUME: 529 case SNDRV_PCM_TRIGGER_RESUME:
175 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 530 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
176 edma_start(prtd->master_lch); 531 edma_resume(prtd->asp_channel);
177 break; 532 break;
178 case SNDRV_PCM_TRIGGER_STOP: 533 case SNDRV_PCM_TRIGGER_STOP:
179 case SNDRV_PCM_TRIGGER_SUSPEND: 534 case SNDRV_PCM_TRIGGER_SUSPEND:
180 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 535 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
181 edma_stop(prtd->master_lch); 536 edma_pause(prtd->asp_channel);
182 break; 537 break;
183 default: 538 default:
184 ret = -EINVAL; 539 ret = -EINVAL;
@@ -193,15 +548,37 @@ static int davinci_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
193static int davinci_pcm_prepare(struct snd_pcm_substream *substream) 548static int davinci_pcm_prepare(struct snd_pcm_substream *substream)
194{ 549{
195 struct davinci_runtime_data *prtd = substream->runtime->private_data; 550 struct davinci_runtime_data *prtd = substream->runtime->private_data;
196 struct edmacc_param temp;
197 551
552 if (prtd->ram_channel >= 0) {
553 int ret = ping_pong_dma_setup(substream);
554 if (ret < 0)
555 return ret;
556
557 edma_write_slot(prtd->ram_channel, &prtd->ram_params);
558 edma_write_slot(prtd->asp_channel, &prtd->asp_params);
559
560 print_buf_info(prtd->ram_channel, "ram_channel");
561 print_buf_info(prtd->ram_link, "ram_link");
562 print_buf_info(prtd->ram_link2, "ram_link2");
563 print_buf_info(prtd->asp_channel, "asp_channel");
564 print_buf_info(prtd->asp_link[0], "asp_link[0]");
565 print_buf_info(prtd->asp_link[1], "asp_link[1]");
566
567 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
568 /* copy 1st iram buffer */
569 edma_start(prtd->ram_channel);
570 }
571 edma_start(prtd->asp_channel);
572 return 0;
573 }
198 prtd->period = 0; 574 prtd->period = 0;
199 davinci_pcm_enqueue_dma(substream); 575 davinci_pcm_enqueue_dma(substream);
200 576
201 /* Copy self-linked parameter RAM entry into master channel */ 577 /* Copy self-linked parameter RAM entry into master channel */
202 edma_read_slot(prtd->slave_lch, &temp); 578 edma_read_slot(prtd->asp_link[0], &prtd->asp_params);
203 edma_write_slot(prtd->master_lch, &temp); 579 edma_write_slot(prtd->asp_channel, &prtd->asp_params);
204 davinci_pcm_enqueue_dma(substream); 580 davinci_pcm_enqueue_dma(substream);
581 edma_start(prtd->asp_channel);
205 582
206 return 0; 583 return 0;
207} 584}
@@ -212,20 +589,53 @@ davinci_pcm_pointer(struct snd_pcm_substream *substream)
212 struct snd_pcm_runtime *runtime = substream->runtime; 589 struct snd_pcm_runtime *runtime = substream->runtime;
213 struct davinci_runtime_data *prtd = runtime->private_data; 590 struct davinci_runtime_data *prtd = runtime->private_data;
214 unsigned int offset; 591 unsigned int offset;
215 dma_addr_t count; 592 int asp_count;
216 dma_addr_t src, dst; 593 dma_addr_t asp_src, asp_dst;
217 594
218 spin_lock(&prtd->lock); 595 spin_lock(&prtd->lock);
219 596 if (prtd->ram_channel >= 0) {
220 edma_get_position(prtd->master_lch, &src, &dst); 597 int ram_count;
221 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 598 int mod_ram;
222 count = src - runtime->dma_addr; 599 dma_addr_t ram_src, ram_dst;
223 else 600 unsigned int period_size = snd_pcm_lib_period_bytes(substream);
224 count = dst - runtime->dma_addr; 601 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
225 602 /* reading ram before asp should be safe
603 * as long as the asp transfers less than a ping size
604 * of bytes between the 2 reads
605 */
606 edma_get_position(prtd->ram_channel,
607 &ram_src, &ram_dst);
608 edma_get_position(prtd->asp_channel,
609 &asp_src, &asp_dst);
610 asp_count = asp_src - prtd->asp_params.src;
611 ram_count = ram_src - prtd->ram_params.src;
612 mod_ram = ram_count % period_size;
613 mod_ram -= asp_count;
614 if (mod_ram < 0)
615 mod_ram += period_size;
616 else if (mod_ram == 0) {
617 if (snd_pcm_running(substream))
618 mod_ram += period_size;
619 }
620 ram_count -= mod_ram;
621 if (ram_count < 0)
622 ram_count += period_size * runtime->periods;
623 } else {
624 edma_get_position(prtd->ram_channel,
625 &ram_src, &ram_dst);
626 ram_count = ram_dst - prtd->ram_params.dst;
627 }
628 asp_count = ram_count;
629 } else {
630 edma_get_position(prtd->asp_channel, &asp_src, &asp_dst);
631 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
632 asp_count = asp_src - runtime->dma_addr;
633 else
634 asp_count = asp_dst - runtime->dma_addr;
635 }
226 spin_unlock(&prtd->lock); 636 spin_unlock(&prtd->lock);
227 637
228 offset = bytes_to_frames(runtime, count); 638 offset = bytes_to_frames(runtime, asp_count);
229 if (offset >= runtime->buffer_size) 639 if (offset >= runtime->buffer_size)
230 offset = 0; 640 offset = 0;
231 641
@@ -236,14 +646,19 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
236{ 646{
237 struct snd_pcm_runtime *runtime = substream->runtime; 647 struct snd_pcm_runtime *runtime = substream->runtime;
238 struct davinci_runtime_data *prtd; 648 struct davinci_runtime_data *prtd;
649 struct snd_pcm_hardware *ppcm;
239 int ret = 0; 650 int ret = 0;
240 struct snd_soc_pcm_runtime *rtd = substream->private_data; 651 struct snd_soc_pcm_runtime *rtd = substream->private_data;
241 struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->private_data; 652 struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->dma_data;
242 struct davinci_pcm_dma_params *params = &pa[substream->stream]; 653 struct davinci_pcm_dma_params *params;
243 if (!params) 654 if (!pa)
244 return -ENODEV; 655 return -ENODEV;
656 params = &pa[substream->stream];
245 657
246 snd_soc_set_runtime_hwparams(substream, &davinci_pcm_hardware); 658 ppcm = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
659 &pcm_hardware_playback : &pcm_hardware_capture;
660 allocate_sram(substream, params->sram_size, ppcm);
661 snd_soc_set_runtime_hwparams(substream, ppcm);
247 /* ensure that buffer size is a multiple of period size */ 662 /* ensure that buffer size is a multiple of period size */
248 ret = snd_pcm_hw_constraint_integer(runtime, 663 ret = snd_pcm_hw_constraint_integer(runtime,
249 SNDRV_PCM_HW_PARAM_PERIODS); 664 SNDRV_PCM_HW_PARAM_PERIODS);
@@ -256,6 +671,11 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
256 671
257 spin_lock_init(&prtd->lock); 672 spin_lock_init(&prtd->lock);
258 prtd->params = params; 673 prtd->params = params;
674 prtd->asp_channel = -1;
675 prtd->asp_link[0] = prtd->asp_link[1] = -1;
676 prtd->ram_channel = -1;
677 prtd->ram_link = -1;
678 prtd->ram_link2 = -1;
259 679
260 runtime->private_data = prtd; 680 runtime->private_data = prtd;
261 681
@@ -273,10 +693,29 @@ static int davinci_pcm_close(struct snd_pcm_substream *substream)
273 struct snd_pcm_runtime *runtime = substream->runtime; 693 struct snd_pcm_runtime *runtime = substream->runtime;
274 struct davinci_runtime_data *prtd = runtime->private_data; 694 struct davinci_runtime_data *prtd = runtime->private_data;
275 695
276 edma_unlink(prtd->slave_lch); 696 if (prtd->ram_channel >= 0)
277 697 edma_stop(prtd->ram_channel);
278 edma_free_slot(prtd->slave_lch); 698 if (prtd->asp_channel >= 0)
279 edma_free_channel(prtd->master_lch); 699 edma_stop(prtd->asp_channel);
700 if (prtd->asp_link[0] >= 0)
701 edma_unlink(prtd->asp_link[0]);
702 if (prtd->asp_link[1] >= 0)
703 edma_unlink(prtd->asp_link[1]);
704 if (prtd->ram_link >= 0)
705 edma_unlink(prtd->ram_link);
706
707 if (prtd->asp_link[0] >= 0)
708 edma_free_slot(prtd->asp_link[0]);
709 if (prtd->asp_link[1] >= 0)
710 edma_free_slot(prtd->asp_link[1]);
711 if (prtd->asp_channel >= 0)
712 edma_free_channel(prtd->asp_channel);
713 if (prtd->ram_link >= 0)
714 edma_free_slot(prtd->ram_link);
715 if (prtd->ram_link2 >= 0)
716 edma_free_slot(prtd->ram_link2);
717 if (prtd->ram_channel >= 0)
718 edma_free_channel(prtd->ram_channel);
280 719
281 kfree(prtd); 720 kfree(prtd);
282 721
@@ -318,11 +757,11 @@ static struct snd_pcm_ops davinci_pcm_ops = {
318 .mmap = davinci_pcm_mmap, 757 .mmap = davinci_pcm_mmap,
319}; 758};
320 759
321static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 760static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
761 size_t size)
322{ 762{
323 struct snd_pcm_substream *substream = pcm->streams[stream].substream; 763 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
324 struct snd_dma_buffer *buf = &substream->dma_buffer; 764 struct snd_dma_buffer *buf = &substream->dma_buffer;
325 size_t size = davinci_pcm_hardware.buffer_bytes_max;
326 765
327 buf->dev.type = SNDRV_DMA_TYPE_DEV; 766 buf->dev.type = SNDRV_DMA_TYPE_DEV;
328 buf->dev.dev = pcm->card->dev; 767 buf->dev.dev = pcm->card->dev;
@@ -347,6 +786,7 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
347 int stream; 786 int stream;
348 787
349 for (stream = 0; stream < 2; stream++) { 788 for (stream = 0; stream < 2; stream++) {
789 struct snd_dma_buffer *iram_dma;
350 substream = pcm->streams[stream].substream; 790 substream = pcm->streams[stream].substream;
351 if (!substream) 791 if (!substream)
352 continue; 792 continue;
@@ -358,6 +798,11 @@ static void davinci_pcm_free(struct snd_pcm *pcm)
358 dma_free_writecombine(pcm->card->dev, buf->bytes, 798 dma_free_writecombine(pcm->card->dev, buf->bytes,
359 buf->area, buf->addr); 799 buf->area, buf->addr);
360 buf->area = NULL; 800 buf->area = NULL;
801 iram_dma = (struct snd_dma_buffer *)buf->private_data;
802 if (iram_dma) {
803 sram_free(iram_dma->area, iram_dma->bytes);
804 kfree(iram_dma);
805 }
361 } 806 }
362} 807}
363 808
@@ -375,14 +820,16 @@ static int davinci_pcm_new(struct snd_card *card,
375 820
376 if (dai->playback.channels_min) { 821 if (dai->playback.channels_min) {
377 ret = davinci_pcm_preallocate_dma_buffer(pcm, 822 ret = davinci_pcm_preallocate_dma_buffer(pcm,
378 SNDRV_PCM_STREAM_PLAYBACK); 823 SNDRV_PCM_STREAM_PLAYBACK,
824 pcm_hardware_playback.buffer_bytes_max);
379 if (ret) 825 if (ret)
380 return ret; 826 return ret;
381 } 827 }
382 828
383 if (dai->capture.channels_min) { 829 if (dai->capture.channels_min) {
384 ret = davinci_pcm_preallocate_dma_buffer(pcm, 830 ret = davinci_pcm_preallocate_dma_buffer(pcm,
385 SNDRV_PCM_STREAM_CAPTURE); 831 SNDRV_PCM_STREAM_CAPTURE,
832 pcm_hardware_capture.buffer_bytes_max);
386 if (ret) 833 if (ret)
387 return ret; 834 return ret;
388 } 835 }
diff --git a/sound/soc/davinci/davinci-pcm.h b/sound/soc/davinci/davinci-pcm.h
index 8746606efc89..0764944cf10f 100644
--- a/sound/soc/davinci/davinci-pcm.h
+++ b/sound/soc/davinci/davinci-pcm.h
@@ -20,9 +20,11 @@ struct davinci_pcm_dma_params {
20 int channel; /* sync dma channel ID */ 20 int channel; /* sync dma channel ID */
21 unsigned short acnt; 21 unsigned short acnt;
22 dma_addr_t dma_addr; /* device physical address for DMA */ 22 dma_addr_t dma_addr; /* device physical address for DMA */
23 unsigned sram_size;
23 enum dma_event_q eventq_no; /* event queue number */ 24 enum dma_event_q eventq_no; /* event queue number */
24 unsigned char data_type; /* xfer data type */ 25 unsigned char data_type; /* xfer data type */
25 unsigned char convert_mono_stereo; 26 unsigned char convert_mono_stereo;
27 unsigned int fifo_level;
26}; 28};
27 29
28 30
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 6096d22283e6..30ed568afb2e 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -58,47 +58,15 @@ static void psc_dma_bcom_enqueue_next_buffer(struct psc_dma_stream *s)
58 /* Prepare and enqueue the next buffer descriptor */ 58 /* Prepare and enqueue the next buffer descriptor */
59 bd = bcom_prepare_next_buffer(s->bcom_task); 59 bd = bcom_prepare_next_buffer(s->bcom_task);
60 bd->status = s->period_bytes; 60 bd->status = s->period_bytes;
61 bd->data[0] = s->period_next_pt; 61 bd->data[0] = s->runtime->dma_addr + (s->period_next * s->period_bytes);
62 bcom_submit_next_buffer(s->bcom_task, NULL); 62 bcom_submit_next_buffer(s->bcom_task, NULL);
63 63
64 /* Update for next period */ 64 /* Update for next period */
65 s->period_next_pt += s->period_bytes; 65 s->period_next = (s->period_next + 1) % s->runtime->periods;
66 if (s->period_next_pt >= s->period_end)
67 s->period_next_pt = s->period_start;
68}
69
70static void psc_dma_bcom_enqueue_tx(struct psc_dma_stream *s)
71{
72 if (s->appl_ptr > s->runtime->control->appl_ptr) {
73 /*
74 * In this case s->runtime->control->appl_ptr has wrapped around.
75 * Play the data to the end of the boundary, then wrap our own
76 * appl_ptr back around.
77 */
78 while (s->appl_ptr < s->runtime->boundary) {
79 if (bcom_queue_full(s->bcom_task))
80 return;
81
82 s->appl_ptr += s->period_size;
83
84 psc_dma_bcom_enqueue_next_buffer(s);
85 }
86 s->appl_ptr -= s->runtime->boundary;
87 }
88
89 while (s->appl_ptr < s->runtime->control->appl_ptr) {
90
91 if (bcom_queue_full(s->bcom_task))
92 return;
93
94 s->appl_ptr += s->period_size;
95
96 psc_dma_bcom_enqueue_next_buffer(s);
97 }
98} 66}
99 67
100/* Bestcomm DMA irq handler */ 68/* Bestcomm DMA irq handler */
101static irqreturn_t psc_dma_bcom_irq_tx(int irq, void *_psc_dma_stream) 69static irqreturn_t psc_dma_bcom_irq(int irq, void *_psc_dma_stream)
102{ 70{
103 struct psc_dma_stream *s = _psc_dma_stream; 71 struct psc_dma_stream *s = _psc_dma_stream;
104 72
@@ -108,34 +76,8 @@ static irqreturn_t psc_dma_bcom_irq_tx(int irq, void *_psc_dma_stream)
108 while (bcom_buffer_done(s->bcom_task)) { 76 while (bcom_buffer_done(s->bcom_task)) {
109 bcom_retrieve_buffer(s->bcom_task, NULL, NULL); 77 bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
110 78
111 s->period_current_pt += s->period_bytes; 79 s->period_current = (s->period_current+1) % s->runtime->periods;
112 if (s->period_current_pt >= s->period_end) 80 s->period_count++;
113 s->period_current_pt = s->period_start;
114 }
115 psc_dma_bcom_enqueue_tx(s);
116 spin_unlock(&s->psc_dma->lock);
117
118 /* If the stream is active, then also inform the PCM middle layer
119 * of the period finished event. */
120 if (s->active)
121 snd_pcm_period_elapsed(s->stream);
122
123 return IRQ_HANDLED;
124}
125
126static irqreturn_t psc_dma_bcom_irq_rx(int irq, void *_psc_dma_stream)
127{
128 struct psc_dma_stream *s = _psc_dma_stream;
129
130 spin_lock(&s->psc_dma->lock);
131 /* For each finished period, dequeue the completed period buffer
132 * and enqueue a new one in it's place. */
133 while (bcom_buffer_done(s->bcom_task)) {
134 bcom_retrieve_buffer(s->bcom_task, NULL, NULL);
135
136 s->period_current_pt += s->period_bytes;
137 if (s->period_current_pt >= s->period_end)
138 s->period_current_pt = s->period_start;
139 81
140 psc_dma_bcom_enqueue_next_buffer(s); 82 psc_dma_bcom_enqueue_next_buffer(s);
141 } 83 }
@@ -166,54 +108,38 @@ static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
166 struct snd_soc_pcm_runtime *rtd = substream->private_data; 108 struct snd_soc_pcm_runtime *rtd = substream->private_data;
167 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 109 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
168 struct snd_pcm_runtime *runtime = substream->runtime; 110 struct snd_pcm_runtime *runtime = substream->runtime;
169 struct psc_dma_stream *s; 111 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
170 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs; 112 struct mpc52xx_psc __iomem *regs = psc_dma->psc_regs;
171 u16 imr; 113 u16 imr;
172 unsigned long flags; 114 unsigned long flags;
173 int i; 115 int i;
174 116
175 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
176 s = &psc_dma->capture;
177 else
178 s = &psc_dma->playback;
179
180 dev_dbg(psc_dma->dev, "psc_dma_trigger(substream=%p, cmd=%i)"
181 " stream_id=%i\n",
182 substream, cmd, substream->pstr->stream);
183
184 switch (cmd) { 117 switch (cmd) {
185 case SNDRV_PCM_TRIGGER_START: 118 case SNDRV_PCM_TRIGGER_START:
119 dev_dbg(psc_dma->dev, "START: stream=%i fbits=%u ps=%u #p=%u\n",
120 substream->pstr->stream, runtime->frame_bits,
121 (int)runtime->period_size, runtime->periods);
186 s->period_bytes = frames_to_bytes(runtime, 122 s->period_bytes = frames_to_bytes(runtime,
187 runtime->period_size); 123 runtime->period_size);
188 s->period_start = virt_to_phys(runtime->dma_area); 124 s->period_next = 0;
189 s->period_end = s->period_start + 125 s->period_current = 0;
190 (s->period_bytes * runtime->periods);
191 s->period_next_pt = s->period_start;
192 s->period_current_pt = s->period_start;
193 s->period_size = runtime->period_size;
194 s->active = 1; 126 s->active = 1;
195 127 s->period_count = 0;
196 /* track appl_ptr so that we have a better chance of detecting
197 * end of stream and not over running it.
198 */
199 s->runtime = runtime; 128 s->runtime = runtime;
200 s->appl_ptr = s->runtime->control->appl_ptr -
201 (runtime->period_size * runtime->periods);
202 129
203 /* Fill up the bestcomm bd queue and enable DMA. 130 /* Fill up the bestcomm bd queue and enable DMA.
204 * This will begin filling the PSC's fifo. 131 * This will begin filling the PSC's fifo.
205 */ 132 */
206 spin_lock_irqsave(&psc_dma->lock, flags); 133 spin_lock_irqsave(&psc_dma->lock, flags);
207 134
208 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { 135 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
209 bcom_gen_bd_rx_reset(s->bcom_task); 136 bcom_gen_bd_rx_reset(s->bcom_task);
210 for (i = 0; i < runtime->periods; i++) 137 else
211 if (!bcom_queue_full(s->bcom_task))
212 psc_dma_bcom_enqueue_next_buffer(s);
213 } else {
214 bcom_gen_bd_tx_reset(s->bcom_task); 138 bcom_gen_bd_tx_reset(s->bcom_task);
215 psc_dma_bcom_enqueue_tx(s); 139
216 } 140 for (i = 0; i < runtime->periods; i++)
141 if (!bcom_queue_full(s->bcom_task))
142 psc_dma_bcom_enqueue_next_buffer(s);
217 143
218 bcom_enable(s->bcom_task); 144 bcom_enable(s->bcom_task);
219 spin_unlock_irqrestore(&psc_dma->lock, flags); 145 spin_unlock_irqrestore(&psc_dma->lock, flags);
@@ -223,6 +149,8 @@ static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
223 break; 149 break;
224 150
225 case SNDRV_PCM_TRIGGER_STOP: 151 case SNDRV_PCM_TRIGGER_STOP:
152 dev_dbg(psc_dma->dev, "STOP: stream=%i periods_count=%i\n",
153 substream->pstr->stream, s->period_count);
226 s->active = 0; 154 s->active = 0;
227 155
228 spin_lock_irqsave(&psc_dma->lock, flags); 156 spin_lock_irqsave(&psc_dma->lock, flags);
@@ -236,7 +164,8 @@ static int psc_dma_trigger(struct snd_pcm_substream *substream, int cmd)
236 break; 164 break;
237 165
238 default: 166 default:
239 dev_dbg(psc_dma->dev, "invalid command\n"); 167 dev_dbg(psc_dma->dev, "unhandled trigger: stream=%i cmd=%i\n",
168 substream->pstr->stream, cmd);
240 return -EINVAL; 169 return -EINVAL;
241 } 170 }
242 171
@@ -343,7 +272,7 @@ psc_dma_pointer(struct snd_pcm_substream *substream)
343 else 272 else
344 s = &psc_dma->playback; 273 s = &psc_dma->playback;
345 274
346 count = s->period_current_pt - s->period_start; 275 count = s->period_current * s->period_bytes;
347 276
348 return bytes_to_frames(substream->runtime, count); 277 return bytes_to_frames(substream->runtime, count);
349} 278}
@@ -532,11 +461,9 @@ int mpc5200_audio_dma_create(struct of_device *op)
532 461
533 rc = request_irq(psc_dma->irq, &psc_dma_status_irq, IRQF_SHARED, 462 rc = request_irq(psc_dma->irq, &psc_dma_status_irq, IRQF_SHARED,
534 "psc-dma-status", psc_dma); 463 "psc-dma-status", psc_dma);
535 rc |= request_irq(psc_dma->capture.irq, 464 rc |= request_irq(psc_dma->capture.irq, &psc_dma_bcom_irq, IRQF_SHARED,
536 &psc_dma_bcom_irq_rx, IRQF_SHARED,
537 "psc-dma-capture", &psc_dma->capture); 465 "psc-dma-capture", &psc_dma->capture);
538 rc |= request_irq(psc_dma->playback.irq, 466 rc |= request_irq(psc_dma->playback.irq, &psc_dma_bcom_irq, IRQF_SHARED,
539 &psc_dma_bcom_irq_tx, IRQF_SHARED,
540 "psc-dma-playback", &psc_dma->playback); 467 "psc-dma-playback", &psc_dma->playback);
541 if (rc) { 468 if (rc) {
542 ret = -ENODEV; 469 ret = -ENODEV;
diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h
index 8d396bb9d9fe..22208b373fb9 100644
--- a/sound/soc/fsl/mpc5200_dma.h
+++ b/sound/soc/fsl/mpc5200_dma.h
@@ -13,26 +13,25 @@
13 * @psc_dma: pointer back to parent psc_dma data structure 13 * @psc_dma: pointer back to parent psc_dma data structure
14 * @bcom_task: bestcomm task structure 14 * @bcom_task: bestcomm task structure
15 * @irq: irq number for bestcomm task 15 * @irq: irq number for bestcomm task
16 * @period_start: physical address of start of DMA region
17 * @period_end: physical address of end of DMA region 16 * @period_end: physical address of end of DMA region
18 * @period_next_pt: physical address of next DMA buffer to enqueue 17 * @period_next_pt: physical address of next DMA buffer to enqueue
19 * @period_bytes: size of DMA period in bytes 18 * @period_bytes: size of DMA period in bytes
19 * @ac97_slot_bits: Enable bits for turning on the correct AC97 slot
20 */ 20 */
21struct psc_dma_stream { 21struct psc_dma_stream {
22 struct snd_pcm_runtime *runtime; 22 struct snd_pcm_runtime *runtime;
23 snd_pcm_uframes_t appl_ptr;
24
25 int active; 23 int active;
26 struct psc_dma *psc_dma; 24 struct psc_dma *psc_dma;
27 struct bcom_task *bcom_task; 25 struct bcom_task *bcom_task;
28 int irq; 26 int irq;
29 struct snd_pcm_substream *stream; 27 struct snd_pcm_substream *stream;
30 dma_addr_t period_start; 28 int period_next;
31 dma_addr_t period_end; 29 int period_current;
32 dma_addr_t period_next_pt;
33 dma_addr_t period_current_pt;
34 int period_bytes; 30 int period_bytes;
35 int period_size; 31 int period_count;
32
33 /* AC97 state */
34 u32 ac97_slot_bits;
36}; 35};
37 36
38/** 37/**
@@ -73,6 +72,15 @@ struct psc_dma {
73 } stats; 72 } stats;
74}; 73};
75 74
75/* Utility for retrieving psc_dma_stream structure from a substream */
76inline struct psc_dma_stream *
77to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma)
78{
79 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE)
80 return &psc_dma->capture;
81 return &psc_dma->playback;
82}
83
76int mpc5200_audio_dma_create(struct of_device *op); 84int mpc5200_audio_dma_create(struct of_device *op);
77int mpc5200_audio_dma_destroy(struct of_device *op); 85int mpc5200_audio_dma_destroy(struct of_device *op);
78 86
diff --git a/sound/soc/fsl/mpc5200_psc_ac97.c b/sound/soc/fsl/mpc5200_psc_ac97.c
index c4ae3e096bb9..3dbc7f7cd7b9 100644
--- a/sound/soc/fsl/mpc5200_psc_ac97.c
+++ b/sound/soc/fsl/mpc5200_psc_ac97.c
@@ -130,6 +130,7 @@ static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
130 struct snd_soc_dai *cpu_dai) 130 struct snd_soc_dai *cpu_dai)
131{ 131{
132 struct psc_dma *psc_dma = cpu_dai->private_data; 132 struct psc_dma *psc_dma = cpu_dai->private_data;
133 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
133 134
134 dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i" 135 dev_dbg(psc_dma->dev, "%s(substream=%p) p_size=%i p_bytes=%i"
135 " periods=%i buffer_size=%i buffer_bytes=%i channels=%i" 136 " periods=%i buffer_size=%i buffer_bytes=%i channels=%i"
@@ -140,20 +141,10 @@ static int psc_ac97_hw_analog_params(struct snd_pcm_substream *substream,
140 params_channels(params), params_rate(params), 141 params_channels(params), params_rate(params),
141 params_format(params)); 142 params_format(params));
142 143
143 144 /* Determine the set of enable bits to turn on */
144 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) { 145 s->ac97_slot_bits = (params_channels(params) == 1) ? 0x100 : 0x300;
145 if (params_channels(params) == 1) 146 if (substream->pstr->stream != SNDRV_PCM_STREAM_CAPTURE)
146 psc_dma->slots |= 0x00000100; 147 s->ac97_slot_bits <<= 16;
147 else
148 psc_dma->slots |= 0x00000300;
149 } else {
150 if (params_channels(params) == 1)
151 psc_dma->slots |= 0x01000000;
152 else
153 psc_dma->slots |= 0x03000000;
154 }
155 out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
156
157 return 0; 148 return 0;
158} 149}
159 150
@@ -163,6 +154,8 @@ static int psc_ac97_hw_digital_params(struct snd_pcm_substream *substream,
163{ 154{
164 struct psc_dma *psc_dma = cpu_dai->private_data; 155 struct psc_dma *psc_dma = cpu_dai->private_data;
165 156
157 dev_dbg(psc_dma->dev, "%s(substream=%p)\n", __func__, substream);
158
166 if (params_channels(params) == 1) 159 if (params_channels(params) == 1)
167 out_be32(&psc_dma->psc_regs->ac97_slots, 0x01000000); 160 out_be32(&psc_dma->psc_regs->ac97_slots, 0x01000000);
168 else 161 else
@@ -176,14 +169,24 @@ static int psc_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
176{ 169{
177 struct snd_soc_pcm_runtime *rtd = substream->private_data; 170 struct snd_soc_pcm_runtime *rtd = substream->private_data;
178 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data; 171 struct psc_dma *psc_dma = rtd->dai->cpu_dai->private_data;
172 struct psc_dma_stream *s = to_psc_dma_stream(substream, psc_dma);
179 173
180 switch (cmd) { 174 switch (cmd) {
175 case SNDRV_PCM_TRIGGER_START:
176 dev_dbg(psc_dma->dev, "AC97 START: stream=%i\n",
177 substream->pstr->stream);
178
179 /* Set the slot enable bits */
180 psc_dma->slots |= s->ac97_slot_bits;
181 out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
182 break;
183
181 case SNDRV_PCM_TRIGGER_STOP: 184 case SNDRV_PCM_TRIGGER_STOP:
182 if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) 185 dev_dbg(psc_dma->dev, "AC97 STOP: stream=%i\n",
183 psc_dma->slots &= 0xFFFF0000; 186 substream->pstr->stream);
184 else
185 psc_dma->slots &= 0x0000FFFF;
186 187
188 /* Clear the slot enable bits */
189 psc_dma->slots &= ~(s->ac97_slot_bits);
187 out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots); 190 out_be32(&psc_dma->psc_regs->ac97_slots, psc_dma->slots);
188 break; 191 break;
189 } 192 }
diff --git a/sound/soc/imx/mx1_mx2-pcm.c b/sound/soc/imx/mx1_mx2-pcm.c
index b83866529397..bffffcd5ff34 100644
--- a/sound/soc/imx/mx1_mx2-pcm.c
+++ b/sound/soc/imx/mx1_mx2-pcm.c
@@ -322,12 +322,12 @@ static int mx1_mx2_pcm_open(struct snd_pcm_substream *substream)
322 322
323 pr_debug("%s: Requesting dma channel (%s)\n", __func__, 323 pr_debug("%s: Requesting dma channel (%s)\n", __func__,
324 prtd->dma_params->name); 324 prtd->dma_params->name);
325 prtd->dma_ch = imx_dma_request_by_prio(prtd->dma_params->name, 325 ret = imx_dma_request_by_prio(prtd->dma_params->name, DMA_PRIO_HIGH);
326 DMA_PRIO_HIGH); 326 if (ret < 0) {
327 if (prtd->dma_ch < 0) {
328 printk(KERN_ERR "Error %d requesting dma channel\n", ret); 327 printk(KERN_ERR "Error %d requesting dma channel\n", ret);
329 return ret; 328 return ret;
330 } 329 }
330 prtd->dma_ch = ret;
331 imx_dma_config_burstlen(prtd->dma_ch, 331 imx_dma_config_burstlen(prtd->dma_ch,
332 prtd->dma_params->watermark_level); 332 prtd->dma_params->watermark_level);
333 333
diff --git a/sound/soc/imx/mx27vis_wm8974.c b/sound/soc/imx/mx27vis_wm8974.c
index e4dcb539108a..0267d2d91685 100644
--- a/sound/soc/imx/mx27vis_wm8974.c
+++ b/sound/soc/imx/mx27vis_wm8974.c
@@ -157,7 +157,7 @@ static int mx27vis_hifi_hw_params(struct snd_pcm_substream *substream,
157 157
158 158
159 /* codec PLL input is 25 MHz */ 159 /* codec PLL input is 25 MHz */
160 ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, 160 ret = codec_dai->ops->set_pll(codec_dai, IGNORED_ARG, IGNORED_ARG,
161 25000000, pll_out); 161 25000000, pll_out);
162 if (ret < 0) { 162 if (ret < 0) {
163 printk(KERN_ERR "Error when setting PLL input\n"); 163 printk(KERN_ERR "Error when setting PLL input\n");
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 2dee9839be86..61952aa6cd5a 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -21,7 +21,18 @@ config SND_OMAP_SOC_AMS_DELTA
21 select SND_OMAP_SOC_MCBSP 21 select SND_OMAP_SOC_MCBSP
22 select SND_SOC_CX20442 22 select SND_SOC_CX20442
23 help 23 help
24 Say Y if you want to add support for SoC audio on Amstrad Delta. 24 Say Y if you want to add support for SoC audio device connected to
25 a handset and a speakerphone found on Amstrad E3 (Delta) videophone.
26
27 Note that in order to get those devices fully supported, you have to
28 build the kernel with standard serial port driver included and
29 configured for at least 4 ports. Then, from userspace, you must load
30 a line discipline #19 on the modem (ttyS3) serial line. The simplest
31 way to achieve this is to install util-linux-ng and use the included
32 ldattach utility. This can be started automatically from udev,
33 a simple rule like this one should do the trick (it does for me):
34 ACTION=="add", KERNEL=="controlC0", \
35 RUN+="/usr/sbin/ldattach 19 /dev/ttyS3"
25 36
26config SND_OMAP_SOC_OSK5912 37config SND_OMAP_SOC_OSK5912
27 tristate "SoC Audio support for omap osk5912" 38 tristate "SoC Audio support for omap osk5912"
@@ -32,12 +43,13 @@ config SND_OMAP_SOC_OSK5912
32 Say Y if you want to add support for SoC audio on osk5912. 43 Say Y if you want to add support for SoC audio on osk5912.
33 44
34config SND_OMAP_SOC_OVERO 45config SND_OMAP_SOC_OVERO
35 tristate "SoC Audio support for Gumstix Overo" 46 tristate "SoC Audio support for Gumstix Overo and CompuLab CM-T35"
36 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OVERO 47 depends on TWL4030_CORE && SND_OMAP_SOC && (MACH_OVERO || MACH_CM_T35)
37 select SND_OMAP_SOC_MCBSP 48 select SND_OMAP_SOC_MCBSP
38 select SND_SOC_TWL4030 49 select SND_SOC_TWL4030
39 help 50 help
40 Say Y if you want to add support for SoC audio on the Gumstix Overo. 51 Say Y if you want to add support for SoC audio on the
52 Gumstix Overo or CompuLab CM-T35
41 53
42config SND_OMAP_SOC_OMAP2EVM 54config SND_OMAP_SOC_OMAP2EVM
43 tristate "SoC Audio support for OMAP2EVM board" 55 tristate "SoC Audio support for OMAP2EVM board"
@@ -55,6 +67,15 @@ config SND_OMAP_SOC_OMAP3EVM
55 help 67 help
56 Say Y if you want to add support for SoC audio on the omap3evm board. 68 Say Y if you want to add support for SoC audio on the omap3evm board.
57 69
70config SND_OMAP_SOC_AM3517EVM
71 tristate "SoC Audio support for OMAP3517 / AM3517 EVM"
72 depends on SND_OMAP_SOC && MACH_OMAP3517EVM && I2C
73 select SND_OMAP_SOC_MCBSP
74 select SND_SOC_TLV320AIC23
75 help
76 Say Y if you want to add support for SoC audio on the OMAP3517 / AM3517
77 EVM.
78
58config SND_OMAP_SOC_SDP3430 79config SND_OMAP_SOC_SDP3430
59 tristate "SoC Audio support for Texas Instruments SDP3430" 80 tristate "SoC Audio support for Texas Instruments SDP3430"
60 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP 81 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
@@ -88,3 +109,10 @@ config SND_OMAP_SOC_ZOOM2
88 help 109 help
89 Say Y if you want to add support for Soc audio on Zoom2 board. 110 Say Y if you want to add support for Soc audio on Zoom2 board.
90 111
112config SND_OMAP_SOC_IGEP0020
113 tristate "SoC Audio support for IGEP v2"
114 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_IGEP0020
115 select SND_OMAP_SOC_MCBSP
116 select SND_SOC_TWL4030
117 help
118 Say Y if you want to add support for Soc audio on IGEP v2 board.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index 02d69471dcb5..3db8a6c523f4 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -12,18 +12,22 @@ snd-soc-osk5912-objs := osk5912.o
12snd-soc-overo-objs := overo.o 12snd-soc-overo-objs := overo.o
13snd-soc-omap2evm-objs := omap2evm.o 13snd-soc-omap2evm-objs := omap2evm.o
14snd-soc-omap3evm-objs := omap3evm.o 14snd-soc-omap3evm-objs := omap3evm.o
15snd-soc-am3517evm-objs := am3517evm.o
15snd-soc-sdp3430-objs := sdp3430.o 16snd-soc-sdp3430-objs := sdp3430.o
16snd-soc-omap3pandora-objs := omap3pandora.o 17snd-soc-omap3pandora-objs := omap3pandora.o
17snd-soc-omap3beagle-objs := omap3beagle.o 18snd-soc-omap3beagle-objs := omap3beagle.o
18snd-soc-zoom2-objs := zoom2.o 19snd-soc-zoom2-objs := zoom2.o
20snd-soc-igep0020-objs := igep0020.o
19 21
20obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 22obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
21obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o 23obj-$(CONFIG_SND_OMAP_SOC_AMS_DELTA) += snd-soc-ams-delta.o
22obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 24obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
23obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o 25obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
24obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o 26obj-$(CONFIG_SND_OMAP_SOC_OMAP2EVM) += snd-soc-omap2evm.o
25obj-$(CONFIG_MACH_OMAP3EVM) += snd-soc-omap3evm.o 27obj-$(CONFIG_SND_OMAP_SOC_OMAP3EVM) += snd-soc-omap3evm.o
28obj-$(CONFIG_SND_OMAP_SOC_OMAP3517EVM) += snd-soc-am3517evm.o
26obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o 29obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
27obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o 30obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
28obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o 31obj-$(CONFIG_SND_OMAP_SOC_OMAP3_BEAGLE) += snd-soc-omap3beagle.o
29obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o 32obj-$(CONFIG_SND_OMAP_SOC_ZOOM2) += snd-soc-zoom2.o
33obj-$(CONFIG_SND_OMAP_SOC_IGEP0020) += snd-soc-igep0020.o
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
new file mode 100644
index 000000000000..135901b2ea11
--- /dev/null
+++ b/sound/soc/omap/am3517evm.c
@@ -0,0 +1,202 @@
1/*
2 * am3517evm.c -- ALSA SoC support for OMAP3517 / AM3517 EVM
3 *
4 * Author: Anuj Aggarwal <anuj.aggarwal@ti.com>
5 *
6 * Based on sound/soc/omap/beagle.c by Steve Sakoman
7 *
8 * Copyright (C) 2009 Texas Instruments Incorporated
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation version 2.
13 *
14 * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
15 * whether express or implied; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 */
19
20#include <linux/clk.h>
21#include <linux/platform_device.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26
27#include <asm/mach-types.h>
28#include <mach/hardware.h>
29#include <mach/gpio.h>
30#include <plat/mcbsp.h>
31
32#include "omap-mcbsp.h"
33#include "omap-pcm.h"
34
35#include "../codecs/tlv320aic23.h"
36
37#define CODEC_CLOCK 12000000
38
39static int am3517evm_hw_params(struct snd_pcm_substream *substream,
40 struct snd_pcm_hw_params *params)
41{
42 struct snd_soc_pcm_runtime *rtd = substream->private_data;
43 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
44 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
45 int ret;
46
47 /* Set codec DAI configuration */
48 ret = snd_soc_dai_set_fmt(codec_dai,
49 SND_SOC_DAIFMT_DSP_B |
50 SND_SOC_DAIFMT_NB_NF |
51 SND_SOC_DAIFMT_CBM_CFM);
52 if (ret < 0) {
53 printk(KERN_ERR "can't set codec DAI configuration\n");
54 return ret;
55 }
56
57 /* Set cpu DAI configuration */
58 ret = snd_soc_dai_set_fmt(cpu_dai,
59 SND_SOC_DAIFMT_DSP_B |
60 SND_SOC_DAIFMT_NB_NF |
61 SND_SOC_DAIFMT_CBM_CFM);
62 if (ret < 0) {
63 printk(KERN_ERR "can't set cpu DAI configuration\n");
64 return ret;
65 }
66
67 /* Set the codec system clock for DAC and ADC */
68 ret = snd_soc_dai_set_sysclk(codec_dai, 0,
69 CODEC_CLOCK, SND_SOC_CLOCK_IN);
70 if (ret < 0) {
71 printk(KERN_ERR "can't set codec system clock\n");
72 return ret;
73 }
74
75 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_CLKR_SRC_CLKX, 0,
76 SND_SOC_CLOCK_IN);
77 if (ret < 0) {
78 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_CLKR_SRC_CLKX\n");
79 return ret;
80 }
81
82 snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_FSR_SRC_FSX, 0,
83 SND_SOC_CLOCK_IN);
84 if (ret < 0) {
85 printk(KERN_ERR "can't set CPU system clock OMAP_MCBSP_FSR_SRC_FSX\n");
86 return ret;
87 }
88
89 return 0;
90}
91
92static struct snd_soc_ops am3517evm_ops = {
93 .hw_params = am3517evm_hw_params,
94};
95
96/* am3517evm machine dapm widgets */
97static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = {
98 SND_SOC_DAPM_HP("Line Out", NULL),
99 SND_SOC_DAPM_LINE("Line In", NULL),
100 SND_SOC_DAPM_MIC("Mic In", NULL),
101};
102
103static const struct snd_soc_dapm_route audio_map[] = {
104 /* Line Out connected to LLOUT, RLOUT */
105 {"Line Out", NULL, "LOUT"},
106 {"Line Out", NULL, "ROUT"},
107
108 {"LLINEIN", NULL, "Line In"},
109 {"RLINEIN", NULL, "Line In"},
110
111 {"MICIN", NULL, "Mic In"},
112};
113
114static int am3517evm_aic23_init(struct snd_soc_codec *codec)
115{
116 /* Add am3517-evm specific widgets */
117 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
118 ARRAY_SIZE(tlv320aic23_dapm_widgets));
119
120 /* Set up davinci-evm specific audio path audio_map */
121 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
122
123 /* always connected */
124 snd_soc_dapm_enable_pin(codec, "Line Out");
125 snd_soc_dapm_enable_pin(codec, "Line In");
126 snd_soc_dapm_enable_pin(codec, "Mic In");
127
128 snd_soc_dapm_sync(codec);
129
130 return 0;
131}
132
133/* Digital audio interface glue - connects codec <--> CPU */
134static struct snd_soc_dai_link am3517evm_dai = {
135 .name = "TLV320AIC23",
136 .stream_name = "AIC23",
137 .cpu_dai = &omap_mcbsp_dai[0],
138 .codec_dai = &tlv320aic23_dai,
139 .init = am3517evm_aic23_init,
140 .ops = &am3517evm_ops,
141};
142
143/* Audio machine driver */
144static struct snd_soc_card snd_soc_am3517evm = {
145 .name = "am3517evm",
146 .platform = &omap_soc_platform,
147 .dai_link = &am3517evm_dai,
148 .num_links = 1,
149};
150
151/* Audio subsystem */
152static struct snd_soc_device am3517evm_snd_devdata = {
153 .card = &snd_soc_am3517evm,
154 .codec_dev = &soc_codec_dev_tlv320aic23,
155};
156
157static struct platform_device *am3517evm_snd_device;
158
159static int __init am3517evm_soc_init(void)
160{
161 int ret;
162
163 if (!machine_is_omap3517evm()) {
164 pr_err("Not OMAP3517 / AM3517 EVM!\n");
165 return -ENODEV;
166 }
167 pr_info("OMAP3517 / AM3517 EVM SoC init\n");
168
169 am3517evm_snd_device = platform_device_alloc("soc-audio", -1);
170 if (!am3517evm_snd_device) {
171 printk(KERN_ERR "Platform device allocation failed\n");
172 return -ENOMEM;
173 }
174
175 platform_set_drvdata(am3517evm_snd_device, &am3517evm_snd_devdata);
176 am3517evm_snd_devdata.dev = &am3517evm_snd_device->dev;
177 *(unsigned int *)am3517evm_dai.cpu_dai->private_data = 0; /* McBSP1 */
178
179 ret = platform_device_add(am3517evm_snd_device);
180 if (ret)
181 goto err1;
182
183 return 0;
184
185err1:
186 printk(KERN_ERR "Unable to add platform device\n");
187 platform_device_put(am3517evm_snd_device);
188
189 return ret;
190}
191
192static void __exit am3517evm_soc_exit(void)
193{
194 platform_device_unregister(am3517evm_snd_device);
195}
196
197module_init(am3517evm_soc_init);
198module_exit(am3517evm_soc_exit);
199
200MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
201MODULE_DESCRIPTION("ALSA SoC OMAP3517 / AM3517 EVM");
202MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 5a5166ac7279..b0f618e44840 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -31,8 +31,8 @@
31 31
32#include <asm/mach-types.h> 32#include <asm/mach-types.h>
33 33
34#include <mach/board-ams-delta.h> 34#include <plat/board-ams-delta.h>
35#include <mach/mcbsp.h> 35#include <plat/mcbsp.h>
36 36
37#include "omap-mcbsp.h" 37#include "omap-mcbsp.h"
38#include "omap-pcm.h" 38#include "omap-pcm.h"
@@ -40,7 +40,7 @@
40 40
41 41
42/* Board specific DAPM widgets */ 42/* Board specific DAPM widgets */
43 const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = { 43static const struct snd_soc_dapm_widget ams_delta_dapm_widgets[] = {
44 /* Handset */ 44 /* Handset */
45 SND_SOC_DAPM_MIC("Mouthpiece", NULL), 45 SND_SOC_DAPM_MIC("Mouthpiece", NULL),
46 SND_SOC_DAPM_HP("Earpiece", NULL), 46 SND_SOC_DAPM_HP("Earpiece", NULL),
@@ -81,7 +81,7 @@ static const char *ams_delta_audio_mode[] =
81 (1 << AMS_DELTA_SPEAKER)) 81 (1 << AMS_DELTA_SPEAKER))
82#define AMS_DELTA_SPEAKERPHONE (AMS_DELTA_HANDSFREE | (1 << AMS_DELTA_AGC)) 82#define AMS_DELTA_SPEAKERPHONE (AMS_DELTA_HANDSFREE | (1 << AMS_DELTA_AGC))
83 83
84unsigned short ams_delta_audio_mode_pins[] = { 84static const unsigned short ams_delta_audio_mode_pins[] = {
85 AMS_DELTA_MIXED, 85 AMS_DELTA_MIXED,
86 AMS_DELTA_HANDSET, 86 AMS_DELTA_HANDSET,
87 AMS_DELTA_HANDSFREE, 87 AMS_DELTA_HANDSFREE,
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
new file mode 100644
index 000000000000..3583c429f9be
--- /dev/null
+++ b/sound/soc/omap/igep0020.c
@@ -0,0 +1,148 @@
1/*
2 * igep0020.c -- SoC audio for IGEP v2
3 *
4 * Based on sound/soc/omap/overo.c by Steve Sakoman
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 */
21
22#include <linux/clk.h>
23#include <linux/platform_device.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28
29#include <asm/mach-types.h>
30#include <mach/hardware.h>
31#include <mach/gpio.h>
32#include <plat/mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38static int igep2_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params)
40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
44 int ret;
45
46 /* Set codec DAI configuration */
47 ret = snd_soc_dai_set_fmt(codec_dai,
48 SND_SOC_DAIFMT_I2S |
49 SND_SOC_DAIFMT_NB_NF |
50 SND_SOC_DAIFMT_CBM_CFM);
51 if (ret < 0) {
52 printk(KERN_ERR "can't set codec DAI configuration\n");
53 return ret;
54 }
55
56 /* Set cpu DAI configuration */
57 ret = snd_soc_dai_set_fmt(cpu_dai,
58 SND_SOC_DAIFMT_I2S |
59 SND_SOC_DAIFMT_NB_NF |
60 SND_SOC_DAIFMT_CBM_CFM);
61 if (ret < 0) {
62 printk(KERN_ERR "can't set cpu DAI configuration\n");
63 return ret;
64 }
65
66 /* Set the codec system clock for DAC and ADC */
67 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
68 SND_SOC_CLOCK_IN);
69 if (ret < 0) {
70 printk(KERN_ERR "can't set codec system clock\n");
71 return ret;
72 }
73
74 return 0;
75}
76
77static struct snd_soc_ops igep2_ops = {
78 .hw_params = igep2_hw_params,
79};
80
81/* Digital audio interface glue - connects codec <--> CPU */
82static struct snd_soc_dai_link igep2_dai = {
83 .name = "TWL4030",
84 .stream_name = "TWL4030",
85 .cpu_dai = &omap_mcbsp_dai[0],
86 .codec_dai = &twl4030_dai[TWL4030_DAI_HIFI],
87 .ops = &igep2_ops,
88};
89
90/* Audio machine driver */
91static struct snd_soc_card snd_soc_card_igep2 = {
92 .name = "igep2",
93 .platform = &omap_soc_platform,
94 .dai_link = &igep2_dai,
95 .num_links = 1,
96};
97
98/* Audio subsystem */
99static struct snd_soc_device igep2_snd_devdata = {
100 .card = &snd_soc_card_igep2,
101 .codec_dev = &soc_codec_dev_twl4030,
102};
103
104static struct platform_device *igep2_snd_device;
105
106static int __init igep2_soc_init(void)
107{
108 int ret;
109
110 if (!machine_is_igep0020()) {
111 pr_debug("Not IGEP v2!\n");
112 return -ENODEV;
113 }
114 printk(KERN_INFO "IGEP v2 SoC init\n");
115
116 igep2_snd_device = platform_device_alloc("soc-audio", -1);
117 if (!igep2_snd_device) {
118 printk(KERN_ERR "Platform device allocation failed\n");
119 return -ENOMEM;
120 }
121
122 platform_set_drvdata(igep2_snd_device, &igep2_snd_devdata);
123 igep2_snd_devdata.dev = &igep2_snd_device->dev;
124 *(unsigned int *)igep2_dai.cpu_dai->private_data = 1; /* McBSP2 */
125
126 ret = platform_device_add(igep2_snd_device);
127 if (ret)
128 goto err1;
129
130 return 0;
131
132err1:
133 printk(KERN_ERR "Unable to add platform device\n");
134 platform_device_put(igep2_snd_device);
135
136 return ret;
137}
138module_init(igep2_soc_init);
139
140static void __exit igep2_soc_exit(void)
141{
142 platform_device_unregister(igep2_snd_device);
143}
144module_exit(igep2_soc_exit);
145
146MODULE_AUTHOR("Enric Balletbo i Serra <eballetbo@iseebcn.com>");
147MODULE_DESCRIPTION("ALSA SoC IGEP v2");
148MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index 0a505938e42b..08e09d72790f 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -32,7 +32,7 @@
32#include <asm/mach-types.h> 32#include <asm/mach-types.h>
33#include <mach/hardware.h> 33#include <mach/hardware.h>
34#include <linux/gpio.h> 34#include <linux/gpio.h>
35#include <mach/mcbsp.h> 35#include <plat/mcbsp.h>
36 36
37#include "omap-mcbsp.h" 37#include "omap-mcbsp.h"
38#include "omap-pcm.h" 38#include "omap-pcm.h"
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 3341f49402ca..6bbbd2ab0ee7 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -31,9 +31,9 @@
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33 33
34#include <mach/control.h> 34#include <plat/control.h>
35#include <mach/dma.h> 35#include <plat/dma.h>
36#include <mach/mcbsp.h> 36#include <plat/mcbsp.h>
37#include "omap-mcbsp.h" 37#include "omap-mcbsp.h"
38#include "omap-pcm.h" 38#include "omap-pcm.h"
39 39
@@ -49,6 +49,8 @@ struct omap_mcbsp_data {
49 */ 49 */
50 int active; 50 int active;
51 int configured; 51 int configured;
52 unsigned int in_freq;
53 int clk_div;
52}; 54};
53 55
54#define to_mcbsp(priv) container_of((priv), struct omap_mcbsp_data, bus_id) 56#define to_mcbsp(priv) container_of((priv), struct omap_mcbsp_data, bus_id)
@@ -257,7 +259,7 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
257 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 259 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
258 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT; 260 int wlen, channels, wpf, sync_mode = OMAP_DMA_SYNC_ELEMENT;
259 unsigned long port; 261 unsigned long port;
260 unsigned int format; 262 unsigned int format, div, framesize, master;
261 263
262 if (cpu_class_is_omap1()) { 264 if (cpu_class_is_omap1()) {
263 dma = omap1_dma_reqs[bus_id][substream->stream]; 265 dma = omap1_dma_reqs[bus_id][substream->stream];
@@ -294,28 +296,19 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
294 296
295 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK; 297 format = mcbsp_data->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
296 wpf = channels = params_channels(params); 298 wpf = channels = params_channels(params);
297 switch (channels) { 299 if (channels == 2 && format == SND_SOC_DAIFMT_I2S) {
298 case 2: 300 /* Use dual-phase frames */
299 if (format == SND_SOC_DAIFMT_I2S) { 301 regs->rcr2 |= RPHASE;
300 /* Use dual-phase frames */ 302 regs->xcr2 |= XPHASE;
301 regs->rcr2 |= RPHASE; 303 /* Set 1 word per (McBSP) frame for phase1 and phase2 */
302 regs->xcr2 |= XPHASE; 304 wpf--;
303 /* Set 1 word per (McBSP) frame for phase1 and phase2 */ 305 regs->rcr2 |= RFRLEN2(wpf - 1);
304 wpf--; 306 regs->xcr2 |= XFRLEN2(wpf - 1);
305 regs->rcr2 |= RFRLEN2(wpf - 1);
306 regs->xcr2 |= XFRLEN2(wpf - 1);
307 }
308 case 1:
309 case 4:
310 /* Set word per (McBSP) frame for phase1 */
311 regs->rcr1 |= RFRLEN1(wpf - 1);
312 regs->xcr1 |= XFRLEN1(wpf - 1);
313 break;
314 default:
315 /* Unsupported number of channels */
316 return -EINVAL;
317 } 307 }
318 308
309 regs->rcr1 |= RFRLEN1(wpf - 1);
310 regs->xcr1 |= XFRLEN1(wpf - 1);
311
319 switch (params_format(params)) { 312 switch (params_format(params)) {
320 case SNDRV_PCM_FORMAT_S16_LE: 313 case SNDRV_PCM_FORMAT_S16_LE:
321 /* Set word lengths */ 314 /* Set word lengths */
@@ -330,15 +323,30 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
330 return -EINVAL; 323 return -EINVAL;
331 } 324 }
332 325
326 /* In McBSP master modes, FRAME (i.e. sample rate) is generated
327 * by _counting_ BCLKs. Calculate frame size in BCLKs */
328 master = mcbsp_data->fmt & SND_SOC_DAIFMT_MASTER_MASK;
329 if (master == SND_SOC_DAIFMT_CBS_CFS) {
330 div = mcbsp_data->clk_div ? mcbsp_data->clk_div : 1;
331 framesize = (mcbsp_data->in_freq / div) / params_rate(params);
332
333 if (framesize < wlen * channels) {
334 printk(KERN_ERR "%s: not enough bandwidth for desired rate and "
335 "channels\n", __func__);
336 return -EINVAL;
337 }
338 } else
339 framesize = wlen * channels;
340
333 /* Set FS period and length in terms of bit clock periods */ 341 /* Set FS period and length in terms of bit clock periods */
334 switch (format) { 342 switch (format) {
335 case SND_SOC_DAIFMT_I2S: 343 case SND_SOC_DAIFMT_I2S:
336 regs->srgr2 |= FPER(wlen * channels - 1); 344 regs->srgr2 |= FPER(framesize - 1);
337 regs->srgr1 |= FWID(wlen - 1); 345 regs->srgr1 |= FWID((framesize >> 1) - 1);
338 break; 346 break;
339 case SND_SOC_DAIFMT_DSP_A: 347 case SND_SOC_DAIFMT_DSP_A:
340 case SND_SOC_DAIFMT_DSP_B: 348 case SND_SOC_DAIFMT_DSP_B:
341 regs->srgr2 |= FPER(wlen * channels - 1); 349 regs->srgr2 |= FPER(framesize - 1);
342 regs->srgr1 |= FWID(0); 350 regs->srgr1 |= FWID(0);
343 break; 351 break;
344 } 352 }
@@ -454,6 +462,7 @@ static int omap_mcbsp_dai_set_clkdiv(struct snd_soc_dai *cpu_dai,
454 if (div_id != OMAP_MCBSP_CLKGDV) 462 if (div_id != OMAP_MCBSP_CLKGDV)
455 return -ENODEV; 463 return -ENODEV;
456 464
465 mcbsp_data->clk_div = div;
457 regs->srgr1 |= CLKGDV(div - 1); 466 regs->srgr1 |= CLKGDV(div - 1);
458 467
459 return 0; 468 return 0;
@@ -554,6 +563,8 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
554 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 563 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
555 int err = 0; 564 int err = 0;
556 565
566 mcbsp_data->in_freq = freq;
567
557 switch (clk_id) { 568 switch (clk_id) {
558 case OMAP_MCBSP_SYSCLK_CLK: 569 case OMAP_MCBSP_SYSCLK_CLK:
559 regs->srgr2 |= CLKSM; 570 regs->srgr2 |= CLKSM;
@@ -598,13 +609,13 @@ static struct snd_soc_dai_ops omap_mcbsp_dai_ops = {
598 .id = (link_id), \ 609 .id = (link_id), \
599 .playback = { \ 610 .playback = { \
600 .channels_min = 1, \ 611 .channels_min = 1, \
601 .channels_max = 4, \ 612 .channels_max = 16, \
602 .rates = OMAP_MCBSP_RATES, \ 613 .rates = OMAP_MCBSP_RATES, \
603 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 614 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
604 }, \ 615 }, \
605 .capture = { \ 616 .capture = { \
606 .channels_min = 1, \ 617 .channels_min = 1, \
607 .channels_max = 4, \ 618 .channels_max = 16, \
608 .rates = OMAP_MCBSP_RATES, \ 619 .rates = OMAP_MCBSP_RATES, \
609 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 620 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
610 }, \ 621 }, \
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index 5735945788bf..9db2770e9640 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -28,7 +28,7 @@
28#include <sound/pcm_params.h> 28#include <sound/pcm_params.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30 30
31#include <mach/dma.h> 31#include <plat/dma.h>
32#include "omap-pcm.h" 32#include "omap-pcm.h"
33 33
34static const struct snd_pcm_hardware omap_pcm_hardware = { 34static const struct snd_pcm_hardware omap_pcm_hardware = {
@@ -195,8 +195,12 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
195 else 195 else
196 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); 196 omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ);
197 197
198 omap_set_dma_src_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16); 198 if (!(cpu_class_is_omap1())) {
199 omap_set_dma_dest_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16); 199 omap_set_dma_src_burst_mode(prtd->dma_ch,
200 OMAP_DMA_DATA_BURST_16);
201 omap_set_dma_dest_burst_mode(prtd->dma_ch,
202 OMAP_DMA_DATA_BURST_16);
203 }
200 204
201 return 0; 205 return 0;
202} 206}
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
index 027e1a40f8a1..c7adea38274c 100644
--- a/sound/soc/omap/omap2evm.c
+++ b/sound/soc/omap/omap2evm.c
@@ -31,7 +31,7 @@
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <mach/gpio.h> 33#include <mach/gpio.h>
34#include <mach/mcbsp.h> 34#include <plat/mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index b0cff9f33b7e..d88ad5ca526c 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -29,7 +29,7 @@
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/gpio.h> 31#include <mach/gpio.h>
32#include <mach/mcbsp.h> 32#include <plat/mcbsp.h>
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 9114c263077b..dfcb344092e4 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -27,7 +27,7 @@
27#include <asm/mach-types.h> 27#include <asm/mach-types.h>
28#include <mach/hardware.h> 28#include <mach/hardware.h>
29#include <mach/gpio.h> 29#include <mach/gpio.h>
30#include <mach/mcbsp.h> 30#include <plat/mcbsp.h>
31 31
32#include "omap-mcbsp.h" 32#include "omap-mcbsp.h"
33#include "omap-pcm.h" 33#include "omap-pcm.h"
@@ -93,10 +93,17 @@ static struct snd_soc_card snd_soc_omap3evm = {
93 .num_links = 1, 93 .num_links = 1,
94}; 94};
95 95
96/* twl4030 setup */
97static struct twl4030_setup_data twl4030_setup = {
98 .ramp_delay_value = 4,
99 .sysclk = 26000,
100};
101
96/* Audio subsystem */ 102/* Audio subsystem */
97static struct snd_soc_device omap3evm_snd_devdata = { 103static struct snd_soc_device omap3evm_snd_devdata = {
98 .card = &snd_soc_omap3evm, 104 .card = &snd_soc_omap3evm,
99 .codec_dev = &soc_codec_dev_twl4030, 105 .codec_dev = &soc_codec_dev_twl4030,
106 .codec_data = &twl4030_setup,
100}; 107};
101 108
102static struct platform_device *omap3evm_snd_device; 109static struct platform_device *omap3evm_snd_device;
@@ -144,4 +151,4 @@ module_exit(omap3evm_soc_exit);
144 151
145MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>"); 152MODULE_AUTHOR("Anuj Aggarwal <anuj.aggarwal@ti.com>");
146MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM"); 153MODULE_DESCRIPTION("ALSA SoC OMAP3 EVM");
147MODULE_LICENSE("GPLv2"); 154MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index ad219aaf7cb8..71b2c161158d 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -40,9 +40,12 @@
40 40
41#define PREFIX "ASoC omap3pandora: " 41#define PREFIX "ASoC omap3pandora: "
42 42
43static int omap3pandora_cmn_hw_params(struct snd_soc_dai *codec_dai, 43static int omap3pandora_cmn_hw_params(struct snd_pcm_substream *substream,
44 struct snd_soc_dai *cpu_dai, unsigned int fmt) 44 struct snd_pcm_hw_params *params, unsigned int fmt)
45{ 45{
46 struct snd_soc_pcm_runtime *rtd = substream->private_data;
47 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
48 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
46 int ret; 49 int ret;
47 50
48 /* Set codec DAI configuration */ 51 /* Set codec DAI configuration */
@@ -68,8 +71,9 @@ static int omap3pandora_cmn_hw_params(struct snd_soc_dai *codec_dai,
68 } 71 }
69 72
70 /* Set McBSP clock to external */ 73 /* Set McBSP clock to external */
71 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT, 0, 74 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT,
72 SND_SOC_CLOCK_IN); 75 256 * params_rate(params),
76 SND_SOC_CLOCK_IN);
73 if (ret < 0) { 77 if (ret < 0) {
74 pr_err(PREFIX "can't set cpu system clock\n"); 78 pr_err(PREFIX "can't set cpu system clock\n");
75 return ret; 79 return ret;
@@ -87,11 +91,7 @@ static int omap3pandora_cmn_hw_params(struct snd_soc_dai *codec_dai,
87static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream, 91static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params) 92 struct snd_pcm_hw_params *params)
89{ 93{
90 struct snd_soc_pcm_runtime *rtd = substream->private_data; 94 return omap3pandora_cmn_hw_params(substream, params,
91 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
92 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
93
94 return omap3pandora_cmn_hw_params(codec_dai, cpu_dai,
95 SND_SOC_DAIFMT_I2S | 95 SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_IB_NF | 96 SND_SOC_DAIFMT_IB_NF |
97 SND_SOC_DAIFMT_CBS_CFS); 97 SND_SOC_DAIFMT_CBS_CFS);
@@ -100,11 +100,7 @@ static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream,
100static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream, 100static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream,
101 struct snd_pcm_hw_params *params) 101 struct snd_pcm_hw_params *params)
102{ 102{
103 struct snd_soc_pcm_runtime *rtd = substream->private_data; 103 return omap3pandora_cmn_hw_params(substream, params,
104 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
105 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
106
107 return omap3pandora_cmn_hw_params(codec_dai, cpu_dai,
108 SND_SOC_DAIFMT_I2S | 104 SND_SOC_DAIFMT_I2S |
109 SND_SOC_DAIFMT_NB_NF | 105 SND_SOC_DAIFMT_NB_NF |
110 SND_SOC_DAIFMT_CBS_CFS); 106 SND_SOC_DAIFMT_CBS_CFS);
@@ -134,7 +130,7 @@ static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
134 * |P| <--- TWL4030 <--------- Line In and MICs 130 * |P| <--- TWL4030 <--------- Line In and MICs
135 */ 131 */
136static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = { 132static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
137 SND_SOC_DAPM_DAC("PCM DAC", "Playback", SND_SOC_NOPM, 0, 0), 133 SND_SOC_DAPM_DAC("PCM DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0),
138 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM, 134 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
139 0, 0, NULL, 0, omap3pandora_hp_event, 135 0, 0, NULL, 0, omap3pandora_hp_event,
140 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 136 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
@@ -181,6 +177,7 @@ static int omap3pandora_out_init(struct snd_soc_codec *codec)
181 snd_soc_dapm_nc_pin(codec, "CARKITR"); 177 snd_soc_dapm_nc_pin(codec, "CARKITR");
182 snd_soc_dapm_nc_pin(codec, "HFL"); 178 snd_soc_dapm_nc_pin(codec, "HFL");
183 snd_soc_dapm_nc_pin(codec, "HFR"); 179 snd_soc_dapm_nc_pin(codec, "HFR");
180 snd_soc_dapm_nc_pin(codec, "VIBRA");
184 181
185 ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets, 182 ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets,
186 ARRAY_SIZE(omap3pandora_out_dapm_widgets)); 183 ARRAY_SIZE(omap3pandora_out_dapm_widgets));
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index a4e149b7f0eb..498ca2e03519 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -31,7 +31,7 @@
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <linux/gpio.h> 33#include <linux/gpio.h>
34#include <mach/mcbsp.h> 34#include <plat/mcbsp.h>
35 35
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index ec4f8fd8b3a2..c25f5276ad6f 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -29,7 +29,7 @@
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/gpio.h> 31#include <mach/gpio.h>
32#include <mach/mcbsp.h> 32#include <plat/mcbsp.h>
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
@@ -107,8 +107,8 @@ static int __init overo_soc_init(void)
107{ 107{
108 int ret; 108 int ret;
109 109
110 if (!machine_is_overo()) { 110 if (!(machine_is_overo() || machine_is_cm_t35())) {
111 pr_debug("Not Overo!\n"); 111 pr_debug("Incomatible machine!\n");
112 return -ENODEV; 112 return -ENODEV;
113 } 113 }
114 printk(KERN_INFO "overo SoC init\n"); 114 printk(KERN_INFO "overo SoC init\n");
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 4a3f62d1f295..c071f9603a38 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -34,7 +34,7 @@
34#include <asm/mach-types.h> 34#include <asm/mach-types.h>
35#include <mach/hardware.h> 35#include <mach/hardware.h>
36#include <mach/gpio.h> 36#include <mach/gpio.h>
37#include <mach/mcbsp.h> 37#include <plat/mcbsp.h>
38 38
39#include "omap-mcbsp.h" 39#include "omap-mcbsp.h"
40#include "omap-pcm.h" 40#include "omap-pcm.h"
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index f90b45f56220..f90a2ac888cf 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -29,7 +29,7 @@
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/gpio.h> 31#include <mach/gpio.h>
32#include <mach/mcbsp.h> 32#include <plat/mcbsp.h>
33 33
34#include "omap-mcbsp.h" 34#include "omap-mcbsp.h"
35#include "omap-pcm.h" 35#include "omap-pcm.h"
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index dcb3181bb340..376e14a9c273 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -90,7 +90,8 @@ config SND_PXA2XX_SOC_E800
90 90
91config SND_PXA2XX_SOC_EM_X270 91config SND_PXA2XX_SOC_EM_X270
92 tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300" 92 tristate "SoC Audio support for CompuLab EM-x270, eXeda and CM-X300"
93 depends on SND_PXA2XX_SOC && MACH_EM_X270 93 depends on SND_PXA2XX_SOC && (MACH_EM_X270 || MACH_EXEDA || \
94 MACH_CM_X300)
94 select SND_PXA2XX_SOC_AC97 95 select SND_PXA2XX_SOC_AC97
95 select SND_SOC_WM9712 96 select SND_SOC_WM9712
96 help 97 help
@@ -117,6 +118,15 @@ config SND_SOC_ZYLONITE
117 Say Y if you want to add support for SoC audio on the 118 Say Y if you want to add support for SoC audio on the
118 Marvell Zylonite reference platform. 119 Marvell Zylonite reference platform.
119 120
121config SND_SOC_RAUMFELD
122 tristate "SoC Audio support Raumfeld audio adapter"
123 depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR)
124 select SND_PXA_SOC_SSP
125 select SND_SOC_CS4270
126 select SND_SOC_AK4104
127 help
128 Say Y if you want to add support for SoC audio on Raumfeld devices
129
120config SND_PXA2XX_SOC_MAGICIAN 130config SND_PXA2XX_SOC_MAGICIAN
121 tristate "SoC Audio support for HTC Magician" 131 tristate "SoC Audio support for HTC Magician"
122 depends on SND_PXA2XX_SOC && MACH_MAGICIAN 132 depends on SND_PXA2XX_SOC && MACH_MAGICIAN
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 6e096b480335..f3e08fd40ca2 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -23,6 +23,7 @@ snd-soc-zylonite-objs := zylonite.o
23snd-soc-magician-objs := magician.o 23snd-soc-magician-objs := magician.o
24snd-soc-mioa701-objs := mioa701_wm9713.o 24snd-soc-mioa701-objs := mioa701_wm9713.o
25snd-soc-imote2-objs := imote2.o 25snd-soc-imote2-objs := imote2.o
26snd-soc-raumfeld-objs := raumfeld.o
26 27
27obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 28obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
28obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 29obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -37,3 +38,4 @@ obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o
37obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o 38obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o
38obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 39obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
39obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o 40obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
41obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 9f7c61e23daf..4c8d99a8d386 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -213,7 +213,7 @@ static int magician_playback_hw_params(struct snd_pcm_substream *substream,
213 return ret; 213 return ret;
214 214
215 /* set SSP audio pll clock */ 215 /* set SSP audio pll clock */
216 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, acps); 216 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, acps);
217 if (ret < 0) 217 if (ret < 0)
218 return ret; 218 return ret;
219 219
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index d11a6d7e384a..3bd7712f029b 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -305,8 +305,8 @@ static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
305/* 305/*
306 * Configure the PLL frequency pxa27x and (afaik - pxa320 only) 306 * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
307 */ 307 */
308static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, 308static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
309 int pll_id, unsigned int freq_in, unsigned int freq_out) 309 int source, unsigned int freq_in, unsigned int freq_out)
310{ 310{
311 struct ssp_priv *priv = cpu_dai->private_data; 311 struct ssp_priv *priv = cpu_dai->private_data;
312 struct ssp_device *ssp = priv->dev.ssp; 312 struct ssp_device *ssp = priv->dev.ssp;
@@ -760,13 +760,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
760 .resume = pxa_ssp_resume, 760 .resume = pxa_ssp_resume,
761 .playback = { 761 .playback = {
762 .channels_min = 1, 762 .channels_min = 1,
763 .channels_max = 2, 763 .channels_max = 8,
764 .rates = PXA_SSP_RATES, 764 .rates = PXA_SSP_RATES,
765 .formats = PXA_SSP_FORMATS, 765 .formats = PXA_SSP_FORMATS,
766 }, 766 },
767 .capture = { 767 .capture = {
768 .channels_min = 1, 768 .channels_min = 1,
769 .channels_max = 2, 769 .channels_max = 8,
770 .rates = PXA_SSP_RATES, 770 .rates = PXA_SSP_RATES,
771 .formats = PXA_SSP_FORMATS, 771 .formats = PXA_SSP_FORMATS,
772 }, 772 },
@@ -780,13 +780,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
780 .resume = pxa_ssp_resume, 780 .resume = pxa_ssp_resume,
781 .playback = { 781 .playback = {
782 .channels_min = 1, 782 .channels_min = 1,
783 .channels_max = 2, 783 .channels_max = 8,
784 .rates = PXA_SSP_RATES, 784 .rates = PXA_SSP_RATES,
785 .formats = PXA_SSP_FORMATS, 785 .formats = PXA_SSP_FORMATS,
786 }, 786 },
787 .capture = { 787 .capture = {
788 .channels_min = 1, 788 .channels_min = 1,
789 .channels_max = 2, 789 .channels_max = 8,
790 .rates = PXA_SSP_RATES, 790 .rates = PXA_SSP_RATES,
791 .formats = PXA_SSP_FORMATS, 791 .formats = PXA_SSP_FORMATS,
792 }, 792 },
@@ -801,13 +801,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
801 .resume = pxa_ssp_resume, 801 .resume = pxa_ssp_resume,
802 .playback = { 802 .playback = {
803 .channels_min = 1, 803 .channels_min = 1,
804 .channels_max = 2, 804 .channels_max = 8,
805 .rates = PXA_SSP_RATES, 805 .rates = PXA_SSP_RATES,
806 .formats = PXA_SSP_FORMATS, 806 .formats = PXA_SSP_FORMATS,
807 }, 807 },
808 .capture = { 808 .capture = {
809 .channels_min = 1, 809 .channels_min = 1,
810 .channels_max = 2, 810 .channels_max = 8,
811 .rates = PXA_SSP_RATES, 811 .rates = PXA_SSP_RATES,
812 .formats = PXA_SSP_FORMATS, 812 .formats = PXA_SSP_FORMATS,
813 }, 813 },
@@ -822,13 +822,13 @@ struct snd_soc_dai pxa_ssp_dai[] = {
822 .resume = pxa_ssp_resume, 822 .resume = pxa_ssp_resume,
823 .playback = { 823 .playback = {
824 .channels_min = 1, 824 .channels_min = 1,
825 .channels_max = 2, 825 .channels_max = 8,
826 .rates = PXA_SSP_RATES, 826 .rates = PXA_SSP_RATES,
827 .formats = PXA_SSP_FORMATS, 827 .formats = PXA_SSP_FORMATS,
828 }, 828 },
829 .capture = { 829 .capture = {
830 .channels_min = 1, 830 .channels_min = 1,
831 .channels_max = 2, 831 .channels_max = 8,
832 .rates = PXA_SSP_RATES, 832 .rates = PXA_SSP_RATES,
833 .formats = PXA_SSP_FORMATS, 833 .formats = PXA_SSP_FORMATS,
834 }, 834 },
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
new file mode 100644
index 000000000000..acfce1c0f1c9
--- /dev/null
+++ b/sound/soc/pxa/raumfeld.c
@@ -0,0 +1,335 @@
1/*
2 * raumfeld_audio.c -- SoC audio for Raumfeld audio devices
3 *
4 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
5 *
6 * based on code from:
7 *
8 * Wolfson Microelectronics PLC.
9 * Openedhand Ltd.
10 * Liam Girdwood <lrg@slimlogic.co.uk>
11 * Richard Purdie <richard@openedhand.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#include <linux/module.h>
20#include <linux/i2c.h>
21#include <linux/delay.h>
22#include <linux/gpio.h>
23#include <sound/pcm.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26
27#include <asm/mach-types.h>
28
29#include "../codecs/cs4270.h"
30#include "../codecs/ak4104.h"
31#include "pxa2xx-pcm.h"
32#include "pxa-ssp.h"
33
34#define GPIO_SPDIF_RESET (38)
35#define GPIO_MCLK_RESET (111)
36#define GPIO_CODEC_RESET (120)
37
38static struct i2c_client *max9486_client;
39static struct i2c_board_info max9486_hwmon_info = {
40 I2C_BOARD_INFO("max9485", 0x63),
41};
42
43#define MAX9485_MCLK_FREQ_112896 0x22
44#define MAX9485_MCLK_FREQ_122880 0x23
45
46static void set_max9485_clk(char clk)
47{
48 i2c_master_send(max9486_client, &clk, 1);
49}
50
51static void raumfeld_enable_audio(bool en)
52{
53 if (en) {
54 gpio_set_value(GPIO_MCLK_RESET, 1);
55
56 /* wait some time to let the clocks become stable */
57 msleep(100);
58
59 gpio_set_value(GPIO_SPDIF_RESET, 1);
60 gpio_set_value(GPIO_CODEC_RESET, 1);
61 } else {
62 gpio_set_value(GPIO_MCLK_RESET, 0);
63 gpio_set_value(GPIO_SPDIF_RESET, 0);
64 gpio_set_value(GPIO_CODEC_RESET, 0);
65 }
66}
67
68/* CS4270 */
69static int raumfeld_cs4270_startup(struct snd_pcm_substream *substream)
70{
71 struct snd_soc_pcm_runtime *rtd = substream->private_data;
72 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
73
74 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
75
76 return snd_soc_dai_set_sysclk(codec_dai, 0, 11289600, 0);
77}
78
79static int raumfeld_cs4270_hw_params(struct snd_pcm_substream *substream,
80 struct snd_pcm_hw_params *params)
81{
82 struct snd_soc_pcm_runtime *rtd = substream->private_data;
83 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
84 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
85 unsigned int fmt, clk = 0;
86 int ret = 0;
87
88 switch (params_rate(params)) {
89 case 8000:
90 case 16000:
91 case 48000:
92 case 96000:
93 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
94 clk = 12288000;
95 break;
96 case 11025:
97 case 22050:
98 case 44100:
99 case 88200:
100 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
101 clk = 11289600;
102 break;
103 }
104
105 fmt = SND_SOC_DAIFMT_I2S |
106 SND_SOC_DAIFMT_NB_NF |
107 SND_SOC_DAIFMT_CBS_CFS;
108
109 /* setup the CODEC DAI */
110 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
111 if (ret < 0)
112 return ret;
113
114 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, 0);
115 if (ret < 0)
116 return ret;
117
118 /* setup the CPU DAI */
119 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
120 if (ret < 0)
121 return ret;
122
123 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
124 if (ret < 0)
125 return ret;
126
127 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
128 if (ret < 0)
129 return ret;
130
131 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, 0, 1);
132 if (ret < 0)
133 return ret;
134
135 return 0;
136}
137
138static struct snd_soc_ops raumfeld_cs4270_ops = {
139 .startup = raumfeld_cs4270_startup,
140 .hw_params = raumfeld_cs4270_hw_params,
141};
142
143static int raumfeld_line_suspend(struct platform_device *pdev, pm_message_t state)
144{
145 raumfeld_enable_audio(false);
146 return 0;
147}
148
149static int raumfeld_line_resume(struct platform_device *pdev)
150{
151 raumfeld_enable_audio(true);
152 return 0;
153}
154
155static struct snd_soc_dai_link raumfeld_line_dai = {
156 .name = "CS4270",
157 .stream_name = "CS4270",
158 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP1],
159 .codec_dai = &cs4270_dai,
160 .ops = &raumfeld_cs4270_ops,
161};
162
163static struct snd_soc_card snd_soc_line_raumfeld = {
164 .name = "Raumfeld analog",
165 .platform = &pxa2xx_soc_platform,
166 .dai_link = &raumfeld_line_dai,
167 .suspend_post = raumfeld_line_suspend,
168 .resume_pre = raumfeld_line_resume,
169 .num_links = 1,
170};
171
172
173/* AK4104 */
174
175static int raumfeld_ak4104_hw_params(struct snd_pcm_substream *substream,
176 struct snd_pcm_hw_params *params)
177{
178 struct snd_soc_pcm_runtime *rtd = substream->private_data;
179 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
180 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
181 int fmt, ret = 0, clk = 0;
182
183 switch (params_rate(params)) {
184 case 8000:
185 case 16000:
186 case 48000:
187 case 96000:
188 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
189 clk = 12288000;
190 break;
191 case 11025:
192 case 22050:
193 case 44100:
194 case 88200:
195 set_max9485_clk(MAX9485_MCLK_FREQ_112896);
196 clk = 11289600;
197 break;
198 }
199
200 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF;
201
202 /* setup the CODEC DAI */
203 ret = snd_soc_dai_set_fmt(codec_dai, fmt | SND_SOC_DAIFMT_CBS_CFS);
204 if (ret < 0)
205 return ret;
206
207 /* setup the CPU DAI */
208 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, clk);
209 if (ret < 0)
210 return ret;
211
212 ret = snd_soc_dai_set_fmt(cpu_dai, fmt | SND_SOC_DAIFMT_CBS_CFS);
213 if (ret < 0)
214 return ret;
215
216 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_DIV_SCR, 4);
217 if (ret < 0)
218 return ret;
219
220 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_EXT, 0, 1);
221 if (ret < 0)
222 return ret;
223
224 return 0;
225}
226
227static struct snd_soc_ops raumfeld_ak4104_ops = {
228 .hw_params = raumfeld_ak4104_hw_params,
229};
230
231static struct snd_soc_dai_link raumfeld_spdif_dai = {
232 .name = "ak4104",
233 .stream_name = "Playback",
234 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP2],
235 .codec_dai = &ak4104_dai,
236 .ops = &raumfeld_ak4104_ops,
237};
238
239static struct snd_soc_card snd_soc_spdif_raumfeld = {
240 .name = "Raumfeld S/PDIF",
241 .platform = &pxa2xx_soc_platform,
242 .dai_link = &raumfeld_spdif_dai,
243 .num_links = 1
244};
245
246/* raumfeld_audio audio subsystem */
247static struct snd_soc_device raumfeld_line_devdata = {
248 .card = &snd_soc_line_raumfeld,
249 .codec_dev = &soc_codec_device_cs4270,
250};
251
252static struct snd_soc_device raumfeld_spdif_devdata = {
253 .card = &snd_soc_spdif_raumfeld,
254 .codec_dev = &soc_codec_device_ak4104,
255};
256
257static struct platform_device *raumfeld_audio_line_device;
258static struct platform_device *raumfeld_audio_spdif_device;
259
260static int __init raumfeld_audio_init(void)
261{
262 int ret;
263
264 if (!machine_is_raumfeld_speaker() &&
265 !machine_is_raumfeld_connector())
266 return 0;
267
268 max9486_client = i2c_new_device(i2c_get_adapter(0),
269 &max9486_hwmon_info);
270
271 if (!max9486_client)
272 return -ENOMEM;
273
274 set_max9485_clk(MAX9485_MCLK_FREQ_122880);
275
276 /* LINE */
277 raumfeld_audio_line_device = platform_device_alloc("soc-audio", 0);
278 if (!raumfeld_audio_line_device)
279 return -ENOMEM;
280
281 platform_set_drvdata(raumfeld_audio_line_device,
282 &raumfeld_line_devdata);
283 raumfeld_line_devdata.dev = &raumfeld_audio_line_device->dev;
284 ret = platform_device_add(raumfeld_audio_line_device);
285 if (ret)
286 platform_device_put(raumfeld_audio_line_device);
287
288 /* no S/PDIF on Speakers */
289 if (machine_is_raumfeld_speaker())
290 return ret;
291
292 /* S/PDIF */
293 raumfeld_audio_spdif_device = platform_device_alloc("soc-audio", 1);
294 if (!raumfeld_audio_spdif_device) {
295 platform_device_put(raumfeld_audio_line_device);
296 return -ENOMEM;
297 }
298
299 platform_set_drvdata(raumfeld_audio_spdif_device,
300 &raumfeld_spdif_devdata);
301 raumfeld_spdif_devdata.dev = &raumfeld_audio_spdif_device->dev;
302 ret = platform_device_add(raumfeld_audio_spdif_device);
303 if (ret) {
304 platform_device_put(raumfeld_audio_line_device);
305 platform_device_put(raumfeld_audio_spdif_device);
306 }
307
308 raumfeld_enable_audio(true);
309
310 return ret;
311}
312
313static void __exit raumfeld_audio_exit(void)
314{
315 raumfeld_enable_audio(false);
316
317 platform_device_unregister(raumfeld_audio_line_device);
318
319 if (machine_is_raumfeld_connector())
320 platform_device_unregister(raumfeld_audio_spdif_device);
321
322 i2c_unregister_device(max9486_client);
323
324 gpio_free(GPIO_MCLK_RESET);
325 gpio_free(GPIO_CODEC_RESET);
326 gpio_free(GPIO_SPDIF_RESET);
327}
328
329module_init(raumfeld_audio_init);
330module_exit(raumfeld_audio_exit);
331
332/* Module information */
333MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
334MODULE_DESCRIPTION("Raumfeld audio SoC");
335MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index 9a386b4c4ed1..dd678ae24398 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -74,7 +74,8 @@ static const struct snd_soc_dapm_route audio_map[] = {
74static int zylonite_wm9713_init(struct snd_soc_codec *codec) 74static int zylonite_wm9713_init(struct snd_soc_codec *codec)
75{ 75{
76 if (clk_pout) 76 if (clk_pout)
77 snd_soc_dai_set_pll(&codec->dai[0], 0, clk_get_rate(pout), 0); 77 snd_soc_dai_set_pll(&codec->dai[0], 0, 0,
78 clk_get_rate(pout), 0);
78 79
79 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, 80 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
80 ARRAY_SIZE(zylonite_dapm_widgets)); 81 ARRAY_SIZE(zylonite_dapm_widgets));
@@ -128,7 +129,7 @@ static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
128 if (ret < 0) 129 if (ret < 0)
129 return ret; 130 return ret;
130 131
131 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, pll_out); 132 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, 0, pll_out);
132 if (ret < 0) 133 if (ret < 0)
133 return ret; 134 return ret;
134 135
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index 923428fc1adb..b489f1ae103d 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -24,6 +24,9 @@ config SND_S3C64XX_SOC_I2S
24 select SND_S3C_I2SV2_SOC 24 select SND_S3C_I2SV2_SOC
25 select S3C64XX_DMA 25 select S3C64XX_DMA
26 26
27config SND_S3C_SOC_PCM
28 tristate
29
27config SND_S3C2443_SOC_AC97 30config SND_S3C2443_SOC_AC97
28 tristate 31 tristate
29 select S3C2410_DMA 32 select S3C2410_DMA
@@ -56,6 +59,15 @@ config SND_S3C24XX_SOC_JIVE_WM8750
56 help 59 help
57 Sat Y if you want to add support for SoC audio on the Jive. 60 Sat Y if you want to add support for SoC audio on the Jive.
58 61
62config SND_S3C64XX_SOC_WM8580
63 tristate "SoC I2S Audio support for WM8580 on SMDK64XX"
64 depends on SND_S3C24XX_SOC && (MACH_SMDK6400 || MACH_SMDK6410)
65 depends on BROKEN
66 select SND_SOC_WM8580
67 select SND_S3C64XX_SOC_I2S
68 help
69 Sat Y if you want to add support for SoC audio on the SMDK64XX.
70
59config SND_S3C24XX_SOC_SMDK2443_WM9710 71config SND_S3C24XX_SOC_SMDK2443_WM9710
60 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" 72 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
61 depends on SND_S3C24XX_SOC && MACH_SMDK2443 73 depends on SND_S3C24XX_SOC && MACH_SMDK2443
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 99f5a7dd3fc6..b744657733d7 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -1,10 +1,11 @@
1# S3c24XX Platform Support 1# S3c24XX Platform Support
2snd-soc-s3c24xx-objs := s3c24xx-pcm.o 2snd-soc-s3c24xx-objs := s3c-dma.o
3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o 3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o 4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o 5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o
6snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o 6snd-soc-s3c2443-ac97-objs := s3c2443-ac97.o
7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o 7snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
8snd-soc-s3c-pcm-objs := s3c-pcm.o
8 9
9obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o 10obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
10obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o 11obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
@@ -12,6 +13,7 @@ obj-$(CONFIG_SND_S3C2443_SOC_AC97) += snd-soc-s3c2443-ac97.o
12obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o 13obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
13obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o 14obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o
14obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o 15obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
16obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o
15 17
16# S3C24XX Machine Support 18# S3C24XX Machine Support
17snd-soc-jive-wm8750-objs := jive_wm8750.o 19snd-soc-jive-wm8750-objs := jive_wm8750.o
@@ -23,6 +25,7 @@ snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
23snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o 25snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
24snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o 26snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
25snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o 27snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
28snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o
26 29
27obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o 30obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
28obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 31obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@@ -33,4 +36,5 @@ obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
33obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o 36obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o
34obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o 37obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
35obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o 38obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
39obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o
36 40
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c
index 93e6c87b7399..59dc2c6b56d9 100644
--- a/sound/soc/s3c24xx/jive_wm8750.c
+++ b/sound/soc/s3c24xx/jive_wm8750.c
@@ -25,7 +25,7 @@
25 25
26#include <asm/mach-types.h> 26#include <asm/mach-types.h>
27 27
28#include "s3c24xx-pcm.h" 28#include "s3c-dma.h"
29#include "s3c2412-i2s.h" 29#include "s3c2412-i2s.h"
30 30
31#include "../codecs/wm8750.h" 31#include "../codecs/wm8750.h"
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c
index 12c71482d258..d00d359a03e6 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c
@@ -24,7 +24,7 @@
24#include <sound/soc-dapm.h> 24#include <sound/soc-dapm.h>
25 25
26#include "../codecs/ac97.h" 26#include "../codecs/ac97.h"
27#include "s3c24xx-pcm.h" 27#include "s3c-dma.h"
28#include "s3c24xx-ac97.h" 28#include "s3c24xx-ac97.h"
29 29
30static struct snd_soc_card ln2440sbc; 30static struct snd_soc_card ln2440sbc;
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
index 0c52e36ddd87..dea83d30a5c9 100644
--- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
@@ -32,7 +32,7 @@
32#include <asm/io.h> 32#include <asm/io.h>
33#include <mach/gta02.h> 33#include <mach/gta02.h>
34#include "../codecs/wm8753.h" 34#include "../codecs/wm8753.h"
35#include "s3c24xx-pcm.h" 35#include "s3c-dma.h"
36#include "s3c24xx-i2s.h" 36#include "s3c24xx-i2s.h"
37 37
38static struct snd_soc_card neo1973_gta02; 38static struct snd_soc_card neo1973_gta02;
@@ -119,7 +119,7 @@ static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream,
119 return ret; 119 return ret;
120 120
121 /* codec PLL input is PCLK/4 */ 121 /* codec PLL input is PCLK/4 */
122 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 122 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
123 iis_clkrate / 4, pll_out); 123 iis_clkrate / 4, pll_out);
124 if (ret < 0) 124 if (ret < 0)
125 return ret; 125 return ret;
@@ -133,7 +133,7 @@ static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream)
133 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 133 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
134 134
135 /* disable the PLL */ 135 /* disable the PLL */
136 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); 136 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
137} 137}
138 138
139/* 139/*
@@ -183,7 +183,7 @@ static int neo1973_gta02_voice_hw_params(
183 return ret; 183 return ret;
184 184
185 /* configue and enable PLL for 12.288MHz output */ 185 /* configue and enable PLL for 12.288MHz output */
186 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 186 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
187 iis_clkrate / 4, 12288000); 187 iis_clkrate / 4, 12288000);
188 if (ret < 0) 188 if (ret < 0)
189 return ret; 189 return ret;
@@ -197,7 +197,7 @@ static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream)
197 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 197 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
198 198
199 /* disable the PLL */ 199 /* disable the PLL */
200 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); 200 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
201} 201}
202 202
203static struct snd_soc_ops neo1973_gta02_voice_ops = { 203static struct snd_soc_ops neo1973_gta02_voice_ops = {
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 906709e6dd5f..0cb4f86f6d1e 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -29,7 +29,6 @@
29#include <mach/regs-clock.h> 29#include <mach/regs-clock.h>
30#include <mach/regs-gpio.h> 30#include <mach/regs-gpio.h>
31#include <mach/hardware.h> 31#include <mach/hardware.h>
32#include <plat/audio.h>
33#include <linux/io.h> 32#include <linux/io.h>
34#include <mach/spi-gpio.h> 33#include <mach/spi-gpio.h>
35 34
@@ -37,7 +36,7 @@
37 36
38#include "../codecs/wm8753.h" 37#include "../codecs/wm8753.h"
39#include "lm4857.h" 38#include "lm4857.h"
40#include "s3c24xx-pcm.h" 39#include "s3c-dma.h"
41#include "s3c24xx-i2s.h" 40#include "s3c24xx-i2s.h"
42 41
43/* define the scenarios */ 42/* define the scenarios */
@@ -137,7 +136,7 @@ static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
137 return ret; 136 return ret;
138 137
139 /* codec PLL input is PCLK/4 */ 138 /* codec PLL input is PCLK/4 */
140 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 139 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0,
141 iis_clkrate / 4, pll_out); 140 iis_clkrate / 4, pll_out);
142 if (ret < 0) 141 if (ret < 0)
143 return ret; 142 return ret;
@@ -153,7 +152,7 @@ static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream)
153 pr_debug("Entered %s\n", __func__); 152 pr_debug("Entered %s\n", __func__);
154 153
155 /* disable the PLL */ 154 /* disable the PLL */
156 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0); 155 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0);
157} 156}
158 157
159/* 158/*
@@ -203,7 +202,7 @@ static int neo1973_voice_hw_params(struct snd_pcm_substream *substream,
203 return ret; 202 return ret;
204 203
205 /* configue and enable PLL for 12.288MHz output */ 204 /* configue and enable PLL for 12.288MHz output */
206 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 205 ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0,
207 iis_clkrate / 4, 12288000); 206 iis_clkrate / 4, 12288000);
208 if (ret < 0) 207 if (ret < 0)
209 return ret; 208 return ret;
@@ -219,7 +218,7 @@ static int neo1973_voice_hw_free(struct snd_pcm_substream *substream)
219 pr_debug("Entered %s\n", __func__); 218 pr_debug("Entered %s\n", __func__);
220 219
221 /* disable the PLL */ 220 /* disable the PLL */
222 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0); 221 return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0);
223} 222}
224 223
225static struct snd_soc_ops neo1973_voice_ops = { 224static struct snd_soc_ops neo1973_voice_ops = {
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c-dma.c
index 5cbbdc80fde3..7725e26d6c91 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c-dma.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * s3c24xx-pcm.c -- ALSA Soc Audio Layer 2 * s3c-dma.c -- ALSA Soc Audio Layer
3 * 3 *
4 * (c) 2006 Wolfson Microelectronics PLC. 4 * (c) 2006 Wolfson Microelectronics PLC.
5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com 5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
@@ -29,11 +29,10 @@
29#include <asm/dma.h> 29#include <asm/dma.h>
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/dma.h> 31#include <mach/dma.h>
32#include <plat/audio.h>
33 32
34#include "s3c24xx-pcm.h" 33#include "s3c-dma.h"
35 34
36static const struct snd_pcm_hardware s3c24xx_pcm_hardware = { 35static const struct snd_pcm_hardware s3c_dma_hardware = {
37 .info = SNDRV_PCM_INFO_INTERLEAVED | 36 .info = SNDRV_PCM_INFO_INTERLEAVED |
38 SNDRV_PCM_INFO_BLOCK_TRANSFER | 37 SNDRV_PCM_INFO_BLOCK_TRANSFER |
39 SNDRV_PCM_INFO_MMAP | 38 SNDRV_PCM_INFO_MMAP |
@@ -63,23 +62,32 @@ struct s3c24xx_runtime_data {
63 dma_addr_t dma_start; 62 dma_addr_t dma_start;
64 dma_addr_t dma_pos; 63 dma_addr_t dma_pos;
65 dma_addr_t dma_end; 64 dma_addr_t dma_end;
66 struct s3c24xx_pcm_dma_params *params; 65 struct s3c_dma_params *params;
67}; 66};
68 67
69/* s3c24xx_pcm_enqueue 68/* s3c_dma_enqueue
70 * 69 *
71 * place a dma buffer onto the queue for the dma system 70 * place a dma buffer onto the queue for the dma system
72 * to handle. 71 * to handle.
73*/ 72*/
74static void s3c24xx_pcm_enqueue(struct snd_pcm_substream *substream) 73static void s3c_dma_enqueue(struct snd_pcm_substream *substream)
75{ 74{
76 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 75 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
77 dma_addr_t pos = prtd->dma_pos; 76 dma_addr_t pos = prtd->dma_pos;
77 unsigned int limit;
78 int ret; 78 int ret;
79 79
80 pr_debug("Entered %s\n", __func__); 80 pr_debug("Entered %s\n", __func__);
81 81
82 while (prtd->dma_loaded < prtd->dma_limit) { 82 if (s3c_dma_has_circular())
83 limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
84 else
85 limit = prtd->dma_limit;
86
87 pr_debug("%s: loaded %d, limit %d\n",
88 __func__, prtd->dma_loaded, limit);
89
90 while (prtd->dma_loaded < limit) {
83 unsigned long len = prtd->dma_period; 91 unsigned long len = prtd->dma_period;
84 92
85 pr_debug("dma_loaded: %d\n", prtd->dma_loaded); 93 pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
@@ -123,21 +131,21 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
123 snd_pcm_period_elapsed(substream); 131 snd_pcm_period_elapsed(substream);
124 132
125 spin_lock(&prtd->lock); 133 spin_lock(&prtd->lock);
126 if (prtd->state & ST_RUNNING) { 134 if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) {
127 prtd->dma_loaded--; 135 prtd->dma_loaded--;
128 s3c24xx_pcm_enqueue(substream); 136 s3c_dma_enqueue(substream);
129 } 137 }
130 138
131 spin_unlock(&prtd->lock); 139 spin_unlock(&prtd->lock);
132} 140}
133 141
134static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream, 142static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
135 struct snd_pcm_hw_params *params) 143 struct snd_pcm_hw_params *params)
136{ 144{
137 struct snd_pcm_runtime *runtime = substream->runtime; 145 struct snd_pcm_runtime *runtime = substream->runtime;
138 struct s3c24xx_runtime_data *prtd = runtime->private_data; 146 struct s3c24xx_runtime_data *prtd = runtime->private_data;
139 struct snd_soc_pcm_runtime *rtd = substream->private_data; 147 struct snd_soc_pcm_runtime *rtd = substream->private_data;
140 struct s3c24xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; 148 struct s3c_dma_params *dma = rtd->dai->cpu_dai->dma_data;
141 unsigned long totbytes = params_buffer_bytes(params); 149 unsigned long totbytes = params_buffer_bytes(params);
142 int ret = 0; 150 int ret = 0;
143 151
@@ -164,6 +172,11 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream,
164 printk(KERN_ERR "failed to get dma channel\n"); 172 printk(KERN_ERR "failed to get dma channel\n");
165 return ret; 173 return ret;
166 } 174 }
175
176 /* use the circular buffering if we have it available. */
177 if (s3c_dma_has_circular())
178 s3c2410_dma_setflags(prtd->params->channel,
179 S3C2410_DMAF_CIRCULAR);
167 } 180 }
168 181
169 s3c2410_dma_set_buffdone_fn(prtd->params->channel, 182 s3c2410_dma_set_buffdone_fn(prtd->params->channel,
@@ -185,7 +198,7 @@ static int s3c24xx_pcm_hw_params(struct snd_pcm_substream *substream,
185 return 0; 198 return 0;
186} 199}
187 200
188static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream) 201static int s3c_dma_hw_free(struct snd_pcm_substream *substream)
189{ 202{
190 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 203 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
191 204
@@ -202,7 +215,7 @@ static int s3c24xx_pcm_hw_free(struct snd_pcm_substream *substream)
202 return 0; 215 return 0;
203} 216}
204 217
205static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream) 218static int s3c_dma_prepare(struct snd_pcm_substream *substream)
206{ 219{
207 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 220 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
208 int ret = 0; 221 int ret = 0;
@@ -235,12 +248,12 @@ static int s3c24xx_pcm_prepare(struct snd_pcm_substream *substream)
235 prtd->dma_pos = prtd->dma_start; 248 prtd->dma_pos = prtd->dma_start;
236 249
237 /* enqueue dma buffers */ 250 /* enqueue dma buffers */
238 s3c24xx_pcm_enqueue(substream); 251 s3c_dma_enqueue(substream);
239 252
240 return ret; 253 return ret;
241} 254}
242 255
243static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) 256static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd)
244{ 257{
245 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 258 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data;
246 int ret = 0; 259 int ret = 0;
@@ -275,7 +288,7 @@ static int s3c24xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
275} 288}
276 289
277static snd_pcm_uframes_t 290static snd_pcm_uframes_t
278s3c24xx_pcm_pointer(struct snd_pcm_substream *substream) 291s3c_dma_pointer(struct snd_pcm_substream *substream)
279{ 292{
280 struct snd_pcm_runtime *runtime = substream->runtime; 293 struct snd_pcm_runtime *runtime = substream->runtime;
281 struct s3c24xx_runtime_data *prtd = runtime->private_data; 294 struct s3c24xx_runtime_data *prtd = runtime->private_data;
@@ -310,7 +323,7 @@ s3c24xx_pcm_pointer(struct snd_pcm_substream *substream)
310 return bytes_to_frames(substream->runtime, res); 323 return bytes_to_frames(substream->runtime, res);
311} 324}
312 325
313static int s3c24xx_pcm_open(struct snd_pcm_substream *substream) 326static int s3c_dma_open(struct snd_pcm_substream *substream)
314{ 327{
315 struct snd_pcm_runtime *runtime = substream->runtime; 328 struct snd_pcm_runtime *runtime = substream->runtime;
316 struct s3c24xx_runtime_data *prtd; 329 struct s3c24xx_runtime_data *prtd;
@@ -318,7 +331,7 @@ static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
318 pr_debug("Entered %s\n", __func__); 331 pr_debug("Entered %s\n", __func__);
319 332
320 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 333 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
321 snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware); 334 snd_soc_set_runtime_hwparams(substream, &s3c_dma_hardware);
322 335
323 prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); 336 prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
324 if (prtd == NULL) 337 if (prtd == NULL)
@@ -330,7 +343,7 @@ static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
330 return 0; 343 return 0;
331} 344}
332 345
333static int s3c24xx_pcm_close(struct snd_pcm_substream *substream) 346static int s3c_dma_close(struct snd_pcm_substream *substream)
334{ 347{
335 struct snd_pcm_runtime *runtime = substream->runtime; 348 struct snd_pcm_runtime *runtime = substream->runtime;
336 struct s3c24xx_runtime_data *prtd = runtime->private_data; 349 struct s3c24xx_runtime_data *prtd = runtime->private_data;
@@ -338,14 +351,14 @@ static int s3c24xx_pcm_close(struct snd_pcm_substream *substream)
338 pr_debug("Entered %s\n", __func__); 351 pr_debug("Entered %s\n", __func__);
339 352
340 if (!prtd) 353 if (!prtd)
341 pr_debug("s3c24xx_pcm_close called with prtd == NULL\n"); 354 pr_debug("s3c_dma_close called with prtd == NULL\n");
342 355
343 kfree(prtd); 356 kfree(prtd);
344 357
345 return 0; 358 return 0;
346} 359}
347 360
348static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream, 361static int s3c_dma_mmap(struct snd_pcm_substream *substream,
349 struct vm_area_struct *vma) 362 struct vm_area_struct *vma)
350{ 363{
351 struct snd_pcm_runtime *runtime = substream->runtime; 364 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -358,23 +371,23 @@ static int s3c24xx_pcm_mmap(struct snd_pcm_substream *substream,
358 runtime->dma_bytes); 371 runtime->dma_bytes);
359} 372}
360 373
361static struct snd_pcm_ops s3c24xx_pcm_ops = { 374static struct snd_pcm_ops s3c_dma_ops = {
362 .open = s3c24xx_pcm_open, 375 .open = s3c_dma_open,
363 .close = s3c24xx_pcm_close, 376 .close = s3c_dma_close,
364 .ioctl = snd_pcm_lib_ioctl, 377 .ioctl = snd_pcm_lib_ioctl,
365 .hw_params = s3c24xx_pcm_hw_params, 378 .hw_params = s3c_dma_hw_params,
366 .hw_free = s3c24xx_pcm_hw_free, 379 .hw_free = s3c_dma_hw_free,
367 .prepare = s3c24xx_pcm_prepare, 380 .prepare = s3c_dma_prepare,
368 .trigger = s3c24xx_pcm_trigger, 381 .trigger = s3c_dma_trigger,
369 .pointer = s3c24xx_pcm_pointer, 382 .pointer = s3c_dma_pointer,
370 .mmap = s3c24xx_pcm_mmap, 383 .mmap = s3c_dma_mmap,
371}; 384};
372 385
373static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 386static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
374{ 387{
375 struct snd_pcm_substream *substream = pcm->streams[stream].substream; 388 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
376 struct snd_dma_buffer *buf = &substream->dma_buffer; 389 struct snd_dma_buffer *buf = &substream->dma_buffer;
377 size_t size = s3c24xx_pcm_hardware.buffer_bytes_max; 390 size_t size = s3c_dma_hardware.buffer_bytes_max;
378 391
379 pr_debug("Entered %s\n", __func__); 392 pr_debug("Entered %s\n", __func__);
380 393
@@ -389,7 +402,7 @@ static int s3c24xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
389 return 0; 402 return 0;
390} 403}
391 404
392static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm) 405static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm)
393{ 406{
394 struct snd_pcm_substream *substream; 407 struct snd_pcm_substream *substream;
395 struct snd_dma_buffer *buf; 408 struct snd_dma_buffer *buf;
@@ -412,9 +425,9 @@ static void s3c24xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
412 } 425 }
413} 426}
414 427
415static u64 s3c24xx_pcm_dmamask = DMA_BIT_MASK(32); 428static u64 s3c_dma_mask = DMA_BIT_MASK(32);
416 429
417static int s3c24xx_pcm_new(struct snd_card *card, 430static int s3c_dma_new(struct snd_card *card,
418 struct snd_soc_dai *dai, struct snd_pcm *pcm) 431 struct snd_soc_dai *dai, struct snd_pcm *pcm)
419{ 432{
420 int ret = 0; 433 int ret = 0;
@@ -422,19 +435,19 @@ static int s3c24xx_pcm_new(struct snd_card *card,
422 pr_debug("Entered %s\n", __func__); 435 pr_debug("Entered %s\n", __func__);
423 436
424 if (!card->dev->dma_mask) 437 if (!card->dev->dma_mask)
425 card->dev->dma_mask = &s3c24xx_pcm_dmamask; 438 card->dev->dma_mask = &s3c_dma_mask;
426 if (!card->dev->coherent_dma_mask) 439 if (!card->dev->coherent_dma_mask)
427 card->dev->coherent_dma_mask = 0xffffffff; 440 card->dev->coherent_dma_mask = 0xffffffff;
428 441
429 if (dai->playback.channels_min) { 442 if (dai->playback.channels_min) {
430 ret = s3c24xx_pcm_preallocate_dma_buffer(pcm, 443 ret = s3c_preallocate_dma_buffer(pcm,
431 SNDRV_PCM_STREAM_PLAYBACK); 444 SNDRV_PCM_STREAM_PLAYBACK);
432 if (ret) 445 if (ret)
433 goto out; 446 goto out;
434 } 447 }
435 448
436 if (dai->capture.channels_min) { 449 if (dai->capture.channels_min) {
437 ret = s3c24xx_pcm_preallocate_dma_buffer(pcm, 450 ret = s3c_preallocate_dma_buffer(pcm,
438 SNDRV_PCM_STREAM_CAPTURE); 451 SNDRV_PCM_STREAM_CAPTURE);
439 if (ret) 452 if (ret)
440 goto out; 453 goto out;
@@ -445,9 +458,9 @@ static int s3c24xx_pcm_new(struct snd_card *card,
445 458
446struct snd_soc_platform s3c24xx_soc_platform = { 459struct snd_soc_platform s3c24xx_soc_platform = {
447 .name = "s3c24xx-audio", 460 .name = "s3c24xx-audio",
448 .pcm_ops = &s3c24xx_pcm_ops, 461 .pcm_ops = &s3c_dma_ops,
449 .pcm_new = s3c24xx_pcm_new, 462 .pcm_new = s3c_dma_new,
450 .pcm_free = s3c24xx_pcm_free_dma_buffers, 463 .pcm_free = s3c_dma_free_dma_buffers,
451}; 464};
452EXPORT_SYMBOL_GPL(s3c24xx_soc_platform); 465EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
453 466
@@ -464,5 +477,5 @@ static void __exit s3c24xx_soc_platform_exit(void)
464module_exit(s3c24xx_soc_platform_exit); 477module_exit(s3c24xx_soc_platform_exit);
465 478
466MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 479MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
467MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module"); 480MODULE_DESCRIPTION("Samsung S3C Audio DMA module");
468MODULE_LICENSE("GPL"); 481MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.h b/sound/soc/s3c24xx/s3c-dma.h
index 0088c79822ea..69bb6bf6fc1c 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.h
+++ b/sound/soc/s3c24xx/s3c-dma.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * s3c24xx-pcm.h -- 2 * s3c-dma.h --
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the 5 * under the terms of the GNU General Public License as published by the
@@ -9,13 +9,13 @@
9 * ALSA PCM interface for the Samsung S3C24xx CPU 9 * ALSA PCM interface for the Samsung S3C24xx CPU
10 */ 10 */
11 11
12#ifndef _S3C24XX_PCM_H 12#ifndef _S3C_AUDIO_H
13#define _S3C24XX_PCM_H 13#define _S3C_AUDIO_H
14 14
15#define ST_RUNNING (1<<0) 15#define ST_RUNNING (1<<0)
16#define ST_OPENED (1<<1) 16#define ST_OPENED (1<<1)
17 17
18struct s3c24xx_pcm_dma_params { 18struct s3c_dma_params {
19 struct s3c2410_dma_client *client; /* stream identifier */ 19 struct s3c2410_dma_client *client; /* stream identifier */
20 int channel; /* Channel ID */ 20 int channel; /* Channel ID */
21 dma_addr_t dma_addr; 21 dma_addr_t dma_addr;
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c
index 9bc4aa35caab..e994d8374fe6 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.c
@@ -32,11 +32,10 @@
32 32
33#include <plat/regs-s3c2412-iis.h> 33#include <plat/regs-s3c2412-iis.h>
34 34
35#include <plat/audio.h>
36#include <mach/dma.h> 35#include <mach/dma.h>
37 36
38#include "s3c-i2s-v2.h" 37#include "s3c-i2s-v2.h"
39#include "s3c24xx-pcm.h" 38#include "s3c-dma.h"
40 39
41#undef S3C_IIS_V2_SUPPORTED 40#undef S3C_IIS_V2_SUPPORTED
42 41
@@ -312,12 +311,15 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
312 311
313 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 312 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
314 case SND_SOC_DAIFMT_RIGHT_J: 313 case SND_SOC_DAIFMT_RIGHT_J:
314 iismod |= S3C2412_IISMOD_LR_RLOW;
315 iismod |= S3C2412_IISMOD_SDF_MSB; 315 iismod |= S3C2412_IISMOD_SDF_MSB;
316 break; 316 break;
317 case SND_SOC_DAIFMT_LEFT_J: 317 case SND_SOC_DAIFMT_LEFT_J:
318 iismod |= S3C2412_IISMOD_LR_RLOW;
318 iismod |= S3C2412_IISMOD_SDF_LSB; 319 iismod |= S3C2412_IISMOD_SDF_LSB;
319 break; 320 break;
320 case SND_SOC_DAIFMT_I2S: 321 case SND_SOC_DAIFMT_I2S:
322 iismod &= ~S3C2412_IISMOD_LR_RLOW;
321 iismod |= S3C2412_IISMOD_SDF_IIS; 323 iismod |= S3C2412_IISMOD_SDF_IIS;
322 break; 324 break;
323 default: 325 default:
@@ -392,7 +394,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
392 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 394 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
393 unsigned long irqs; 395 unsigned long irqs;
394 int ret = 0; 396 int ret = 0;
395 int channel = ((struct s3c24xx_pcm_dma_params *) 397 int channel = ((struct s3c_dma_params *)
396 rtd->dai->cpu_dai->dma_data)->channel; 398 rtd->dai->cpu_dai->dma_data)->channel;
397 399
398 pr_debug("Entered %s\n", __func__); 400 pr_debug("Entered %s\n", __func__);
@@ -467,6 +469,31 @@ static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai,
467 469
468 switch (div_id) { 470 switch (div_id) {
469 case S3C_I2SV2_DIV_BCLK: 471 case S3C_I2SV2_DIV_BCLK:
472 if (div > 3) {
473 /* convert value to bit field */
474
475 switch (div) {
476 case 16:
477 div = S3C2412_IISMOD_BCLK_16FS;
478 break;
479
480 case 32:
481 div = S3C2412_IISMOD_BCLK_32FS;
482 break;
483
484 case 24:
485 div = S3C2412_IISMOD_BCLK_24FS;
486 break;
487
488 case 48:
489 div = S3C2412_IISMOD_BCLK_48FS;
490 break;
491
492 default:
493 return -EINVAL;
494 }
495 }
496
470 reg = readl(i2s->regs + S3C2412_IISMOD); 497 reg = readl(i2s->regs + S3C2412_IISMOD);
471 reg &= ~S3C2412_IISMOD_BCLK_MASK; 498 reg &= ~S3C2412_IISMOD_BCLK_MASK;
472 writel(reg | div, i2s->regs + S3C2412_IISMOD); 499 writel(reg | div, i2s->regs + S3C2412_IISMOD);
@@ -626,7 +653,7 @@ int s3c_i2sv2_probe(struct platform_device *pdev,
626 } 653 }
627 654
628 i2s->iis_pclk = clk_get(dev, "iis"); 655 i2s->iis_pclk = clk_get(dev, "iis");
629 if (i2s->iis_pclk == NULL) { 656 if (IS_ERR(i2s->iis_pclk)) {
630 dev_err(dev, "failed to get iis_clock\n"); 657 dev_err(dev, "failed to get iis_clock\n");
631 iounmap(i2s->regs); 658 iounmap(i2s->regs);
632 return -ENOENT; 659 return -ENOENT;
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/s3c24xx/s3c-i2s-v2.h
index f66854a77fb2..ecf8eaaed1db 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.h
+++ b/sound/soc/s3c24xx/s3c-i2s-v2.h
@@ -49,8 +49,8 @@ struct s3c_i2sv2_info {
49 49
50 unsigned char master; 50 unsigned char master;
51 51
52 struct s3c24xx_pcm_dma_params *dma_playback; 52 struct s3c_dma_params *dma_playback;
53 struct s3c24xx_pcm_dma_params *dma_capture; 53 struct s3c_dma_params *dma_capture;
54 54
55 u32 suspend_iismod; 55 u32 suspend_iismod;
56 u32 suspend_iiscon; 56 u32 suspend_iiscon;
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c
new file mode 100644
index 000000000000..9e61a7c2d9ac
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-pcm.c
@@ -0,0 +1,552 @@
1/* sound/soc/s3c24xx/s3c-pcm.c
2 *
3 * ALSA SoC Audio Layer - S3C PCM-Controller driver
4 *
5 * Copyright (c) 2009 Samsung Electronics Co. Ltd
6 * Author: Jaswinder Singh <jassi.brar@samsung.com>
7 * based upon I2S drivers by Ben Dooks.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/init.h>
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/delay.h>
18#include <linux/clk.h>
19#include <linux/kernel.h>
20#include <linux/gpio.h>
21#include <linux/io.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/initval.h>
27#include <sound/soc.h>
28
29#include <plat/audio.h>
30#include <plat/dma.h>
31
32#include "s3c-dma.h"
33#include "s3c-pcm.h"
34
35static struct s3c2410_dma_client s3c_pcm_dma_client_out = {
36 .name = "PCM Stereo out"
37};
38
39static struct s3c2410_dma_client s3c_pcm_dma_client_in = {
40 .name = "PCM Stereo in"
41};
42
43static struct s3c_dma_params s3c_pcm_stereo_out[] = {
44 [0] = {
45 .client = &s3c_pcm_dma_client_out,
46 .dma_size = 4,
47 },
48 [1] = {
49 .client = &s3c_pcm_dma_client_out,
50 .dma_size = 4,
51 },
52};
53
54static struct s3c_dma_params s3c_pcm_stereo_in[] = {
55 [0] = {
56 .client = &s3c_pcm_dma_client_in,
57 .dma_size = 4,
58 },
59 [1] = {
60 .client = &s3c_pcm_dma_client_in,
61 .dma_size = 4,
62 },
63};
64
65static struct s3c_pcm_info s3c_pcm[2];
66
67static inline struct s3c_pcm_info *to_info(struct snd_soc_dai *cpu_dai)
68{
69 return cpu_dai->private_data;
70}
71
72static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on)
73{
74 void __iomem *regs = pcm->regs;
75 u32 ctl, clkctl;
76
77 clkctl = readl(regs + S3C_PCM_CLKCTL);
78 ctl = readl(regs + S3C_PCM_CTL);
79 ctl &= ~(S3C_PCM_CTL_TXDIPSTICK_MASK
80 << S3C_PCM_CTL_TXDIPSTICK_SHIFT);
81
82 if (on) {
83 ctl |= S3C_PCM_CTL_TXDMA_EN;
84 ctl |= S3C_PCM_CTL_TXFIFO_EN;
85 ctl |= S3C_PCM_CTL_ENABLE;
86 ctl |= (0x20<<S3C_PCM_CTL_TXDIPSTICK_SHIFT);
87 clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
88 } else {
89 ctl &= ~S3C_PCM_CTL_TXDMA_EN;
90 ctl &= ~S3C_PCM_CTL_TXFIFO_EN;
91
92 if (!(ctl & S3C_PCM_CTL_RXFIFO_EN)) {
93 ctl &= ~S3C_PCM_CTL_ENABLE;
94 if (!pcm->idleclk)
95 clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
96 }
97 }
98
99 writel(clkctl, regs + S3C_PCM_CLKCTL);
100 writel(ctl, regs + S3C_PCM_CTL);
101}
102
103static void s3c_pcm_snd_rxctrl(struct s3c_pcm_info *pcm, int on)
104{
105 void __iomem *regs = pcm->regs;
106 u32 ctl, clkctl;
107
108 ctl = readl(regs + S3C_PCM_CTL);
109 clkctl = readl(regs + S3C_PCM_CLKCTL);
110
111 if (on) {
112 ctl |= S3C_PCM_CTL_RXDMA_EN;
113 ctl |= S3C_PCM_CTL_RXFIFO_EN;
114 ctl |= S3C_PCM_CTL_ENABLE;
115 clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
116 } else {
117 ctl &= ~S3C_PCM_CTL_RXDMA_EN;
118 ctl &= ~S3C_PCM_CTL_RXFIFO_EN;
119
120 if (!(ctl & S3C_PCM_CTL_TXFIFO_EN)) {
121 ctl &= ~S3C_PCM_CTL_ENABLE;
122 if (!pcm->idleclk)
123 clkctl |= S3C_PCM_CLKCTL_SERCLK_EN;
124 }
125 }
126
127 writel(clkctl, regs + S3C_PCM_CLKCTL);
128 writel(ctl, regs + S3C_PCM_CTL);
129}
130
131static int s3c_pcm_trigger(struct snd_pcm_substream *substream, int cmd,
132 struct snd_soc_dai *dai)
133{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct s3c_pcm_info *pcm = to_info(rtd->dai->cpu_dai);
136 unsigned long flags;
137
138 dev_dbg(pcm->dev, "Entered %s\n", __func__);
139
140 switch (cmd) {
141 case SNDRV_PCM_TRIGGER_START:
142 case SNDRV_PCM_TRIGGER_RESUME:
143 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
144 spin_lock_irqsave(&pcm->lock, flags);
145
146 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
147 s3c_pcm_snd_rxctrl(pcm, 1);
148 else
149 s3c_pcm_snd_txctrl(pcm, 1);
150
151 spin_unlock_irqrestore(&pcm->lock, flags);
152 break;
153
154 case SNDRV_PCM_TRIGGER_STOP:
155 case SNDRV_PCM_TRIGGER_SUSPEND:
156 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
157 spin_lock_irqsave(&pcm->lock, flags);
158
159 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
160 s3c_pcm_snd_rxctrl(pcm, 0);
161 else
162 s3c_pcm_snd_txctrl(pcm, 0);
163
164 spin_unlock_irqrestore(&pcm->lock, flags);
165 break;
166
167 default:
168 return -EINVAL;
169 }
170
171 return 0;
172}
173
174static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
175 struct snd_pcm_hw_params *params,
176 struct snd_soc_dai *socdai)
177{
178 struct snd_soc_pcm_runtime *rtd = substream->private_data;
179 struct snd_soc_dai_link *dai = rtd->dai;
180 struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
181 void __iomem *regs = pcm->regs;
182 struct clk *clk;
183 int sclk_div, sync_div;
184 unsigned long flags;
185 u32 clkctl;
186
187 dev_dbg(pcm->dev, "Entered %s\n", __func__);
188
189 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
190 dai->cpu_dai->dma_data = pcm->dma_playback;
191 else
192 dai->cpu_dai->dma_data = pcm->dma_capture;
193
194 /* Strictly check for sample size */
195 switch (params_format(params)) {
196 case SNDRV_PCM_FORMAT_S16_LE:
197 break;
198 default:
199 return -EINVAL;
200 }
201
202 spin_lock_irqsave(&pcm->lock, flags);
203
204 /* Get hold of the PCMSOURCE_CLK */
205 clkctl = readl(regs + S3C_PCM_CLKCTL);
206 if (clkctl & S3C_PCM_CLKCTL_SERCLKSEL_PCLK)
207 clk = pcm->pclk;
208 else
209 clk = pcm->cclk;
210
211 /* Set the SCLK divider */
212 sclk_div = clk_get_rate(clk) / pcm->sclk_per_fs /
213 params_rate(params) / 2 - 1;
214
215 clkctl &= ~(S3C_PCM_CLKCTL_SCLKDIV_MASK
216 << S3C_PCM_CLKCTL_SCLKDIV_SHIFT);
217 clkctl |= ((sclk_div & S3C_PCM_CLKCTL_SCLKDIV_MASK)
218 << S3C_PCM_CLKCTL_SCLKDIV_SHIFT);
219
220 /* Set the SYNC divider */
221 sync_div = pcm->sclk_per_fs - 1;
222
223 clkctl &= ~(S3C_PCM_CLKCTL_SYNCDIV_MASK
224 << S3C_PCM_CLKCTL_SYNCDIV_SHIFT);
225 clkctl |= ((sync_div & S3C_PCM_CLKCTL_SYNCDIV_MASK)
226 << S3C_PCM_CLKCTL_SYNCDIV_SHIFT);
227
228 writel(clkctl, regs + S3C_PCM_CLKCTL);
229
230 spin_unlock_irqrestore(&pcm->lock, flags);
231
232 dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs \
233 SCLK_DIV=%d SYNC_DIV=%d\n",
234 clk_get_rate(clk), pcm->sclk_per_fs,
235 sclk_div, sync_div);
236
237 return 0;
238}
239
240static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai,
241 unsigned int fmt)
242{
243 struct s3c_pcm_info *pcm = to_info(cpu_dai);
244 void __iomem *regs = pcm->regs;
245 unsigned long flags;
246 int ret = 0;
247 u32 ctl;
248
249 dev_dbg(pcm->dev, "Entered %s\n", __func__);
250
251 spin_lock_irqsave(&pcm->lock, flags);
252
253 ctl = readl(regs + S3C_PCM_CTL);
254
255 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
256 case SND_SOC_DAIFMT_NB_NF:
257 /* Nothing to do, NB_NF by default */
258 break;
259 default:
260 dev_err(pcm->dev, "Unsupported clock inversion!\n");
261 ret = -EINVAL;
262 goto exit;
263 }
264
265 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
266 case SND_SOC_DAIFMT_CBS_CFS:
267 /* Nothing to do, Master by default */
268 break;
269 default:
270 dev_err(pcm->dev, "Unsupported master/slave format!\n");
271 ret = -EINVAL;
272 goto exit;
273 }
274
275 switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
276 case SND_SOC_DAIFMT_CONT:
277 pcm->idleclk = 1;
278 break;
279 case SND_SOC_DAIFMT_GATED:
280 pcm->idleclk = 0;
281 break;
282 default:
283 dev_err(pcm->dev, "Invalid Clock gating request!\n");
284 ret = -EINVAL;
285 goto exit;
286 }
287
288 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
289 case SND_SOC_DAIFMT_DSP_A:
290 ctl |= S3C_PCM_CTL_TXMSB_AFTER_FSYNC;
291 ctl |= S3C_PCM_CTL_RXMSB_AFTER_FSYNC;
292 break;
293 case SND_SOC_DAIFMT_DSP_B:
294 ctl &= ~S3C_PCM_CTL_TXMSB_AFTER_FSYNC;
295 ctl &= ~S3C_PCM_CTL_RXMSB_AFTER_FSYNC;
296 break;
297 default:
298 dev_err(pcm->dev, "Unsupported data format!\n");
299 ret = -EINVAL;
300 goto exit;
301 }
302
303 writel(ctl, regs + S3C_PCM_CTL);
304
305exit:
306 spin_unlock_irqrestore(&pcm->lock, flags);
307
308 return ret;
309}
310
311static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai,
312 int div_id, int div)
313{
314 struct s3c_pcm_info *pcm = to_info(cpu_dai);
315
316 switch (div_id) {
317 case S3C_PCM_SCLK_PER_FS:
318 pcm->sclk_per_fs = div;
319 break;
320
321 default:
322 return -EINVAL;
323 }
324
325 return 0;
326}
327
328static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai,
329 int clk_id, unsigned int freq, int dir)
330{
331 struct s3c_pcm_info *pcm = to_info(cpu_dai);
332 void __iomem *regs = pcm->regs;
333 u32 clkctl = readl(regs + S3C_PCM_CLKCTL);
334
335 switch (clk_id) {
336 case S3C_PCM_CLKSRC_PCLK:
337 clkctl |= S3C_PCM_CLKCTL_SERCLKSEL_PCLK;
338 break;
339
340 case S3C_PCM_CLKSRC_MUX:
341 clkctl &= ~S3C_PCM_CLKCTL_SERCLKSEL_PCLK;
342
343 if (clk_get_rate(pcm->cclk) != freq)
344 clk_set_rate(pcm->cclk, freq);
345
346 break;
347
348 default:
349 return -EINVAL;
350 }
351
352 writel(clkctl, regs + S3C_PCM_CLKCTL);
353
354 return 0;
355}
356
357static struct snd_soc_dai_ops s3c_pcm_dai_ops = {
358 .set_sysclk = s3c_pcm_set_sysclk,
359 .set_clkdiv = s3c_pcm_set_clkdiv,
360 .trigger = s3c_pcm_trigger,
361 .hw_params = s3c_pcm_hw_params,
362 .set_fmt = s3c_pcm_set_fmt,
363};
364
365#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000
366
367#define S3C_PCM_DECLARE(n) \
368{ \
369 .name = "samsung-pcm", \
370 .id = (n), \
371 .symmetric_rates = 1, \
372 .ops = &s3c_pcm_dai_ops, \
373 .playback = { \
374 .channels_min = 2, \
375 .channels_max = 2, \
376 .rates = S3C_PCM_RATES, \
377 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
378 }, \
379 .capture = { \
380 .channels_min = 2, \
381 .channels_max = 2, \
382 .rates = S3C_PCM_RATES, \
383 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
384 }, \
385}
386
387struct snd_soc_dai s3c_pcm_dai[] = {
388 S3C_PCM_DECLARE(0),
389 S3C_PCM_DECLARE(1),
390};
391EXPORT_SYMBOL_GPL(s3c_pcm_dai);
392
393static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev)
394{
395 struct s3c_pcm_info *pcm;
396 struct snd_soc_dai *dai;
397 struct resource *mem_res, *dmatx_res, *dmarx_res;
398 struct s3c_audio_pdata *pcm_pdata;
399 int ret;
400
401 /* Check for valid device index */
402 if ((pdev->id < 0) || pdev->id >= ARRAY_SIZE(s3c_pcm)) {
403 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
404 return -EINVAL;
405 }
406
407 pcm_pdata = pdev->dev.platform_data;
408
409 /* Check for availability of necessary resource */
410 dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
411 if (!dmatx_res) {
412 dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n");
413 return -ENXIO;
414 }
415
416 dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
417 if (!dmarx_res) {
418 dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n");
419 return -ENXIO;
420 }
421
422 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
423 if (!mem_res) {
424 dev_err(&pdev->dev, "Unable to get register resource\n");
425 return -ENXIO;
426 }
427
428 if (pcm_pdata && pcm_pdata->cfg_gpio && pcm_pdata->cfg_gpio(pdev)) {
429 dev_err(&pdev->dev, "Unable to configure gpio\n");
430 return -EINVAL;
431 }
432
433 pcm = &s3c_pcm[pdev->id];
434 pcm->dev = &pdev->dev;
435
436 spin_lock_init(&pcm->lock);
437
438 dai = &s3c_pcm_dai[pdev->id];
439 dai->dev = &pdev->dev;
440
441 /* Default is 128fs */
442 pcm->sclk_per_fs = 128;
443
444 pcm->cclk = clk_get(&pdev->dev, "audio-bus");
445 if (IS_ERR(pcm->cclk)) {
446 dev_err(&pdev->dev, "failed to get audio-bus\n");
447 ret = PTR_ERR(pcm->cclk);
448 goto err1;
449 }
450 clk_enable(pcm->cclk);
451
452 /* record our pcm structure for later use in the callbacks */
453 dai->private_data = pcm;
454
455 if (!request_mem_region(mem_res->start,
456 resource_size(mem_res), "samsung-pcm")) {
457 dev_err(&pdev->dev, "Unable to request register region\n");
458 ret = -EBUSY;
459 goto err2;
460 }
461
462 pcm->regs = ioremap(mem_res->start, 0x100);
463 if (pcm->regs == NULL) {
464 dev_err(&pdev->dev, "cannot ioremap registers\n");
465 ret = -ENXIO;
466 goto err3;
467 }
468
469 pcm->pclk = clk_get(&pdev->dev, "pcm");
470 if (IS_ERR(pcm->pclk)) {
471 dev_err(&pdev->dev, "failed to get pcm_clock\n");
472 ret = -ENOENT;
473 goto err4;
474 }
475 clk_enable(pcm->pclk);
476
477 ret = snd_soc_register_dai(dai);
478 if (ret != 0) {
479 dev_err(&pdev->dev, "failed to get pcm_clock\n");
480 goto err5;
481 }
482
483 s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start
484 + S3C_PCM_RXFIFO;
485 s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start
486 + S3C_PCM_TXFIFO;
487
488 s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start;
489 s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start;
490
491 pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id];
492 pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id];
493
494 return 0;
495
496err5:
497 clk_disable(pcm->pclk);
498 clk_put(pcm->pclk);
499err4:
500 iounmap(pcm->regs);
501err3:
502 release_mem_region(mem_res->start, resource_size(mem_res));
503err2:
504 clk_disable(pcm->cclk);
505 clk_put(pcm->cclk);
506err1:
507 return ret;
508}
509
510static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev)
511{
512 struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id];
513 struct resource *mem_res;
514
515 iounmap(pcm->regs);
516
517 mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
518 release_mem_region(mem_res->start, resource_size(mem_res));
519
520 clk_disable(pcm->cclk);
521 clk_disable(pcm->pclk);
522 clk_put(pcm->pclk);
523 clk_put(pcm->cclk);
524
525 return 0;
526}
527
528static struct platform_driver s3c_pcm_driver = {
529 .probe = s3c_pcm_dev_probe,
530 .remove = s3c_pcm_dev_remove,
531 .driver = {
532 .name = "samsung-pcm",
533 .owner = THIS_MODULE,
534 },
535};
536
537static int __init s3c_pcm_init(void)
538{
539 return platform_driver_register(&s3c_pcm_driver);
540}
541module_init(s3c_pcm_init);
542
543static void __exit s3c_pcm_exit(void)
544{
545 platform_driver_unregister(&s3c_pcm_driver);
546}
547module_exit(s3c_pcm_exit);
548
549/* Module information */
550MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
551MODULE_DESCRIPTION("S3C PCM Controller Driver");
552MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c-pcm.h b/sound/soc/s3c24xx/s3c-pcm.h
new file mode 100644
index 000000000000..69ff9971692f
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c-pcm.h
@@ -0,0 +1,123 @@
1/* sound/soc/s3c24xx/s3c-pcm.h
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
6 *
7 */
8
9#ifndef __S3C_PCM_H
10#define __S3C_PCM_H __FILE__
11
12/*Register Offsets */
13#define S3C_PCM_CTL (0x00)
14#define S3C_PCM_CLKCTL (0x04)
15#define S3C_PCM_TXFIFO (0x08)
16#define S3C_PCM_RXFIFO (0x0C)
17#define S3C_PCM_IRQCTL (0x10)
18#define S3C_PCM_IRQSTAT (0x14)
19#define S3C_PCM_FIFOSTAT (0x18)
20#define S3C_PCM_CLRINT (0x20)
21
22/* PCM_CTL Bit-Fields */
23#define S3C_PCM_CTL_TXDIPSTICK_MASK (0x3f)
24#define S3C_PCM_CTL_TXDIPSTICK_SHIFT (13)
25#define S3C_PCM_CTL_RXDIPSTICK_MSK (0x3f<<7)
26#define S3C_PCM_CTL_TXDMA_EN (0x1<<6)
27#define S3C_PCM_CTL_RXDMA_EN (0x1<<5)
28#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1<<4)
29#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1<<3)
30#define S3C_PCM_CTL_TXFIFO_EN (0x1<<2)
31#define S3C_PCM_CTL_RXFIFO_EN (0x1<<1)
32#define S3C_PCM_CTL_ENABLE (0x1<<0)
33
34/* PCM_CLKCTL Bit-Fields */
35#define S3C_PCM_CLKCTL_SERCLK_EN (0x1<<19)
36#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1<<18)
37#define S3C_PCM_CLKCTL_SCLKDIV_MASK (0x1ff)
38#define S3C_PCM_CLKCTL_SYNCDIV_MASK (0x1ff)
39#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT (9)
40#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT (0)
41
42/* PCM_TXFIFO Bit-Fields */
43#define S3C_PCM_TXFIFO_DVALID (0x1<<16)
44#define S3C_PCM_TXFIFO_DATA_MSK (0xffff<<0)
45
46/* PCM_RXFIFO Bit-Fields */
47#define S3C_PCM_RXFIFO_DVALID (0x1<<16)
48#define S3C_PCM_RXFIFO_DATA_MSK (0xffff<<0)
49
50/* PCM_IRQCTL Bit-Fields */
51#define S3C_PCM_IRQCTL_IRQEN (0x1<<14)
52#define S3C_PCM_IRQCTL_WRDEN (0x1<<12)
53#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1<<11)
54#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1<<10)
55#define S3C_PCM_IRQCTL_TXFULLEN (0x1<<9)
56#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1<<8)
57#define S3C_PCM_IRQCTL_TXSTARVEN (0x1<<7)
58#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1<<6)
59#define S3C_PCM_IRQCTL_RXEMPTEN (0x1<<5)
60#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1<<4)
61#define S3C_PCM_IRQCTL_RXFULLEN (0x1<<3)
62#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1<<2)
63#define S3C_PCM_IRQCTL_RXSTARVEN (0x1<<1)
64#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1<<0)
65
66/* PCM_IRQSTAT Bit-Fields */
67#define S3C_PCM_IRQSTAT_IRQPND (0x1<<13)
68#define S3C_PCM_IRQSTAT_WRD_XFER (0x1<<12)
69#define S3C_PCM_IRQSTAT_TXEMPTY (0x1<<11)
70#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1<<10)
71#define S3C_PCM_IRQSTAT_TXFULL (0x1<<9)
72#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1<<8)
73#define S3C_PCM_IRQSTAT_TXSTARV (0x1<<7)
74#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1<<6)
75#define S3C_PCM_IRQSTAT_RXEMPT (0x1<<5)
76#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1<<4)
77#define S3C_PCM_IRQSTAT_RXFULL (0x1<<3)
78#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1<<2)
79#define S3C_PCM_IRQSTAT_RXSTARV (0x1<<1)
80#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1<<0)
81
82/* PCM_FIFOSTAT Bit-Fields */
83#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f<<14)
84#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1<<13)
85#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1<<12)
86#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1<<11)
87#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1<<10)
88#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f<<4)
89#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1<<3)
90#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1<<2)
91#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1<<1)
92#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1<<0)
93
94#define S3C_PCM_CLKSRC_PCLK 0
95#define S3C_PCM_CLKSRC_MUX 1
96
97#define S3C_PCM_SCLK_PER_FS 0
98
99/**
100 * struct s3c_pcm_info - S3C PCM Controller information
101 * @dev: The parent device passed to use from the probe.
102 * @regs: The pointer to the device register block.
103 * @dma_playback: DMA information for playback channel.
104 * @dma_capture: DMA information for capture channel.
105 */
106struct s3c_pcm_info {
107 spinlock_t lock;
108 struct device *dev;
109 void __iomem *regs;
110
111 unsigned int sclk_per_fs;
112
113 /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */
114 unsigned int idleclk;
115
116 struct clk *pclk;
117 struct clk *cclk;
118
119 struct s3c_dma_params *dma_playback;
120 struct s3c_dma_params *dma_capture;
121};
122
123#endif /* __S3C_PCM_H */
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index a587ec40b449..359e59346ba2 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -34,11 +34,10 @@
34 34
35#include <plat/regs-s3c2412-iis.h> 35#include <plat/regs-s3c2412-iis.h>
36 36
37#include <plat/audio.h>
38#include <mach/regs-gpio.h> 37#include <mach/regs-gpio.h>
39#include <mach/dma.h> 38#include <mach/dma.h>
40 39
41#include "s3c24xx-pcm.h" 40#include "s3c-dma.h"
42#include "s3c2412-i2s.h" 41#include "s3c2412-i2s.h"
43 42
44#define S3C2412_I2S_DEBUG 0 43#define S3C2412_I2S_DEBUG 0
@@ -51,14 +50,14 @@ static struct s3c2410_dma_client s3c2412_dma_client_in = {
51 .name = "I2S PCM Stereo in" 50 .name = "I2S PCM Stereo in"
52}; 51};
53 52
54static struct s3c24xx_pcm_dma_params s3c2412_i2s_pcm_stereo_out = { 53static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
55 .client = &s3c2412_dma_client_out, 54 .client = &s3c2412_dma_client_out,
56 .channel = DMACH_I2S_OUT, 55 .channel = DMACH_I2S_OUT,
57 .dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD, 56 .dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD,
58 .dma_size = 4, 57 .dma_size = 4,
59}; 58};
60 59
61static struct s3c24xx_pcm_dma_params s3c2412_i2s_pcm_stereo_in = { 60static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
62 .client = &s3c2412_dma_client_in, 61 .client = &s3c2412_dma_client_in,
63 .channel = DMACH_I2S_IN, 62 .channel = DMACH_I2S_IN,
64 .dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD, 63 .dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD,
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
index fc1beb0930b9..0191e3acb0b4 100644
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -32,11 +32,10 @@
32#include <plat/regs-ac97.h> 32#include <plat/regs-ac97.h>
33#include <mach/regs-gpio.h> 33#include <mach/regs-gpio.h>
34#include <mach/regs-clock.h> 34#include <mach/regs-clock.h>
35#include <plat/audio.h>
36#include <asm/dma.h> 35#include <asm/dma.h>
37#include <mach/dma.h> 36#include <mach/dma.h>
38 37
39#include "s3c24xx-pcm.h" 38#include "s3c-dma.h"
40#include "s3c24xx-ac97.h" 39#include "s3c24xx-ac97.h"
41 40
42struct s3c24xx_ac97_info { 41struct s3c24xx_ac97_info {
@@ -189,21 +188,21 @@ static struct s3c2410_dma_client s3c2443_dma_client_micin = {
189 .name = "AC97 Mic Mono in" 188 .name = "AC97 Mic Mono in"
190}; 189};
191 190
192static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_out = { 191static struct s3c_dma_params s3c2443_ac97_pcm_stereo_out = {
193 .client = &s3c2443_dma_client_out, 192 .client = &s3c2443_dma_client_out,
194 .channel = DMACH_PCM_OUT, 193 .channel = DMACH_PCM_OUT,
195 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, 194 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
196 .dma_size = 4, 195 .dma_size = 4,
197}; 196};
198 197
199static struct s3c24xx_pcm_dma_params s3c2443_ac97_pcm_stereo_in = { 198static struct s3c_dma_params s3c2443_ac97_pcm_stereo_in = {
200 .client = &s3c2443_dma_client_in, 199 .client = &s3c2443_dma_client_in,
201 .channel = DMACH_PCM_IN, 200 .channel = DMACH_PCM_IN,
202 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA, 201 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
203 .dma_size = 4, 202 .dma_size = 4,
204}; 203};
205 204
206static struct s3c24xx_pcm_dma_params s3c2443_ac97_mic_mono_in = { 205static struct s3c_dma_params s3c2443_ac97_mic_mono_in = {
207 .client = &s3c2443_dma_client_micin, 206 .client = &s3c2443_dma_client_micin,
208 .channel = DMACH_MIC_IN, 207 .channel = DMACH_MIC_IN,
209 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA, 208 .dma_addr = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
@@ -291,7 +290,7 @@ static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
291{ 290{
292 u32 ac_glbctrl; 291 u32 ac_glbctrl;
293 struct snd_soc_pcm_runtime *rtd = substream->private_data; 292 struct snd_soc_pcm_runtime *rtd = substream->private_data;
294 int channel = ((struct s3c24xx_pcm_dma_params *) 293 int channel = ((struct s3c_dma_params *)
295 rtd->dai->cpu_dai->dma_data)->channel; 294 rtd->dai->cpu_dai->dma_data)->channel;
296 295
297 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); 296 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
@@ -340,7 +339,7 @@ static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
340{ 339{
341 u32 ac_glbctrl; 340 u32 ac_glbctrl;
342 struct snd_soc_pcm_runtime *rtd = substream->private_data; 341 struct snd_soc_pcm_runtime *rtd = substream->private_data;
343 int channel = ((struct s3c24xx_pcm_dma_params *) 342 int channel = ((struct s3c_dma_params *)
344 rtd->dai->cpu_dai->dma_data)->channel; 343 rtd->dai->cpu_dai->dma_data)->channel;
345 344
346 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL); 345 ac_glbctrl = readl(s3c24xx_ac97.regs + S3C_AC97_GLBCTRL);
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index 40e2c4790f0d..0bc5950b9f02 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -32,13 +32,13 @@
32#include <mach/hardware.h> 32#include <mach/hardware.h>
33#include <mach/regs-gpio.h> 33#include <mach/regs-gpio.h>
34#include <mach/regs-clock.h> 34#include <mach/regs-clock.h>
35#include <plat/audio.h> 35
36#include <asm/dma.h> 36#include <asm/dma.h>
37#include <mach/dma.h> 37#include <mach/dma.h>
38 38
39#include <plat/regs-iis.h> 39#include <plat/regs-iis.h>
40 40
41#include "s3c24xx-pcm.h" 41#include "s3c-dma.h"
42#include "s3c24xx-i2s.h" 42#include "s3c24xx-i2s.h"
43 43
44static struct s3c2410_dma_client s3c24xx_dma_client_out = { 44static struct s3c2410_dma_client s3c24xx_dma_client_out = {
@@ -49,14 +49,14 @@ static struct s3c2410_dma_client s3c24xx_dma_client_in = {
49 .name = "I2S PCM Stereo in" 49 .name = "I2S PCM Stereo in"
50}; 50};
51 51
52static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_out = { 52static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
53 .client = &s3c24xx_dma_client_out, 53 .client = &s3c24xx_dma_client_out,
54 .channel = DMACH_I2S_OUT, 54 .channel = DMACH_I2S_OUT,
55 .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, 55 .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO,
56 .dma_size = 2, 56 .dma_size = 2,
57}; 57};
58 58
59static struct s3c24xx_pcm_dma_params s3c24xx_i2s_pcm_stereo_in = { 59static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
60 .client = &s3c24xx_dma_client_in, 60 .client = &s3c24xx_dma_client_in,
61 .channel = DMACH_I2S_IN, 61 .channel = DMACH_I2S_IN,
62 .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, 62 .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO,
@@ -258,12 +258,12 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
258 switch (params_format(params)) { 258 switch (params_format(params)) {
259 case SNDRV_PCM_FORMAT_S8: 259 case SNDRV_PCM_FORMAT_S8:
260 iismod &= ~S3C2410_IISMOD_16BIT; 260 iismod &= ~S3C2410_IISMOD_16BIT;
261 ((struct s3c24xx_pcm_dma_params *) 261 ((struct s3c_dma_params *)
262 rtd->dai->cpu_dai->dma_data)->dma_size = 1; 262 rtd->dai->cpu_dai->dma_data)->dma_size = 1;
263 break; 263 break;
264 case SNDRV_PCM_FORMAT_S16_LE: 264 case SNDRV_PCM_FORMAT_S16_LE:
265 iismod |= S3C2410_IISMOD_16BIT; 265 iismod |= S3C2410_IISMOD_16BIT;
266 ((struct s3c24xx_pcm_dma_params *) 266 ((struct s3c_dma_params *)
267 rtd->dai->cpu_dai->dma_data)->dma_size = 2; 267 rtd->dai->cpu_dai->dma_data)->dma_size = 2;
268 break; 268 break;
269 default: 269 default:
@@ -280,7 +280,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
280{ 280{
281 int ret = 0; 281 int ret = 0;
282 struct snd_soc_pcm_runtime *rtd = substream->private_data; 282 struct snd_soc_pcm_runtime *rtd = substream->private_data;
283 int channel = ((struct s3c24xx_pcm_dma_params *) 283 int channel = ((struct s3c_dma_params *)
284 rtd->dai->cpu_dai->dma_data)->channel; 284 rtd->dai->cpu_dai->dma_data)->channel;
285 285
286 pr_debug("Entered %s\n", __func__); 286 pr_debug("Entered %s\n", __func__);
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c
index 1966e0d5652d..d441c3b64631 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec.c
@@ -21,7 +21,7 @@
21 21
22#include <plat/audio-simtec.h> 22#include <plat/audio-simtec.h>
23 23
24#include "s3c24xx-pcm.h" 24#include "s3c-dma.h"
25#include "s3c24xx-i2s.h" 25#include "s3c24xx-i2s.h"
26#include "s3c24xx_simtec.h" 26#include "s3c24xx_simtec.h"
27 27
@@ -270,7 +270,7 @@ static int attach_gpio_amp(struct device *dev,
270 gpio_direction_output(pd->amp_gain[1], 0); 270 gpio_direction_output(pd->amp_gain[1], 0);
271 } 271 }
272 272
273 /* note, curently we assume GPA0 isn't valid amp */ 273 /* note, currently we assume GPA0 isn't valid amp */
274 if (pdata->amp_gpio > 0) { 274 if (pdata->amp_gpio > 0) {
275 ret = gpio_request(pd->amp_gpio, "gpio-amp"); 275 ret = gpio_request(pd->amp_gpio, "gpio-amp");
276 if (ret) { 276 if (ret) {
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
index 8346bd96eaf5..bdf8951af8e3 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
@@ -18,7 +18,7 @@
18 18
19#include <plat/audio-simtec.h> 19#include <plat/audio-simtec.h>
20 20
21#include "s3c24xx-pcm.h" 21#include "s3c-dma.h"
22#include "s3c24xx-i2s.h" 22#include "s3c24xx-i2s.h"
23#include "s3c24xx_simtec.h" 23#include "s3c24xx_simtec.h"
24 24
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
index 25797e096175..185c0acb5ce6 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
@@ -18,7 +18,7 @@
18 18
19#include <plat/audio-simtec.h> 19#include <plat/audio-simtec.h>
20 20
21#include "s3c24xx-pcm.h" 21#include "s3c-dma.h"
22#include "s3c24xx-i2s.h" 22#include "s3c24xx-i2s.h"
23#include "s3c24xx_simtec.h" 23#include "s3c24xx_simtec.h"
24 24
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c
index c215d32d6322..052d59659c29 100644
--- a/sound/soc/s3c24xx/s3c24xx_uda134x.c
+++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c
@@ -24,7 +24,7 @@
24 24
25#include <plat/regs-iis.h> 25#include <plat/regs-iis.h>
26 26
27#include "s3c24xx-pcm.h" 27#include "s3c-dma.h"
28#include "s3c24xx-i2s.h" 28#include "s3c24xx-i2s.h"
29#include "../codecs/uda134x.h" 29#include "../codecs/uda134x.h"
30 30
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
index 3c06c401d0fb..cc7edb5f792d 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.c
@@ -31,12 +31,11 @@
31#include <plat/gpio-bank-d.h> 31#include <plat/gpio-bank-d.h>
32#include <plat/gpio-bank-e.h> 32#include <plat/gpio-bank-e.h>
33#include <plat/gpio-cfg.h> 33#include <plat/gpio-cfg.h>
34#include <plat/audio.h>
35 34
36#include <mach/map.h> 35#include <mach/map.h>
37#include <mach/dma.h> 36#include <mach/dma.h>
38 37
39#include "s3c24xx-pcm.h" 38#include "s3c-dma.h"
40#include "s3c64xx-i2s.h" 39#include "s3c64xx-i2s.h"
41 40
42static struct s3c2410_dma_client s3c64xx_dma_client_out = { 41static struct s3c2410_dma_client s3c64xx_dma_client_out = {
@@ -47,7 +46,7 @@ static struct s3c2410_dma_client s3c64xx_dma_client_in = {
47 .name = "I2S PCM Stereo in" 46 .name = "I2S PCM Stereo in"
48}; 47};
49 48
50static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_out[2] = { 49static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[2] = {
51 [0] = { 50 [0] = {
52 .channel = DMACH_I2S0_OUT, 51 .channel = DMACH_I2S0_OUT,
53 .client = &s3c64xx_dma_client_out, 52 .client = &s3c64xx_dma_client_out,
@@ -62,7 +61,7 @@ static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_out[2] = {
62 }, 61 },
63}; 62};
64 63
65static struct s3c24xx_pcm_dma_params s3c64xx_i2s_pcm_stereo_in[2] = { 64static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[2] = {
66 [0] = { 65 [0] = {
67 .channel = DMACH_I2S0_IN, 66 .channel = DMACH_I2S0_IN,
68 .client = &s3c64xx_dma_client_in, 67 .client = &s3c64xx_dma_client_in,
@@ -99,6 +98,19 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
99 iismod |= S3C64XX_IISMOD_IMS_SYSMUX; 98 iismod |= S3C64XX_IISMOD_IMS_SYSMUX;
100 break; 99 break;
101 100
101 case S3C64XX_CLKSRC_CDCLK:
102 switch (dir) {
103 case SND_SOC_CLOCK_IN:
104 iismod |= S3C64XX_IISMOD_CDCLKCON;
105 break;
106 case SND_SOC_CLOCK_OUT:
107 iismod &= ~S3C64XX_IISMOD_CDCLKCON;
108 break;
109 default:
110 return -EINVAL;
111 }
112 break;
113
102 default: 114 default:
103 return -EINVAL; 115 return -EINVAL;
104 } 116 }
@@ -111,8 +123,12 @@ static int s3c64xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
111struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) 123struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
112{ 124{
113 struct s3c_i2sv2_info *i2s = to_info(dai); 125 struct s3c_i2sv2_info *i2s = to_info(dai);
126 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
114 127
115 return i2s->iis_cclk; 128 if (iismod & S3C64XX_IISMOD_IMS_SYSMUX)
129 return i2s->iis_cclk;
130 else
131 return i2s->iis_pclk;
116} 132}
117EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock); 133EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
118 134
@@ -220,6 +236,8 @@ static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
220 goto err; 236 goto err;
221 } 237 }
222 238
239 clk_enable(i2s->iis_cclk);
240
223 ret = s3c_i2sv2_probe(pdev, dai, i2s, 0); 241 ret = s3c_i2sv2_probe(pdev, dai, i2s, 0);
224 if (ret) 242 if (ret)
225 goto err_clk; 243 goto err_clk;
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
index 02148cee2613..abe7253b55fc 100644
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ b/sound/soc/s3c24xx/s3c64xx-i2s.h
@@ -25,6 +25,7 @@ struct clk;
25 25
26#define S3C64XX_CLKSRC_PCLK (0) 26#define S3C64XX_CLKSRC_PCLK (0)
27#define S3C64XX_CLKSRC_MUX (1) 27#define S3C64XX_CLKSRC_MUX (1)
28#define S3C64XX_CLKSRC_CDCLK (2)
28 29
29extern struct snd_soc_dai s3c64xx_i2s_dai[]; 30extern struct snd_soc_dai s3c64xx_i2s_dai[];
30 31
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
index a2a4f5323c17..12b783b12fcb 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -20,7 +20,7 @@
20#include <sound/soc-dapm.h> 20#include <sound/soc-dapm.h>
21 21
22#include "../codecs/ac97.h" 22#include "../codecs/ac97.h"
23#include "s3c24xx-pcm.h" 23#include "s3c-dma.h"
24#include "s3c24xx-ac97.h" 24#include "s3c24xx-ac97.h"
25 25
26static struct snd_soc_card smdk2443; 26static struct snd_soc_card smdk2443;
diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c
new file mode 100644
index 000000000000..efe4901213a3
--- /dev/null
+++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c
@@ -0,0 +1,268 @@
1/*
2 * smdk64xx_wm8580.c
3 *
4 * Copyright (c) 2009 Samsung Electronics Co. Ltd
5 * Author: Jaswinder Singh <jassi.brar@samsung.com>
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#include <linux/platform_device.h>
14#include <linux/clk.h>
15#include <sound/core.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20
21#include "../codecs/wm8580.h"
22#include "s3c-dma.h"
23#include "s3c64xx-i2s.h"
24
25#define S3C64XX_I2S_V4 2
26
27/* SMDK64XX has a 12MHZ crystal attached to WM8580 */
28#define SMDK64XX_WM8580_FREQ 12000000
29
30static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
31 struct snd_pcm_hw_params *params)
32{
33 struct snd_soc_pcm_runtime *rtd = substream->private_data;
34 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
35 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
36 unsigned int pll_out;
37 int bfs, rfs, ret;
38
39 switch (params_format(params)) {
40 case SNDRV_PCM_FORMAT_U8:
41 case SNDRV_PCM_FORMAT_S8:
42 bfs = 16;
43 break;
44 case SNDRV_PCM_FORMAT_U16_LE:
45 case SNDRV_PCM_FORMAT_S16_LE:
46 bfs = 32;
47 break;
48 default:
49 return -EINVAL;
50 }
51
52 /* The Fvco for WM8580 PLLs must fall within [90,100]MHz.
53 * This criterion can't be met if we request PLL output
54 * as {8000x256, 64000x256, 11025x256}Hz.
55 * As a wayout, we rather change rfs to a minimum value that
56 * results in (params_rate(params) * rfs), and itself, acceptable
57 * to both - the CODEC and the CPU.
58 */
59 switch (params_rate(params)) {
60 case 16000:
61 case 22050:
62 case 32000:
63 case 44100:
64 case 48000:
65 case 88200:
66 case 96000:
67 rfs = 256;
68 break;
69 case 64000:
70 rfs = 384;
71 break;
72 case 8000:
73 case 11025:
74 rfs = 512;
75 break;
76 default:
77 return -EINVAL;
78 }
79 pll_out = params_rate(params) * rfs;
80
81 /* Set the Codec DAI configuration */
82 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
83 | SND_SOC_DAIFMT_NB_NF
84 | SND_SOC_DAIFMT_CBM_CFM);
85 if (ret < 0)
86 return ret;
87
88 /* Set the AP DAI configuration */
89 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
90 | SND_SOC_DAIFMT_NB_NF
91 | SND_SOC_DAIFMT_CBM_CFM);
92 if (ret < 0)
93 return ret;
94
95 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK,
96 0, SND_SOC_CLOCK_IN);
97 if (ret < 0)
98 return ret;
99
100 /* We use PCLK for basic ops in SoC-Slave mode */
101 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
102 0, SND_SOC_CLOCK_IN);
103 if (ret < 0)
104 return ret;
105
106 /* Set WM8580 to drive MCLK from its PLLA */
107 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
108 WM8580_CLKSRC_PLLA);
109 if (ret < 0)
110 return ret;
111
112 /* Explicitly set WM8580-DAC to source from MCLK */
113 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_DAC_CLKSEL,
114 WM8580_CLKSRC_MCLK);
115 if (ret < 0)
116 return ret;
117
118 ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
119 SMDK64XX_WM8580_FREQ, pll_out);
120 if (ret < 0)
121 return ret;
122
123 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs);
124 if (ret < 0)
125 return ret;
126
127 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs);
128 if (ret < 0)
129 return ret;
130
131 return 0;
132}
133
134/*
135 * SMDK64XX WM8580 DAI operations.
136 */
137static struct snd_soc_ops smdk64xx_ops = {
138 .hw_params = smdk64xx_hw_params,
139};
140
141/* SMDK64xx Playback widgets */
142static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = {
143 SND_SOC_DAPM_HP("Front-L/R", NULL),
144 SND_SOC_DAPM_HP("Center/Sub", NULL),
145 SND_SOC_DAPM_HP("Rear-L/R", NULL),
146};
147
148/* SMDK64xx Capture widgets */
149static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = {
150 SND_SOC_DAPM_MIC("MicIn", NULL),
151 SND_SOC_DAPM_LINE("LineIn", NULL),
152};
153
154/* SMDK-PAIFTX connections */
155static const struct snd_soc_dapm_route audio_map_tx[] = {
156 /* MicIn feeds AINL */
157 {"AINL", NULL, "MicIn"},
158
159 /* LineIn feeds AINL/R */
160 {"AINL", NULL, "LineIn"},
161 {"AINR", NULL, "LineIn"},
162};
163
164/* SMDK-PAIFRX connections */
165static const struct snd_soc_dapm_route audio_map_rx[] = {
166 /* Front Left/Right are fed VOUT1L/R */
167 {"Front-L/R", NULL, "VOUT1L"},
168 {"Front-L/R", NULL, "VOUT1R"},
169
170 /* Center/Sub are fed VOUT2L/R */
171 {"Center/Sub", NULL, "VOUT2L"},
172 {"Center/Sub", NULL, "VOUT2R"},
173
174 /* Rear Left/Right are fed VOUT3L/R */
175 {"Rear-L/R", NULL, "VOUT3L"},
176 {"Rear-L/R", NULL, "VOUT3R"},
177};
178
179static int smdk64xx_wm8580_init_paiftx(struct snd_soc_codec *codec)
180{
181 /* Add smdk64xx specific Capture widgets */
182 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt,
183 ARRAY_SIZE(wm8580_dapm_widgets_cpt));
184
185 /* Set up PAIFTX audio path */
186 snd_soc_dapm_add_routes(codec, audio_map_tx, ARRAY_SIZE(audio_map_tx));
187
188 /* Enabling the microphone requires the fitting of a 0R
189 * resistor to connect the line from the microphone jack.
190 */
191 snd_soc_dapm_disable_pin(codec, "MicIn");
192
193 /* signal a DAPM event */
194 snd_soc_dapm_sync(codec);
195
196 return 0;
197}
198
199static int smdk64xx_wm8580_init_paifrx(struct snd_soc_codec *codec)
200{
201 /* Add smdk64xx specific Playback widgets */
202 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk,
203 ARRAY_SIZE(wm8580_dapm_widgets_pbk));
204
205 /* Set up PAIFRX audio path */
206 snd_soc_dapm_add_routes(codec, audio_map_rx, ARRAY_SIZE(audio_map_rx));
207
208 /* signal a DAPM event */
209 snd_soc_dapm_sync(codec);
210
211 return 0;
212}
213
214static struct snd_soc_dai_link smdk64xx_dai[] = {
215{ /* Primary Playback i/f */
216 .name = "WM8580 PAIF RX",
217 .stream_name = "Playback",
218 .cpu_dai = &s3c64xx_i2s_dai[S3C64XX_I2S_V4],
219 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFRX],
220 .init = smdk64xx_wm8580_init_paifrx,
221 .ops = &smdk64xx_ops,
222},
223{ /* Primary Capture i/f */
224 .name = "WM8580 PAIF TX",
225 .stream_name = "Capture",
226 .cpu_dai = &s3c64xx_i2s_dai[S3C64XX_I2S_V4],
227 .codec_dai = &wm8580_dai[WM8580_DAI_PAIFTX],
228 .init = smdk64xx_wm8580_init_paiftx,
229 .ops = &smdk64xx_ops,
230},
231};
232
233static struct snd_soc_card smdk64xx = {
234 .name = "smdk64xx",
235 .platform = &s3c24xx_soc_platform,
236 .dai_link = smdk64xx_dai,
237 .num_links = ARRAY_SIZE(smdk64xx_dai),
238};
239
240static struct snd_soc_device smdk64xx_snd_devdata = {
241 .card = &smdk64xx,
242 .codec_dev = &soc_codec_dev_wm8580,
243};
244
245static struct platform_device *smdk64xx_snd_device;
246
247static int __init smdk64xx_audio_init(void)
248{
249 int ret;
250
251 smdk64xx_snd_device = platform_device_alloc("soc-audio", -1);
252 if (!smdk64xx_snd_device)
253 return -ENOMEM;
254
255 platform_set_drvdata(smdk64xx_snd_device, &smdk64xx_snd_devdata);
256 smdk64xx_snd_devdata.dev = &smdk64xx_snd_device->dev;
257 ret = platform_device_add(smdk64xx_snd_device);
258
259 if (ret)
260 platform_device_put(smdk64xx_snd_device);
261
262 return ret;
263}
264module_init(smdk64xx_audio_init);
265
266MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com");
267MODULE_DESCRIPTION("ALSA SoC SMDK64XX WM8580");
268MODULE_LICENSE("GPL");
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c
index 83b8028e209d..1d61109e09fa 100644
--- a/sound/soc/s6000/s6000-pcm.c
+++ b/sound/soc/s6000/s6000-pcm.c
@@ -196,7 +196,7 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream)
196 0 /* destination skip after chunk (impossible) */, 196 0 /* destination skip after chunk (impossible) */,
197 4 /* 16 byte burst size */, 197 4 /* 16 byte burst size */,
198 -1 /* don't conserve bandwidth */, 198 -1 /* don't conserve bandwidth */,
199 0 /* low watermark irq descriptor theshold */, 199 0 /* low watermark irq descriptor threshold */,
200 0 /* disable hardware timestamps */, 200 0 /* disable hardware timestamps */,
201 1 /* enable channel */); 201 1 /* enable channel */);
202 202
@@ -423,7 +423,7 @@ static void s6000_pcm_free(struct snd_pcm *pcm)
423 snd_pcm_lib_preallocate_free_for_all(pcm); 423 snd_pcm_lib_preallocate_free_for_all(pcm);
424} 424}
425 425
426static u64 s6000_pcm_dmamask = DMA_32BIT_MASK; 426static u64 s6000_pcm_dmamask = DMA_BIT_MASK(32);
427 427
428static int s6000_pcm_new(struct snd_card *card, 428static int s6000_pcm_new(struct snd_card *card,
429 struct snd_soc_dai *dai, struct snd_pcm *pcm) 429 struct snd_soc_dai *dai, struct snd_pcm *pcm)
@@ -435,7 +435,7 @@ static int s6000_pcm_new(struct snd_card *card,
435 if (!card->dev->dma_mask) 435 if (!card->dev->dma_mask)
436 card->dev->dma_mask = &s6000_pcm_dmamask; 436 card->dev->dma_mask = &s6000_pcm_dmamask;
437 if (!card->dev->coherent_dma_mask) 437 if (!card->dev->coherent_dma_mask)
438 card->dev->coherent_dma_mask = DMA_32BIT_MASK; 438 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
439 439
440 if (params->dma_in) { 440 if (params->dma_in) {
441 s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_in), 441 s6dmac_disable_chan(DMA_MASK_DMAC(params->dma_in),
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 9154b4363db3..9e6976586554 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -23,7 +23,6 @@ config SND_SOC_SH4_SSI
23config SND_SOC_SH4_FSI 23config SND_SOC_SH4_FSI
24 tristate "SH4 FSI support" 24 tristate "SH4 FSI support"
25 depends on CPU_SUBTYPE_SH7724 25 depends on CPU_SUBTYPE_SH7724
26 select SH_DMA
27 help 26 help
28 This option enables FSI sound support 27 This option enables FSI sound support
29 28
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 44123248b630..9c49c11c43ce 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -17,7 +17,7 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/clk.h> 20#include <linux/pm_runtime.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <sound/core.h> 22#include <sound/core.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
@@ -26,8 +26,6 @@
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/sh_fsi.h> 27#include <sound/sh_fsi.h>
28#include <asm/atomic.h> 28#include <asm/atomic.h>
29#include <asm/dma.h>
30#include <asm/dma-sh.h>
31 29
32#define DO_FMT 0x0000 30#define DO_FMT 0x0000
33#define DOFF_CTL 0x0004 31#define DOFF_CTL 0x0004
@@ -97,7 +95,6 @@ struct fsi_priv {
97 95
98 int fifo_max; 96 int fifo_max;
99 int chan; 97 int chan;
100 int dma_chan;
101 98
102 int byte_offset; 99 int byte_offset;
103 int period_len; 100 int period_len;
@@ -108,7 +105,6 @@ struct fsi_priv {
108struct fsi_master { 105struct fsi_master {
109 void __iomem *base; 106 void __iomem *base;
110 int irq; 107 int irq;
111 struct clk *clk;
112 struct fsi_priv fsia; 108 struct fsi_priv fsia;
113 struct fsi_priv fsib; 109 struct fsi_priv fsib;
114 struct sh_fsi_platform_info *info; 110 struct sh_fsi_platform_info *info;
@@ -308,62 +304,6 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
308 return residue; 304 return residue;
309} 305}
310 306
311static int fsi_get_residue(struct fsi_priv *fsi, int is_play)
312{
313 int residue;
314 int width;
315 struct snd_pcm_runtime *runtime;
316
317 runtime = fsi->substream->runtime;
318
319 /* get 1 channel data width */
320 width = frames_to_bytes(runtime, 1) / fsi->chan;
321
322 if (2 == width)
323 residue = fsi_get_fifo_residue(fsi, is_play);
324 else
325 residue = get_dma_residue(fsi->dma_chan);
326
327 return residue;
328}
329
330/************************************************************************
331
332
333 basic dma function
334
335
336************************************************************************/
337#define PORTA_DMA 0
338#define PORTB_DMA 1
339
340static int fsi_get_dma_chan(void)
341{
342 if (0 != request_dma(PORTA_DMA, "fsia"))
343 return -EIO;
344
345 if (0 != request_dma(PORTB_DMA, "fsib")) {
346 free_dma(PORTA_DMA);
347 return -EIO;
348 }
349
350 master->fsia.dma_chan = PORTA_DMA;
351 master->fsib.dma_chan = PORTB_DMA;
352
353 return 0;
354}
355
356static void fsi_free_dma_chan(void)
357{
358 dma_wait_for_completion(PORTA_DMA);
359 dma_wait_for_completion(PORTB_DMA);
360 free_dma(PORTA_DMA);
361 free_dma(PORTB_DMA);
362
363 master->fsia.dma_chan = -1;
364 master->fsib.dma_chan = -1;
365}
366
367/************************************************************************ 307/************************************************************************
368 308
369 309
@@ -435,44 +375,6 @@ static void fsi_soft_all_reset(void)
435 mdelay(10); 375 mdelay(10);
436} 376}
437 377
438static void fsi_16data_push(struct fsi_priv *fsi,
439 struct snd_pcm_runtime *runtime,
440 int send)
441{
442 u16 *dma_start;
443 u32 snd;
444 int i;
445
446 /* get dma start position for FSI */
447 dma_start = (u16 *)runtime->dma_area;
448 dma_start += fsi->byte_offset / 2;
449
450 /*
451 * soft dma
452 * FSI can not use DMA when 16bpp
453 */
454 for (i = 0; i < send; i++) {
455 snd = (u32)dma_start[i];
456 fsi_reg_write(fsi, DODT, snd << 8);
457 }
458}
459
460static void fsi_32data_push(struct fsi_priv *fsi,
461 struct snd_pcm_runtime *runtime,
462 int send)
463{
464 u32 *dma_start;
465
466 /* get dma start position for FSI */
467 dma_start = (u32 *)runtime->dma_area;
468 dma_start += fsi->byte_offset / 4;
469
470 dma_wait_for_completion(fsi->dma_chan);
471 dma_configure_channel(fsi->dma_chan, (SM_INC|0x400|TS_32|TM_BUR));
472 dma_write(fsi->dma_chan, (u32)dma_start,
473 (u32)(fsi->base + DODT), send * 4);
474}
475
476/* playback interrupt */ 378/* playback interrupt */
477static int fsi_data_push(struct fsi_priv *fsi) 379static int fsi_data_push(struct fsi_priv *fsi)
478{ 380{
@@ -481,6 +383,8 @@ static int fsi_data_push(struct fsi_priv *fsi)
481 int send; 383 int send;
482 int fifo_free; 384 int fifo_free;
483 int width; 385 int width;
386 u8 *start;
387 int i;
484 388
485 if (!fsi || 389 if (!fsi ||
486 !fsi->substream || 390 !fsi->substream ||
@@ -515,12 +419,22 @@ static int fsi_data_push(struct fsi_priv *fsi)
515 if (fifo_free < send) 419 if (fifo_free < send)
516 send = fifo_free; 420 send = fifo_free;
517 421
518 if (2 == width) 422 start = runtime->dma_area;
519 fsi_16data_push(fsi, runtime, send); 423 start += fsi->byte_offset;
520 else if (4 == width) 424
521 fsi_32data_push(fsi, runtime, send); 425 switch (width) {
522 else 426 case 2:
427 for (i = 0; i < send; i++)
428 fsi_reg_write(fsi, DODT,
429 ((u32)*((u16 *)start + i) << 8));
430 break;
431 case 4:
432 for (i = 0; i < send; i++)
433 fsi_reg_write(fsi, DODT, *((u32 *)start + i));
434 break;
435 default:
523 return -EINVAL; 436 return -EINVAL;
437 }
524 438
525 fsi->byte_offset += send * width; 439 fsi->byte_offset += send * width;
526 440
@@ -532,6 +446,75 @@ static int fsi_data_push(struct fsi_priv *fsi)
532 return 0; 446 return 0;
533} 447}
534 448
449static int fsi_data_pop(struct fsi_priv *fsi)
450{
451 struct snd_pcm_runtime *runtime;
452 struct snd_pcm_substream *substream = NULL;
453 int free;
454 int fifo_fill;
455 int width;
456 u8 *start;
457 int i;
458
459 if (!fsi ||
460 !fsi->substream ||
461 !fsi->substream->runtime)
462 return -EINVAL;
463
464 runtime = fsi->substream->runtime;
465
466 /* FSI FIFO has limit.
467 * So, this driver can not send periods data at a time
468 */
469 if (fsi->byte_offset >=
470 fsi->period_len * (fsi->periods + 1)) {
471
472 substream = fsi->substream;
473 fsi->periods = (fsi->periods + 1) % runtime->periods;
474
475 if (0 == fsi->periods)
476 fsi->byte_offset = 0;
477 }
478
479 /* get 1 channel data width */
480 width = frames_to_bytes(runtime, 1) / fsi->chan;
481
482 /* get free space for alsa */
483 free = (fsi->buffer_len - fsi->byte_offset) / width;
484
485 /* get recv size */
486 fifo_fill = fsi_get_fifo_residue(fsi, 0);
487
488 if (free < fifo_fill)
489 fifo_fill = free;
490
491 start = runtime->dma_area;
492 start += fsi->byte_offset;
493
494 switch (width) {
495 case 2:
496 for (i = 0; i < fifo_fill; i++)
497 *((u16 *)start + i) =
498 (u16)(fsi_reg_read(fsi, DIDT) >> 8);
499 break;
500 case 4:
501 for (i = 0; i < fifo_fill; i++)
502 *((u32 *)start + i) = fsi_reg_read(fsi, DIDT);
503 break;
504 default:
505 return -EINVAL;
506 }
507
508 fsi->byte_offset += fifo_fill * width;
509
510 fsi_irq_enable(fsi, 0);
511
512 if (substream)
513 snd_pcm_period_elapsed(substream);
514
515 return 0;
516}
517
535static irqreturn_t fsi_interrupt(int irq, void *data) 518static irqreturn_t fsi_interrupt(int irq, void *data)
536{ 519{
537 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; 520 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010;
@@ -545,6 +528,10 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
545 fsi_data_push(&master->fsia); 528 fsi_data_push(&master->fsia);
546 if (int_st & INT_B_OUT) 529 if (int_st & INT_B_OUT)
547 fsi_data_push(&master->fsib); 530 fsi_data_push(&master->fsib);
531 if (int_st & INT_A_IN)
532 fsi_data_pop(&master->fsia);
533 if (int_st & INT_B_IN)
534 fsi_data_pop(&master->fsib);
548 535
549 fsi_master_write(INT_ST, 0x0000000); 536 fsi_master_write(INT_ST, 0x0000000);
550 537
@@ -571,7 +558,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
571 int is_master; 558 int is_master;
572 int ret = 0; 559 int ret = 0;
573 560
574 clk_enable(master->clk); 561 pm_runtime_get_sync(dai->dev);
575 562
576 /* CKG1 */ 563 /* CKG1 */
577 data = is_play ? (1 << 0) : (1 << 4); 564 data = is_play ? (1 << 0) : (1 << 4);
@@ -664,8 +651,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
664 } 651 }
665 652
666 fsi_reg_write(fsi, reg, data); 653 fsi_reg_write(fsi, reg, data);
667 dev_dbg(dai->dev, "use %s format (%d channel) use %d DMAC\n",
668 msg, fsi->chan, fsi->dma_chan);
669 654
670 /* 655 /*
671 * clear clk reset if master mode 656 * clear clk reset if master mode
@@ -688,7 +673,7 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
688 fsi_irq_disable(fsi, is_play); 673 fsi_irq_disable(fsi, is_play);
689 fsi_clk_ctrl(fsi, 0); 674 fsi_clk_ctrl(fsi, 0);
690 675
691 clk_disable(master->clk); 676 pm_runtime_put_sync(dai->dev);
692} 677}
693 678
694static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 679static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -699,16 +684,12 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
699 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 684 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
700 int ret = 0; 685 int ret = 0;
701 686
702 /* capture not supported */
703 if (!is_play)
704 return -ENODEV;
705
706 switch (cmd) { 687 switch (cmd) {
707 case SNDRV_PCM_TRIGGER_START: 688 case SNDRV_PCM_TRIGGER_START:
708 fsi_stream_push(fsi, substream, 689 fsi_stream_push(fsi, substream,
709 frames_to_bytes(runtime, runtime->buffer_size), 690 frames_to_bytes(runtime, runtime->buffer_size),
710 frames_to_bytes(runtime, runtime->period_size)); 691 frames_to_bytes(runtime, runtime->period_size));
711 ret = fsi_data_push(fsi); 692 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
712 break; 693 break;
713 case SNDRV_PCM_TRIGGER_STOP: 694 case SNDRV_PCM_TRIGGER_STOP:
714 fsi_irq_disable(fsi, is_play); 695 fsi_irq_disable(fsi, is_play);
@@ -780,10 +761,9 @@ static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
780{ 761{
781 struct snd_pcm_runtime *runtime = substream->runtime; 762 struct snd_pcm_runtime *runtime = substream->runtime;
782 struct fsi_priv *fsi = fsi_get(substream); 763 struct fsi_priv *fsi = fsi_get(substream);
783 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
784 long location; 764 long location;
785 765
786 location = (fsi->byte_offset - 1) - fsi_get_residue(fsi, is_play); 766 location = (fsi->byte_offset - 1);
787 if (location < 0) 767 if (location < 0)
788 location = 0; 768 location = 0;
789 769
@@ -845,7 +825,12 @@ struct snd_soc_dai fsi_soc_dai[] = {
845 .channels_min = 1, 825 .channels_min = 1,
846 .channels_max = 8, 826 .channels_max = 8,
847 }, 827 },
848 /* capture not supported */ 828 .capture = {
829 .rates = FSI_RATES,
830 .formats = FSI_FMTS,
831 .channels_min = 1,
832 .channels_max = 8,
833 },
849 .ops = &fsi_dai_ops, 834 .ops = &fsi_dai_ops,
850 }, 835 },
851 { 836 {
@@ -857,7 +842,12 @@ struct snd_soc_dai fsi_soc_dai[] = {
857 .channels_min = 1, 842 .channels_min = 1,
858 .channels_max = 8, 843 .channels_max = 8,
859 }, 844 },
860 /* capture not supported */ 845 .capture = {
846 .rates = FSI_RATES,
847 .formats = FSI_FMTS,
848 .channels_min = 1,
849 .channels_max = 8,
850 },
861 .ops = &fsi_dai_ops, 851 .ops = &fsi_dai_ops,
862 }, 852 },
863}; 853};
@@ -881,7 +871,6 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
881static int fsi_probe(struct platform_device *pdev) 871static int fsi_probe(struct platform_device *pdev)
882{ 872{
883 struct resource *res; 873 struct resource *res;
884 char clk_name[8];
885 unsigned int irq; 874 unsigned int irq;
886 int ret; 875 int ret;
887 876
@@ -912,23 +901,8 @@ static int fsi_probe(struct platform_device *pdev)
912 master->fsia.base = master->base; 901 master->fsia.base = master->base;
913 master->fsib.base = master->base + 0x40; 902 master->fsib.base = master->base + 0x40;
914 903
915 master->fsia.dma_chan = -1; 904 pm_runtime_enable(&pdev->dev);
916 master->fsib.dma_chan = -1; 905 pm_runtime_resume(&pdev->dev);
917
918 ret = fsi_get_dma_chan();
919 if (ret < 0) {
920 dev_err(&pdev->dev, "cannot get dma api\n");
921 goto exit_iounmap;
922 }
923
924 /* FSI is based on SPU mstp */
925 snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id);
926 master->clk = clk_get(NULL, clk_name);
927 if (IS_ERR(master->clk)) {
928 dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
929 ret = -EIO;
930 goto exit_free_dma;
931 }
932 906
933 fsi_soc_dai[0].dev = &pdev->dev; 907 fsi_soc_dai[0].dev = &pdev->dev;
934 fsi_soc_dai[1].dev = &pdev->dev; 908 fsi_soc_dai[1].dev = &pdev->dev;
@@ -938,7 +912,7 @@ static int fsi_probe(struct platform_device *pdev)
938 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 912 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
939 if (ret) { 913 if (ret) {
940 dev_err(&pdev->dev, "irq request err\n"); 914 dev_err(&pdev->dev, "irq request err\n");
941 goto exit_free_dma; 915 goto exit_iounmap;
942 } 916 }
943 917
944 ret = snd_soc_register_platform(&fsi_soc_platform); 918 ret = snd_soc_register_platform(&fsi_soc_platform);
@@ -951,10 +925,9 @@ static int fsi_probe(struct platform_device *pdev)
951 925
952exit_free_irq: 926exit_free_irq:
953 free_irq(irq, master); 927 free_irq(irq, master);
954exit_free_dma:
955 fsi_free_dma_chan();
956exit_iounmap: 928exit_iounmap:
957 iounmap(master->base); 929 iounmap(master->base);
930 pm_runtime_disable(&pdev->dev);
958exit_kfree: 931exit_kfree:
959 kfree(master); 932 kfree(master);
960 master = NULL; 933 master = NULL;
@@ -967,9 +940,7 @@ static int fsi_remove(struct platform_device *pdev)
967 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 940 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
968 snd_soc_unregister_platform(&fsi_soc_platform); 941 snd_soc_unregister_platform(&fsi_soc_platform);
969 942
970 clk_put(master->clk); 943 pm_runtime_disable(&pdev->dev);
971
972 fsi_free_dma_chan();
973 944
974 free_irq(master->irq, master); 945 free_irq(master->irq, master);
975 946
@@ -979,9 +950,27 @@ static int fsi_remove(struct platform_device *pdev)
979 return 0; 950 return 0;
980} 951}
981 952
953static int fsi_runtime_nop(struct device *dev)
954{
955 /* Runtime PM callback shared between ->runtime_suspend()
956 * and ->runtime_resume(). Simply returns success.
957 *
958 * This driver re-initializes all registers after
959 * pm_runtime_get_sync() anyway so there is no need
960 * to save and restore registers here.
961 */
962 return 0;
963}
964
965static struct dev_pm_ops fsi_pm_ops = {
966 .runtime_suspend = fsi_runtime_nop,
967 .runtime_resume = fsi_runtime_nop,
968};
969
982static struct platform_driver fsi_driver = { 970static struct platform_driver fsi_driver = {
983 .driver = { 971 .driver = {
984 .name = "sh_fsi", 972 .name = "sh_fsi",
973 .pm = &fsi_pm_ops,
985 }, 974 },
986 .probe = fsi_probe, 975 .probe = fsi_probe,
987 .remove = fsi_remove, 976 .remove = fsi_remove,
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index c8ceddc2a26c..d2505e8b06c9 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -77,6 +77,35 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data,
77#define snd_soc_7_9_spi_write NULL 77#define snd_soc_7_9_spi_write NULL
78#endif 78#endif
79 79
80static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
81 unsigned int value)
82{
83 u8 *cache = codec->reg_cache;
84 u8 data[2];
85
86 BUG_ON(codec->volatile_register);
87
88 data[0] = reg & 0xff;
89 data[1] = value & 0xff;
90
91 if (reg < codec->reg_cache_size)
92 cache[reg] = value;
93
94 if (codec->hw_write(codec->control_data, data, 2) == 2)
95 return 0;
96 else
97 return -EIO;
98}
99
100static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
101 unsigned int reg)
102{
103 u8 *cache = codec->reg_cache;
104 if (reg >= codec->reg_cache_size)
105 return -1;
106 return cache[reg];
107}
108
80static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, 109static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
81 unsigned int value) 110 unsigned int value)
82{ 111{
@@ -150,9 +179,20 @@ static struct {
150 unsigned int (*read)(struct snd_soc_codec *, unsigned int); 179 unsigned int (*read)(struct snd_soc_codec *, unsigned int);
151 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int); 180 unsigned int (*i2c_read)(struct snd_soc_codec *, unsigned int);
152} io_types[] = { 181} io_types[] = {
153 { 7, 9, snd_soc_7_9_write, snd_soc_7_9_spi_write, snd_soc_7_9_read }, 182 {
154 { 8, 16, snd_soc_8_16_write, NULL, snd_soc_8_16_read, 183 .addr_bits = 7, .data_bits = 9,
155 snd_soc_8_16_read_i2c }, 184 .write = snd_soc_7_9_write, .read = snd_soc_7_9_read,
185 .spi_write = snd_soc_7_9_spi_write
186 },
187 {
188 .addr_bits = 8, .data_bits = 8,
189 .write = snd_soc_8_8_write, .read = snd_soc_8_8_read,
190 },
191 {
192 .addr_bits = 8, .data_bits = 16,
193 .write = snd_soc_8_16_write, .read = snd_soc_8_16_read,
194 .i2c_read = snd_soc_8_16_read_i2c,
195 },
156}; 196};
157 197
158/** 198/**
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 7ff04ad2a97e..ef8f28284cb9 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -37,7 +37,6 @@
37#include <sound/initval.h> 37#include <sound/initval.h>
38 38
39static DEFINE_MUTEX(pcm_mutex); 39static DEFINE_MUTEX(pcm_mutex);
40static DEFINE_MUTEX(io_mutex);
41static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); 40static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
42 41
43#ifdef CONFIG_DEBUG_FS 42#ifdef CONFIG_DEBUG_FS
@@ -81,6 +80,173 @@ static int run_delayed_work(struct delayed_work *dwork)
81 return ret; 80 return ret;
82} 81}
83 82
83/* codec register dump */
84static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
85{
86 int i, step = 1, count = 0;
87
88 if (!codec->reg_cache_size)
89 return 0;
90
91 if (codec->reg_cache_step)
92 step = codec->reg_cache_step;
93
94 count += sprintf(buf, "%s registers\n", codec->name);
95 for (i = 0; i < codec->reg_cache_size; i += step) {
96 if (codec->readable_register && !codec->readable_register(i))
97 continue;
98
99 count += sprintf(buf + count, "%2x: ", i);
100 if (count >= PAGE_SIZE - 1)
101 break;
102
103 if (codec->display_register)
104 count += codec->display_register(codec, buf + count,
105 PAGE_SIZE - count, i);
106 else
107 count += snprintf(buf + count, PAGE_SIZE - count,
108 "%4x", codec->read(codec, i));
109
110 if (count >= PAGE_SIZE - 1)
111 break;
112
113 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
114 if (count >= PAGE_SIZE - 1)
115 break;
116 }
117
118 /* Truncate count; min() would cause a warning */
119 if (count >= PAGE_SIZE)
120 count = PAGE_SIZE - 1;
121
122 return count;
123}
124static ssize_t codec_reg_show(struct device *dev,
125 struct device_attribute *attr, char *buf)
126{
127 struct snd_soc_device *devdata = dev_get_drvdata(dev);
128 return soc_codec_reg_show(devdata->card->codec, buf);
129}
130
131static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
132
133#ifdef CONFIG_DEBUG_FS
134static int codec_reg_open_file(struct inode *inode, struct file *file)
135{
136 file->private_data = inode->i_private;
137 return 0;
138}
139
140static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
141 size_t count, loff_t *ppos)
142{
143 ssize_t ret;
144 struct snd_soc_codec *codec = file->private_data;
145 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
146 if (!buf)
147 return -ENOMEM;
148 ret = soc_codec_reg_show(codec, buf);
149 if (ret >= 0)
150 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
151 kfree(buf);
152 return ret;
153}
154
155static ssize_t codec_reg_write_file(struct file *file,
156 const char __user *user_buf, size_t count, loff_t *ppos)
157{
158 char buf[32];
159 int buf_size;
160 char *start = buf;
161 unsigned long reg, value;
162 int step = 1;
163 struct snd_soc_codec *codec = file->private_data;
164
165 buf_size = min(count, (sizeof(buf)-1));
166 if (copy_from_user(buf, user_buf, buf_size))
167 return -EFAULT;
168 buf[buf_size] = 0;
169
170 if (codec->reg_cache_step)
171 step = codec->reg_cache_step;
172
173 while (*start == ' ')
174 start++;
175 reg = simple_strtoul(start, &start, 16);
176 if ((reg >= codec->reg_cache_size) || (reg % step))
177 return -EINVAL;
178 while (*start == ' ')
179 start++;
180 if (strict_strtoul(start, 16, &value))
181 return -EINVAL;
182 codec->write(codec, reg, value);
183 return buf_size;
184}
185
186static const struct file_operations codec_reg_fops = {
187 .open = codec_reg_open_file,
188 .read = codec_reg_read_file,
189 .write = codec_reg_write_file,
190};
191
192static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
193{
194 char codec_root[128];
195
196 if (codec->dev)
197 snprintf(codec_root, sizeof(codec_root),
198 "%s.%s", codec->name, dev_name(codec->dev));
199 else
200 snprintf(codec_root, sizeof(codec_root),
201 "%s", codec->name);
202
203 codec->debugfs_codec_root = debugfs_create_dir(codec_root,
204 debugfs_root);
205 if (!codec->debugfs_codec_root) {
206 printk(KERN_WARNING
207 "ASoC: Failed to create codec debugfs directory\n");
208 return;
209 }
210
211 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
212 codec->debugfs_codec_root,
213 codec, &codec_reg_fops);
214 if (!codec->debugfs_reg)
215 printk(KERN_WARNING
216 "ASoC: Failed to create codec register debugfs file\n");
217
218 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
219 codec->debugfs_codec_root,
220 &codec->pop_time);
221 if (!codec->debugfs_pop_time)
222 printk(KERN_WARNING
223 "Failed to create pop time debugfs file\n");
224
225 codec->debugfs_dapm = debugfs_create_dir("dapm",
226 codec->debugfs_codec_root);
227 if (!codec->debugfs_dapm)
228 printk(KERN_WARNING
229 "Failed to create DAPM debugfs directory\n");
230
231 snd_soc_dapm_debugfs_init(codec);
232}
233
234static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
235{
236 debugfs_remove_recursive(codec->debugfs_codec_root);
237}
238
239#else
240
241static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
242{
243}
244
245static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
246{
247}
248#endif
249
84#ifdef CONFIG_SND_SOC_AC97_BUS 250#ifdef CONFIG_SND_SOC_AC97_BUS
85/* unregister ac97 codec */ 251/* unregister ac97 codec */
86static int soc_ac97_dev_unregister(struct snd_soc_codec *codec) 252static int soc_ac97_dev_unregister(struct snd_soc_codec *codec)
@@ -790,56 +956,21 @@ static int soc_resume(struct device *dev)
790 956
791 return 0; 957 return 0;
792} 958}
793
794/**
795 * snd_soc_suspend_device: Notify core of device suspend
796 *
797 * @dev: Device being suspended.
798 *
799 * In order to ensure that the entire audio subsystem is suspended in a
800 * coordinated fashion ASoC devices should suspend themselves when
801 * called by ASoC. When the standard kernel suspend process asks the
802 * device to suspend it should call this function to initiate a suspend
803 * of the entire ASoC card.
804 *
805 * \note Currently this function is stubbed out.
806 */
807int snd_soc_suspend_device(struct device *dev)
808{
809 return 0;
810}
811EXPORT_SYMBOL_GPL(snd_soc_suspend_device);
812
813/**
814 * snd_soc_resume_device: Notify core of device resume
815 *
816 * @dev: Device being resumed.
817 *
818 * In order to ensure that the entire audio subsystem is resumed in a
819 * coordinated fashion ASoC devices should resume themselves when called
820 * by ASoC. When the standard kernel resume process asks the device
821 * to resume it should call this function. Once all the components of
822 * the card have notified that they are ready to be resumed the card
823 * will be resumed.
824 *
825 * \note Currently this function is stubbed out.
826 */
827int snd_soc_resume_device(struct device *dev)
828{
829 return 0;
830}
831EXPORT_SYMBOL_GPL(snd_soc_resume_device);
832#else 959#else
833#define soc_suspend NULL 960#define soc_suspend NULL
834#define soc_resume NULL 961#define soc_resume NULL
835#endif 962#endif
836 963
964static struct snd_soc_dai_ops null_dai_ops = {
965};
966
837static void snd_soc_instantiate_card(struct snd_soc_card *card) 967static void snd_soc_instantiate_card(struct snd_soc_card *card)
838{ 968{
839 struct platform_device *pdev = container_of(card->dev, 969 struct platform_device *pdev = container_of(card->dev,
840 struct platform_device, 970 struct platform_device,
841 dev); 971 dev);
842 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev; 972 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
973 struct snd_soc_codec *codec;
843 struct snd_soc_platform *platform; 974 struct snd_soc_platform *platform;
844 struct snd_soc_dai *dai; 975 struct snd_soc_dai *dai;
845 int i, found, ret, ac97; 976 int i, found, ret, ac97;
@@ -877,6 +1008,11 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
877 ac97 = 1; 1008 ac97 = 1;
878 } 1009 }
879 1010
1011 for (i = 0; i < card->num_links; i++) {
1012 if (!card->dai_link[i].codec_dai->ops)
1013 card->dai_link[i].codec_dai->ops = &null_dai_ops;
1014 }
1015
880 /* If we have AC97 in the system then don't wait for the 1016 /* If we have AC97 in the system then don't wait for the
881 * codec. This will need revisiting if we have to handle 1017 * codec. This will need revisiting if we have to handle
882 * systems with mixed AC97 and non-AC97 parts. Only check for 1018 * systems with mixed AC97 and non-AC97 parts. Only check for
@@ -923,6 +1059,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
923 if (ret < 0) 1059 if (ret < 0)
924 goto cpu_dai_err; 1060 goto cpu_dai_err;
925 } 1061 }
1062 codec = card->codec;
926 1063
927 if (platform->probe) { 1064 if (platform->probe) {
928 ret = platform->probe(pdev); 1065 ret = platform->probe(pdev);
@@ -937,10 +1074,69 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
937 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred); 1074 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
938#endif 1075#endif
939 1076
1077 for (i = 0; i < card->num_links; i++) {
1078 if (card->dai_link[i].init) {
1079 ret = card->dai_link[i].init(codec);
1080 if (ret < 0) {
1081 printk(KERN_ERR "asoc: failed to init %s\n",
1082 card->dai_link[i].stream_name);
1083 continue;
1084 }
1085 }
1086 if (card->dai_link[i].codec_dai->ac97_control)
1087 ac97 = 1;
1088 }
1089
1090 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1091 "%s", card->name);
1092 snprintf(codec->card->longname, sizeof(codec->card->longname),
1093 "%s (%s)", card->name, codec->name);
1094
1095 /* Make sure all DAPM widgets are instantiated */
1096 snd_soc_dapm_new_widgets(codec);
1097
1098 ret = snd_card_register(codec->card);
1099 if (ret < 0) {
1100 printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
1101 codec->name);
1102 goto card_err;
1103 }
1104
1105 mutex_lock(&codec->mutex);
1106#ifdef CONFIG_SND_SOC_AC97_BUS
1107 /* Only instantiate AC97 if not already done by the adaptor
1108 * for the generic AC97 subsystem.
1109 */
1110 if (ac97 && strcmp(codec->name, "AC97") != 0) {
1111 ret = soc_ac97_dev_register(codec);
1112 if (ret < 0) {
1113 printk(KERN_ERR "asoc: AC97 device register failed\n");
1114 snd_card_free(codec->card);
1115 mutex_unlock(&codec->mutex);
1116 goto card_err;
1117 }
1118 }
1119#endif
1120
1121 ret = snd_soc_dapm_sys_add(card->socdev->dev);
1122 if (ret < 0)
1123 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
1124
1125 ret = device_create_file(card->socdev->dev, &dev_attr_codec_reg);
1126 if (ret < 0)
1127 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1128
1129 soc_init_codec_debugfs(codec);
1130 mutex_unlock(&codec->mutex);
1131
940 card->instantiated = 1; 1132 card->instantiated = 1;
941 1133
942 return; 1134 return;
943 1135
1136card_err:
1137 if (platform->remove)
1138 platform->remove(pdev);
1139
944platform_err: 1140platform_err:
945 if (codec_dev->remove) 1141 if (codec_dev->remove)
946 codec_dev->remove(pdev); 1142 codec_dev->remove(pdev);
@@ -1143,157 +1339,6 @@ int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg)
1143} 1339}
1144EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register); 1340EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
1145 1341
1146/* codec register dump */
1147static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
1148{
1149 int i, step = 1, count = 0;
1150
1151 if (!codec->reg_cache_size)
1152 return 0;
1153
1154 if (codec->reg_cache_step)
1155 step = codec->reg_cache_step;
1156
1157 count += sprintf(buf, "%s registers\n", codec->name);
1158 for (i = 0; i < codec->reg_cache_size; i += step) {
1159 if (codec->readable_register && !codec->readable_register(i))
1160 continue;
1161
1162 count += sprintf(buf + count, "%2x: ", i);
1163 if (count >= PAGE_SIZE - 1)
1164 break;
1165
1166 if (codec->display_register)
1167 count += codec->display_register(codec, buf + count,
1168 PAGE_SIZE - count, i);
1169 else
1170 count += snprintf(buf + count, PAGE_SIZE - count,
1171 "%4x", codec->read(codec, i));
1172
1173 if (count >= PAGE_SIZE - 1)
1174 break;
1175
1176 count += snprintf(buf + count, PAGE_SIZE - count, "\n");
1177 if (count >= PAGE_SIZE - 1)
1178 break;
1179 }
1180
1181 /* Truncate count; min() would cause a warning */
1182 if (count >= PAGE_SIZE)
1183 count = PAGE_SIZE - 1;
1184
1185 return count;
1186}
1187static ssize_t codec_reg_show(struct device *dev,
1188 struct device_attribute *attr, char *buf)
1189{
1190 struct snd_soc_device *devdata = dev_get_drvdata(dev);
1191 return soc_codec_reg_show(devdata->card->codec, buf);
1192}
1193
1194static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
1195
1196#ifdef CONFIG_DEBUG_FS
1197static int codec_reg_open_file(struct inode *inode, struct file *file)
1198{
1199 file->private_data = inode->i_private;
1200 return 0;
1201}
1202
1203static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
1204 size_t count, loff_t *ppos)
1205{
1206 ssize_t ret;
1207 struct snd_soc_codec *codec = file->private_data;
1208 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1209 if (!buf)
1210 return -ENOMEM;
1211 ret = soc_codec_reg_show(codec, buf);
1212 if (ret >= 0)
1213 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1214 kfree(buf);
1215 return ret;
1216}
1217
1218static ssize_t codec_reg_write_file(struct file *file,
1219 const char __user *user_buf, size_t count, loff_t *ppos)
1220{
1221 char buf[32];
1222 int buf_size;
1223 char *start = buf;
1224 unsigned long reg, value;
1225 int step = 1;
1226 struct snd_soc_codec *codec = file->private_data;
1227
1228 buf_size = min(count, (sizeof(buf)-1));
1229 if (copy_from_user(buf, user_buf, buf_size))
1230 return -EFAULT;
1231 buf[buf_size] = 0;
1232
1233 if (codec->reg_cache_step)
1234 step = codec->reg_cache_step;
1235
1236 while (*start == ' ')
1237 start++;
1238 reg = simple_strtoul(start, &start, 16);
1239 if ((reg >= codec->reg_cache_size) || (reg % step))
1240 return -EINVAL;
1241 while (*start == ' ')
1242 start++;
1243 if (strict_strtoul(start, 16, &value))
1244 return -EINVAL;
1245 codec->write(codec, reg, value);
1246 return buf_size;
1247}
1248
1249static const struct file_operations codec_reg_fops = {
1250 .open = codec_reg_open_file,
1251 .read = codec_reg_read_file,
1252 .write = codec_reg_write_file,
1253};
1254
1255static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1256{
1257 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
1258 debugfs_root, codec,
1259 &codec_reg_fops);
1260 if (!codec->debugfs_reg)
1261 printk(KERN_WARNING
1262 "ASoC: Failed to create codec register debugfs file\n");
1263
1264 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
1265 debugfs_root,
1266 &codec->pop_time);
1267 if (!codec->debugfs_pop_time)
1268 printk(KERN_WARNING
1269 "Failed to create pop time debugfs file\n");
1270
1271 codec->debugfs_dapm = debugfs_create_dir("dapm", debugfs_root);
1272 if (!codec->debugfs_dapm)
1273 printk(KERN_WARNING
1274 "Failed to create DAPM debugfs directory\n");
1275
1276 snd_soc_dapm_debugfs_init(codec);
1277}
1278
1279static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1280{
1281 debugfs_remove_recursive(codec->debugfs_dapm);
1282 debugfs_remove(codec->debugfs_pop_time);
1283 debugfs_remove(codec->debugfs_reg);
1284}
1285
1286#else
1287
1288static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1289{
1290}
1291
1292static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1293{
1294}
1295#endif
1296
1297/** 1342/**
1298 * snd_soc_new_ac97_codec - initailise AC97 device 1343 * snd_soc_new_ac97_codec - initailise AC97 device
1299 * @codec: audio codec 1344 * @codec: audio codec
@@ -1361,19 +1406,41 @@ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
1361 int change; 1406 int change;
1362 unsigned int old, new; 1407 unsigned int old, new;
1363 1408
1364 mutex_lock(&io_mutex);
1365 old = snd_soc_read(codec, reg); 1409 old = snd_soc_read(codec, reg);
1366 new = (old & ~mask) | value; 1410 new = (old & ~mask) | value;
1367 change = old != new; 1411 change = old != new;
1368 if (change) 1412 if (change)
1369 snd_soc_write(codec, reg, new); 1413 snd_soc_write(codec, reg, new);
1370 1414
1371 mutex_unlock(&io_mutex);
1372 return change; 1415 return change;
1373} 1416}
1374EXPORT_SYMBOL_GPL(snd_soc_update_bits); 1417EXPORT_SYMBOL_GPL(snd_soc_update_bits);
1375 1418
1376/** 1419/**
1420 * snd_soc_update_bits_locked - update codec register bits
1421 * @codec: audio codec
1422 * @reg: codec register
1423 * @mask: register mask
1424 * @value: new value
1425 *
1426 * Writes new register value, and takes the codec mutex.
1427 *
1428 * Returns 1 for change else 0.
1429 */
1430static int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
1431 unsigned short reg, unsigned int mask,
1432 unsigned int value)
1433{
1434 int change;
1435
1436 mutex_lock(&codec->mutex);
1437 change = snd_soc_update_bits(codec, reg, mask, value);
1438 mutex_unlock(&codec->mutex);
1439
1440 return change;
1441}
1442
1443/**
1377 * snd_soc_test_bits - test register for change 1444 * snd_soc_test_bits - test register for change
1378 * @codec: audio codec 1445 * @codec: audio codec
1379 * @reg: codec register 1446 * @reg: codec register
@@ -1391,11 +1458,9 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
1391 int change; 1458 int change;
1392 unsigned int old, new; 1459 unsigned int old, new;
1393 1460
1394 mutex_lock(&io_mutex);
1395 old = snd_soc_read(codec, reg); 1461 old = snd_soc_read(codec, reg);
1396 new = (old & ~mask) | value; 1462 new = (old & ~mask) | value;
1397 change = old != new; 1463 change = old != new;
1398 mutex_unlock(&io_mutex);
1399 1464
1400 return change; 1465 return change;
1401} 1466}
@@ -1442,89 +1507,16 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1442 mutex_unlock(&codec->mutex); 1507 mutex_unlock(&codec->mutex);
1443 return ret; 1508 return ret;
1444 } 1509 }
1445 }
1446
1447 mutex_unlock(&codec->mutex);
1448 return ret;
1449}
1450EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1451
1452/**
1453 * snd_soc_init_card - register sound card
1454 * @socdev: the SoC audio device
1455 *
1456 * Register a SoC sound card. Also registers an AC97 device if the
1457 * codec is AC97 for ad hoc devices.
1458 *
1459 * Returns 0 for success, else error.
1460 */
1461int snd_soc_init_card(struct snd_soc_device *socdev)
1462{
1463 struct snd_soc_card *card = socdev->card;
1464 struct snd_soc_codec *codec = card->codec;
1465 int ret = 0, i, ac97 = 0, err = 0;
1466
1467 for (i = 0; i < card->num_links; i++) {
1468 if (card->dai_link[i].init) {
1469 err = card->dai_link[i].init(codec);
1470 if (err < 0) {
1471 printk(KERN_ERR "asoc: failed to init %s\n",
1472 card->dai_link[i].stream_name);
1473 continue;
1474 }
1475 }
1476 if (card->dai_link[i].codec_dai->ac97_control) { 1510 if (card->dai_link[i].codec_dai->ac97_control) {
1477 ac97 = 1;
1478 snd_ac97_dev_add_pdata(codec->ac97, 1511 snd_ac97_dev_add_pdata(codec->ac97,
1479 card->dai_link[i].cpu_dai->ac97_pdata); 1512 card->dai_link[i].cpu_dai->ac97_pdata);
1480 } 1513 }
1481 } 1514 }
1482 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1483 "%s", card->name);
1484 snprintf(codec->card->longname, sizeof(codec->card->longname),
1485 "%s (%s)", card->name, codec->name);
1486 1515
1487 /* Make sure all DAPM widgets are instantiated */
1488 snd_soc_dapm_new_widgets(codec);
1489
1490 ret = snd_card_register(codec->card);
1491 if (ret < 0) {
1492 printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
1493 codec->name);
1494 goto out;
1495 }
1496
1497 mutex_lock(&codec->mutex);
1498#ifdef CONFIG_SND_SOC_AC97_BUS
1499 /* Only instantiate AC97 if not already done by the adaptor
1500 * for the generic AC97 subsystem.
1501 */
1502 if (ac97 && strcmp(codec->name, "AC97") != 0) {
1503 ret = soc_ac97_dev_register(codec);
1504 if (ret < 0) {
1505 printk(KERN_ERR "asoc: AC97 device register failed\n");
1506 snd_card_free(codec->card);
1507 mutex_unlock(&codec->mutex);
1508 goto out;
1509 }
1510 }
1511#endif
1512
1513 err = snd_soc_dapm_sys_add(socdev->dev);
1514 if (err < 0)
1515 printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
1516
1517 err = device_create_file(socdev->dev, &dev_attr_codec_reg);
1518 if (err < 0)
1519 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1520
1521 soc_init_codec_debugfs(codec);
1522 mutex_unlock(&codec->mutex); 1516 mutex_unlock(&codec->mutex);
1523
1524out:
1525 return ret; 1517 return ret;
1526} 1518}
1527EXPORT_SYMBOL_GPL(snd_soc_init_card); 1519EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1528 1520
1529/** 1521/**
1530 * snd_soc_free_pcms - free sound card and pcms 1522 * snd_soc_free_pcms - free sound card and pcms
@@ -1726,7 +1718,7 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
1726 mask |= (bitmask - 1) << e->shift_r; 1718 mask |= (bitmask - 1) << e->shift_r;
1727 } 1719 }
1728 1720
1729 return snd_soc_update_bits(codec, e->reg, mask, val); 1721 return snd_soc_update_bits_locked(codec, e->reg, mask, val);
1730} 1722}
1731EXPORT_SYMBOL_GPL(snd_soc_put_enum_double); 1723EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
1732 1724
@@ -1800,7 +1792,7 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
1800 mask |= e->mask << e->shift_r; 1792 mask |= e->mask << e->shift_r;
1801 } 1793 }
1802 1794
1803 return snd_soc_update_bits(codec, e->reg, mask, val); 1795 return snd_soc_update_bits_locked(codec, e->reg, mask, val);
1804} 1796}
1805EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double); 1797EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double);
1806 1798
@@ -1961,7 +1953,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
1961 val_mask |= mask << rshift; 1953 val_mask |= mask << rshift;
1962 val |= val2 << rshift; 1954 val |= val2 << rshift;
1963 } 1955 }
1964 return snd_soc_update_bits(codec, reg, val_mask, val); 1956 return snd_soc_update_bits_locked(codec, reg, val_mask, val);
1965} 1957}
1966EXPORT_SYMBOL_GPL(snd_soc_put_volsw); 1958EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
1967 1959
@@ -2067,11 +2059,11 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
2067 val = val << shift; 2059 val = val << shift;
2068 val2 = val2 << shift; 2060 val2 = val2 << shift;
2069 2061
2070 err = snd_soc_update_bits(codec, reg, val_mask, val); 2062 err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
2071 if (err < 0) 2063 if (err < 0)
2072 return err; 2064 return err;
2073 2065
2074 err = snd_soc_update_bits(codec, reg2, val_mask, val2); 2066 err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2);
2075 return err; 2067 return err;
2076} 2068}
2077EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r); 2069EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);
@@ -2150,7 +2142,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
2150 val = (ucontrol->value.integer.value[0]+min) & 0xff; 2142 val = (ucontrol->value.integer.value[0]+min) & 0xff;
2151 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8; 2143 val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
2152 2144
2153 return snd_soc_update_bits(codec, reg, 0xffff, val); 2145 return snd_soc_update_bits_locked(codec, reg, 0xffff, val);
2154} 2146}
2155EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); 2147EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
2156 2148
@@ -2197,16 +2189,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
2197 * snd_soc_dai_set_pll - configure DAI PLL. 2189 * snd_soc_dai_set_pll - configure DAI PLL.
2198 * @dai: DAI 2190 * @dai: DAI
2199 * @pll_id: DAI specific PLL ID 2191 * @pll_id: DAI specific PLL ID
2192 * @source: DAI specific source for the PLL
2200 * @freq_in: PLL input clock frequency in Hz 2193 * @freq_in: PLL input clock frequency in Hz
2201 * @freq_out: requested PLL output clock frequency in Hz 2194 * @freq_out: requested PLL output clock frequency in Hz
2202 * 2195 *
2203 * Configures and enables PLL to generate output clock based on input clock. 2196 * Configures and enables PLL to generate output clock based on input clock.
2204 */ 2197 */
2205int snd_soc_dai_set_pll(struct snd_soc_dai *dai, 2198int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source,
2206 int pll_id, unsigned int freq_in, unsigned int freq_out) 2199 unsigned int freq_in, unsigned int freq_out)
2207{ 2200{
2208 if (dai->ops && dai->ops->set_pll) 2201 if (dai->ops && dai->ops->set_pll)
2209 return dai->ops->set_pll(dai, pll_id, freq_in, freq_out); 2202 return dai->ops->set_pll(dai, pll_id, source,
2203 freq_in, freq_out);
2210 else 2204 else
2211 return -EINVAL; 2205 return -EINVAL;
2212} 2206}
@@ -2251,6 +2245,30 @@ int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
2251EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); 2245EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
2252 2246
2253/** 2247/**
2248 * snd_soc_dai_set_channel_map - configure DAI audio channel map
2249 * @dai: DAI
2250 * @tx_num: how many TX channels
2251 * @tx_slot: pointer to an array which imply the TX slot number channel
2252 * 0~num-1 uses
2253 * @rx_num: how many RX channels
2254 * @rx_slot: pointer to an array which imply the RX slot number channel
2255 * 0~num-1 uses
2256 *
2257 * configure the relationship between channel number and TDM slot number.
2258 */
2259int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai,
2260 unsigned int tx_num, unsigned int *tx_slot,
2261 unsigned int rx_num, unsigned int *rx_slot)
2262{
2263 if (dai->ops && dai->ops->set_channel_map)
2264 return dai->ops->set_channel_map(dai, tx_num, tx_slot,
2265 rx_num, rx_slot);
2266 else
2267 return -EINVAL;
2268}
2269EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map);
2270
2271/**
2254 * snd_soc_dai_set_tristate - configure DAI system or master clock. 2272 * snd_soc_dai_set_tristate - configure DAI system or master clock.
2255 * @dai: DAI 2273 * @dai: DAI
2256 * @tristate: tristate enable 2274 * @tristate: tristate enable
@@ -2329,9 +2347,6 @@ static int snd_soc_unregister_card(struct snd_soc_card *card)
2329 return 0; 2347 return 0;
2330} 2348}
2331 2349
2332static struct snd_soc_dai_ops null_dai_ops = {
2333};
2334
2335/** 2350/**
2336 * snd_soc_register_dai - Register a DAI with the ASoC core 2351 * snd_soc_register_dai - Register a DAI with the ASoC core
2337 * 2352 *
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 8de6f9dec4a2..0d294ef72590 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -719,6 +719,10 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
719 719
720 /* Check if one of our outputs is connected */ 720 /* Check if one of our outputs is connected */
721 list_for_each_entry(path, &w->sinks, list_source) { 721 list_for_each_entry(path, &w->sinks, list_source) {
722 if (path->connected &&
723 !path->connected(path->source, path->sink))
724 continue;
725
722 if (path->sink && path->sink->power_check && 726 if (path->sink && path->sink->power_check &&
723 path->sink->power_check(path->sink)) { 727 path->sink->power_check(path->sink)) {
724 power = 1; 728 power = 1;
@@ -973,9 +977,19 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
973 if (!w->power_check) 977 if (!w->power_check)
974 continue; 978 continue;
975 979
976 power = w->power_check(w); 980 /* If we're suspending then pull down all the
977 if (power) 981 * power. */
978 sys_power = 1; 982 switch (event) {
983 case SND_SOC_DAPM_STREAM_SUSPEND:
984 power = 0;
985 break;
986
987 default:
988 power = w->power_check(w);
989 if (power)
990 sys_power = 1;
991 break;
992 }
979 993
980 if (w->power == power) 994 if (w->power == power)
981 continue; 995 continue;
@@ -999,8 +1013,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
999 case SND_SOC_DAPM_STREAM_RESUME: 1013 case SND_SOC_DAPM_STREAM_RESUME:
1000 sys_power = 1; 1014 sys_power = 1;
1001 break; 1015 break;
1016 case SND_SOC_DAPM_STREAM_SUSPEND:
1017 sys_power = 0;
1018 break;
1002 case SND_SOC_DAPM_STREAM_NOP: 1019 case SND_SOC_DAPM_STREAM_NOP:
1003 sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; 1020 sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY;
1021 break;
1004 default: 1022 default:
1005 break; 1023 break;
1006 } 1024 }
@@ -1138,6 +1156,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1138 w->active ? "active" : "inactive"); 1156 w->active ? "active" : "inactive");
1139 1157
1140 list_for_each_entry(p, &w->sources, list_sink) { 1158 list_for_each_entry(p, &w->sources, list_sink) {
1159 if (p->connected && !p->connected(w, p->sink))
1160 continue;
1161
1141 if (p->connect) 1162 if (p->connect)
1142 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1163 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1143 " in %s %s\n", 1164 " in %s %s\n",
@@ -1145,6 +1166,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1145 p->source->name); 1166 p->source->name);
1146 } 1167 }
1147 list_for_each_entry(p, &w->sinks, list_source) { 1168 list_for_each_entry(p, &w->sinks, list_source) {
1169 if (p->connected && !p->connected(w, p->sink))
1170 continue;
1171
1148 if (p->connect) 1172 if (p->connect)
1149 ret += snprintf(buf + ret, PAGE_SIZE - ret, 1173 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1150 " out %s %s\n", 1174 " out %s %s\n",
@@ -1192,8 +1216,8 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec)
1192 1216
1193/* test and update the power status of a mux widget */ 1217/* test and update the power status of a mux widget */
1194static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, 1218static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1195 struct snd_kcontrol *kcontrol, int mask, 1219 struct snd_kcontrol *kcontrol, int change,
1196 int mux, int val, struct soc_enum *e) 1220 int mux, struct soc_enum *e)
1197{ 1221{
1198 struct snd_soc_dapm_path *path; 1222 struct snd_soc_dapm_path *path;
1199 int found = 0; 1223 int found = 0;
@@ -1202,7 +1226,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1202 widget->id != snd_soc_dapm_value_mux) 1226 widget->id != snd_soc_dapm_value_mux)
1203 return -ENODEV; 1227 return -ENODEV;
1204 1228
1205 if (!snd_soc_test_bits(widget->codec, e->reg, mask, val)) 1229 if (!change)
1206 return 0; 1230 return 0;
1207 1231
1208 /* find dapm widget path assoc with kcontrol */ 1232 /* find dapm widget path assoc with kcontrol */
@@ -1387,10 +1411,13 @@ int snd_soc_dapm_sync(struct snd_soc_codec *codec)
1387EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1411EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
1388 1412
1389static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, 1413static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1390 const char *sink, const char *control, const char *source) 1414 const struct snd_soc_dapm_route *route)
1391{ 1415{
1392 struct snd_soc_dapm_path *path; 1416 struct snd_soc_dapm_path *path;
1393 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 1417 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
1418 const char *sink = route->sink;
1419 const char *control = route->control;
1420 const char *source = route->source;
1394 int ret = 0; 1421 int ret = 0;
1395 1422
1396 /* find src and dest widgets */ 1423 /* find src and dest widgets */
@@ -1414,6 +1441,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1414 1441
1415 path->source = wsource; 1442 path->source = wsource;
1416 path->sink = wsink; 1443 path->sink = wsink;
1444 path->connected = route->connected;
1417 INIT_LIST_HEAD(&path->list); 1445 INIT_LIST_HEAD(&path->list);
1418 INIT_LIST_HEAD(&path->list_source); 1446 INIT_LIST_HEAD(&path->list_source);
1419 INIT_LIST_HEAD(&path->list_sink); 1447 INIT_LIST_HEAD(&path->list_sink);
@@ -1514,8 +1542,7 @@ int snd_soc_dapm_add_routes(struct snd_soc_codec *codec,
1514 int i, ret; 1542 int i, ret;
1515 1543
1516 for (i = 0; i < num; i++) { 1544 for (i = 0; i < num; i++) {
1517 ret = snd_soc_dapm_add_route(codec, route->sink, 1545 ret = snd_soc_dapm_add_route(codec, route);
1518 route->control, route->source);
1519 if (ret < 0) { 1546 if (ret < 0) {
1520 printk(KERN_ERR "Failed to add route %s->%s\n", 1547 printk(KERN_ERR "Failed to add route %s->%s\n",
1521 route->source, 1548 route->source,
@@ -1752,7 +1779,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1752{ 1779{
1753 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1780 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1754 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1781 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1755 unsigned int val, mux; 1782 unsigned int val, mux, change;
1756 unsigned int mask, bitmask; 1783 unsigned int mask, bitmask;
1757 int ret = 0; 1784 int ret = 0;
1758 1785
@@ -1772,20 +1799,21 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1772 1799
1773 mutex_lock(&widget->codec->mutex); 1800 mutex_lock(&widget->codec->mutex);
1774 widget->value = val; 1801 widget->value = val;
1775 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e); 1802 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1776 if (widget->event) { 1803 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1777 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1804
1778 ret = widget->event(widget, 1805 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1779 kcontrol, SND_SOC_DAPM_PRE_REG); 1806 ret = widget->event(widget,
1780 if (ret < 0) 1807 kcontrol, SND_SOC_DAPM_PRE_REG);
1781 goto out; 1808 if (ret < 0)
1782 } 1809 goto out;
1783 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1810 }
1784 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1811
1785 ret = widget->event(widget, 1812 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1786 kcontrol, SND_SOC_DAPM_POST_REG); 1813
1787 } else 1814 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1788 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1815 ret = widget->event(widget,
1816 kcontrol, SND_SOC_DAPM_POST_REG);
1789 1817
1790out: 1818out:
1791 mutex_unlock(&widget->codec->mutex); 1819 mutex_unlock(&widget->codec->mutex);
@@ -1794,6 +1822,54 @@ out:
1794EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 1822EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1795 1823
1796/** 1824/**
1825 * snd_soc_dapm_get_enum_virt - Get virtual DAPM mux
1826 * @kcontrol: mixer control
1827 * @ucontrol: control element information
1828 *
1829 * Returns 0 for success.
1830 */
1831int snd_soc_dapm_get_enum_virt(struct snd_kcontrol *kcontrol,
1832 struct snd_ctl_elem_value *ucontrol)
1833{
1834 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1835
1836 ucontrol->value.enumerated.item[0] = widget->value;
1837
1838 return 0;
1839}
1840EXPORT_SYMBOL_GPL(snd_soc_dapm_get_enum_virt);
1841
1842/**
1843 * snd_soc_dapm_put_enum_virt - Set virtual DAPM mux
1844 * @kcontrol: mixer control
1845 * @ucontrol: control element information
1846 *
1847 * Returns 0 for success.
1848 */
1849int snd_soc_dapm_put_enum_virt(struct snd_kcontrol *kcontrol,
1850 struct snd_ctl_elem_value *ucontrol)
1851{
1852 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1853 struct soc_enum *e =
1854 (struct soc_enum *)kcontrol->private_value;
1855 int change;
1856 int ret = 0;
1857
1858 if (ucontrol->value.enumerated.item[0] >= e->max)
1859 return -EINVAL;
1860
1861 mutex_lock(&widget->codec->mutex);
1862
1863 change = widget->value != ucontrol->value.enumerated.item[0];
1864 widget->value = ucontrol->value.enumerated.item[0];
1865 dapm_mux_update_power(widget, kcontrol, change, widget->value, e);
1866
1867 mutex_unlock(&widget->codec->mutex);
1868 return ret;
1869}
1870EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_virt);
1871
1872/**
1797 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get 1873 * snd_soc_dapm_get_value_enum_double - dapm semi enumerated double mixer get
1798 * callback 1874 * callback
1799 * @kcontrol: mixer control 1875 * @kcontrol: mixer control
@@ -1851,7 +1927,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1851{ 1927{
1852 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 1928 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
1853 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1929 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1854 unsigned int val, mux; 1930 unsigned int val, mux, change;
1855 unsigned int mask; 1931 unsigned int mask;
1856 int ret = 0; 1932 int ret = 0;
1857 1933
@@ -1869,20 +1945,21 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1869 1945
1870 mutex_lock(&widget->codec->mutex); 1946 mutex_lock(&widget->codec->mutex);
1871 widget->value = val; 1947 widget->value = val;
1872 dapm_mux_update_power(widget, kcontrol, mask, mux, val, e); 1948 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1873 if (widget->event) { 1949 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1874 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1950
1875 ret = widget->event(widget, 1951 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1876 kcontrol, SND_SOC_DAPM_PRE_REG); 1952 ret = widget->event(widget,
1877 if (ret < 0) 1953 kcontrol, SND_SOC_DAPM_PRE_REG);
1878 goto out; 1954 if (ret < 0)
1879 } 1955 goto out;
1880 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1956 }
1881 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1957
1882 ret = widget->event(widget, 1958 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val);
1883 kcontrol, SND_SOC_DAPM_POST_REG); 1959
1884 } else 1960 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1885 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1961 ret = widget->event(widget,
1962 kcontrol, SND_SOC_DAPM_POST_REG);
1886 1963
1887out: 1964out:
1888 mutex_unlock(&widget->codec->mutex); 1965 mutex_unlock(&widget->codec->mutex);
@@ -2072,9 +2149,9 @@ int snd_soc_dapm_stream_event(struct snd_soc_codec *codec,
2072 } 2149 }
2073 } 2150 }
2074 } 2151 }
2075 mutex_unlock(&codec->mutex);
2076 2152
2077 dapm_power_widgets(codec, event); 2153 dapm_power_widgets(codec, event);
2154 mutex_unlock(&codec->mutex);
2078 dump_dapm(codec, __func__); 2155 dump_dapm(codec, __func__);
2079 return 0; 2156 return 0;
2080} 2157}
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 1d455ab79490..3c07a94c2e30 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new);
58 */ 58 */
59void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) 59void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
60{ 60{
61 struct snd_soc_codec *codec = jack->card->codec; 61 struct snd_soc_codec *codec;
62 struct snd_soc_jack_pin *pin; 62 struct snd_soc_jack_pin *pin;
63 int enable; 63 int enable;
64 int oldstatus; 64 int oldstatus;
@@ -67,6 +67,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
67 WARN_ON_ONCE(!jack); 67 WARN_ON_ONCE(!jack);
68 return; 68 return;
69 } 69 }
70 codec = jack->card->codec;
70 71
71 mutex_lock(&codec->mutex); 72 mutex_lock(&codec->mutex);
72 73
@@ -162,6 +163,9 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
162 else 163 else
163 report = 0; 164 report = 0;
164 165
166 if (gpio->jack_status_check)
167 report = gpio->jack_status_check();
168
165 snd_soc_jack_report(jack, report, gpio->report); 169 snd_soc_jack_report(jack, report, gpio->report);
166} 170}
167 171
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
new file mode 100644
index 000000000000..1d07b931f3d8
--- /dev/null
+++ b/sound/soc/soc-utils.c
@@ -0,0 +1,74 @@
1/*
2 * soc-util.c -- ALSA SoC Audio Layer utility functions
3 *
4 * Copyright 2009 Wolfson Microelectronics PLC.
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * Liam Girdwood <lrg@slimlogic.co.uk>
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#include <sound/core.h>
17#include <sound/pcm.h>
18#include <sound/pcm_params.h>
19#include <sound/soc.h>
20
21int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots)
22{
23 return sample_size * channels * tdm_slots;
24}
25EXPORT_SYMBOL_GPL(snd_soc_calc_frame_size);
26
27int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params)
28{
29 int sample_size;
30
31 switch (params_format(params)) {
32 case SNDRV_PCM_FORMAT_S16_LE:
33 case SNDRV_PCM_FORMAT_S16_BE:
34 sample_size = 16;
35 break;
36 case SNDRV_PCM_FORMAT_S20_3LE:
37 case SNDRV_PCM_FORMAT_S20_3BE:
38 sample_size = 20;
39 break;
40 case SNDRV_PCM_FORMAT_S24_LE:
41 case SNDRV_PCM_FORMAT_S24_BE:
42 sample_size = 24;
43 break;
44 case SNDRV_PCM_FORMAT_S32_LE:
45 case SNDRV_PCM_FORMAT_S32_BE:
46 sample_size = 32;
47 break;
48 default:
49 return -ENOTSUPP;
50 }
51
52 return snd_soc_calc_frame_size(sample_size, params_channels(params),
53 1);
54}
55EXPORT_SYMBOL_GPL(snd_soc_params_to_frame_size);
56
57int snd_soc_calc_bclk(int fs, int sample_size, int channels, int tdm_slots)
58{
59 return fs * snd_soc_calc_frame_size(sample_size, channels, tdm_slots);
60}
61EXPORT_SYMBOL_GPL(snd_soc_calc_bclk);
62
63int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params)
64{
65 int ret;
66
67 ret = snd_soc_params_to_frame_size(params);
68
69 if (ret > 0)
70 return ret * params_rate(params);
71 else
72 return ret;
73}
74EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk);
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 49c998186592..dbca7c909a31 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -353,7 +353,7 @@ static struct sound_unit *chains[SOUND_STEP];
353 * @dev: device pointer 353 * @dev: device pointer
354 * 354 *
355 * Allocate a special sound device by minor number from the sound 355 * Allocate a special sound device by minor number from the sound
356 * subsystem. The allocated number is returned on succes. On failure 356 * subsystem. The allocated number is returned on success. On failure
357 * a negative error code is returned. 357 * a negative error code is returned.
358 */ 358 */
359 359
diff --git a/sound/synth/emux/soundfont.c b/sound/synth/emux/soundfont.c
index 63c8f45c0c22..67c91230c197 100644
--- a/sound/synth/emux/soundfont.c
+++ b/sound/synth/emux/soundfont.c
@@ -374,7 +374,7 @@ sf_zone_new(struct snd_sf_list *sflist, struct snd_soundfont *sf)
374 374
375 375
376/* 376/*
377 * increment sample couter 377 * increment sample counter
378 */ 378 */
379static void 379static void
380set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf, 380set_sample_counter(struct snd_sf_list *sflist, struct snd_soundfont *sf,
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 8db0374e10d5..b074a594c595 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -2893,7 +2893,9 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
2893 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO || 2893 if ((altsd->bInterfaceClass == USB_CLASS_AUDIO ||
2894 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) && 2894 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC) &&
2895 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) { 2895 altsd->bInterfaceSubClass == USB_SUBCLASS_MIDI_STREAMING) {
2896 if (snd_usb_create_midi_interface(chip, iface, NULL) < 0) { 2896 int err = snd_usbmidi_create(chip->card, iface,
2897 &chip->midi_list, NULL);
2898 if (err < 0) {
2897 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j); 2899 snd_printk(KERN_ERR "%d:%u:%d: cannot create sequencer device\n", dev->devnum, ctrlif, j);
2898 continue; 2900 continue;
2899 } 2901 }
@@ -3038,12 +3040,11 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
3038 .type = QUIRK_MIDI_FIXED_ENDPOINT, 3040 .type = QUIRK_MIDI_FIXED_ENDPOINT,
3039 .data = &uaxx_ep 3041 .data = &uaxx_ep
3040 }; 3042 };
3041 if (chip->usb_id == USB_ID(0x0582, 0x002b)) 3043 const struct snd_usb_audio_quirk *quirk =
3042 return snd_usb_create_midi_interface(chip, iface, 3044 chip->usb_id == USB_ID(0x0582, 0x002b)
3043 &ua700_quirk); 3045 ? &ua700_quirk : &uaxx_quirk;
3044 else 3046 return snd_usbmidi_create(chip->card, iface,
3045 return snd_usb_create_midi_interface(chip, iface, 3047 &chip->midi_list, quirk);
3046 &uaxx_quirk);
3047 } 3048 }
3048 3049
3049 if (altsd->bNumEndpoints != 1) 3050 if (altsd->bNumEndpoints != 1)
@@ -3370,6 +3371,13 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
3370 return 0; /* keep this altsetting */ 3371 return 0; /* keep this altsetting */
3371} 3372}
3372 3373
3374static int create_any_midi_quirk(struct snd_usb_audio *chip,
3375 struct usb_interface *intf,
3376 const struct snd_usb_audio_quirk *quirk)
3377{
3378 return snd_usbmidi_create(chip->card, intf, &chip->midi_list, quirk);
3379}
3380
3373/* 3381/*
3374 * audio-interface quirks 3382 * audio-interface quirks
3375 * 3383 *
@@ -3387,14 +3395,14 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
3387 static const quirk_func_t quirk_funcs[] = { 3395 static const quirk_func_t quirk_funcs[] = {
3388 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk, 3396 [QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
3389 [QUIRK_COMPOSITE] = create_composite_quirk, 3397 [QUIRK_COMPOSITE] = create_composite_quirk,
3390 [QUIRK_MIDI_STANDARD_INTERFACE] = snd_usb_create_midi_interface, 3398 [QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
3391 [QUIRK_MIDI_FIXED_ENDPOINT] = snd_usb_create_midi_interface, 3399 [QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
3392 [QUIRK_MIDI_YAMAHA] = snd_usb_create_midi_interface, 3400 [QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
3393 [QUIRK_MIDI_MIDIMAN] = snd_usb_create_midi_interface, 3401 [QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
3394 [QUIRK_MIDI_NOVATION] = snd_usb_create_midi_interface, 3402 [QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
3395 [QUIRK_MIDI_FASTLANE] = snd_usb_create_midi_interface, 3403 [QUIRK_MIDI_FASTLANE] = create_any_midi_quirk,
3396 [QUIRK_MIDI_EMAGIC] = snd_usb_create_midi_interface, 3404 [QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
3397 [QUIRK_MIDI_CME] = snd_usb_create_midi_interface, 3405 [QUIRK_MIDI_CME] = create_any_midi_quirk,
3398 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk, 3406 [QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
3399 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk, 3407 [QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
3400 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk, 3408 [QUIRK_AUDIO_EDIROL_UA1000] = create_ua1000_quirk,
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 8e7f78941ba6..40ba8115fb81 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -132,7 +132,6 @@ struct snd_usb_audio {
132 int pcm_devs; 132 int pcm_devs;
133 133
134 struct list_head midi_list; /* list of midi interfaces */ 134 struct list_head midi_list; /* list of midi interfaces */
135 int next_midi_device;
136 135
137 struct list_head mixer_list; /* list of mixer interfaces */ 136 struct list_head mixer_list; /* list of mixer interfaces */
138}; 137};
@@ -210,7 +209,7 @@ struct snd_usb_midi_endpoint_info {
210/* 209/*
211 */ 210 */
212 211
213#define combine_word(s) ((*s) | ((unsigned int)(s)[1] << 8)) 212#define combine_word(s) ((*(s)) | ((unsigned int)(s)[1] << 8))
214#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16)) 213#define combine_triple(s) (combine_word(s) | ((unsigned int)(s)[2] << 16))
215#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24)) 214#define combine_quad(s) (combine_triple(s) | ((unsigned int)(s)[3] << 24))
216 215
@@ -227,8 +226,10 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
227 int ignore_error); 226 int ignore_error);
228void snd_usb_mixer_disconnect(struct list_head *p); 227void snd_usb_mixer_disconnect(struct list_head *p);
229 228
230int snd_usb_create_midi_interface(struct snd_usb_audio *chip, struct usb_interface *iface, 229int snd_usbmidi_create(struct snd_card *card,
231 const struct snd_usb_audio_quirk *quirk); 230 struct usb_interface *iface,
231 struct list_head *midi_list,
232 const struct snd_usb_audio_quirk *quirk);
232void snd_usbmidi_input_stop(struct list_head* p); 233void snd_usbmidi_input_stop(struct list_head* p);
233void snd_usbmidi_input_start(struct list_head* p); 234void snd_usbmidi_input_start(struct list_head* p);
234void snd_usbmidi_disconnect(struct list_head *p); 235void snd_usbmidi_disconnect(struct list_head *p);
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 0eff19ceb7e1..6e89b8368d9a 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * usbmidi.c - ALSA USB MIDI driver 2 * usbmidi.c - ALSA USB MIDI driver
3 * 3 *
4 * Copyright (c) 2002-2007 Clemens Ladisch 4 * Copyright (c) 2002-2009 Clemens Ladisch
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Based on the OSS usb-midi driver by NAGANO Daisuke, 7 * Based on the OSS usb-midi driver by NAGANO Daisuke,
@@ -47,6 +47,7 @@
47#include <linux/usb.h> 47#include <linux/usb.h>
48#include <linux/wait.h> 48#include <linux/wait.h>
49#include <sound/core.h> 49#include <sound/core.h>
50#include <sound/control.h>
50#include <sound/rawmidi.h> 51#include <sound/rawmidi.h>
51#include <sound/asequencer.h> 52#include <sound/asequencer.h>
52#include "usbaudio.h" 53#include "usbaudio.h"
@@ -101,7 +102,8 @@ struct usb_protocol_ops {
101}; 102};
102 103
103struct snd_usb_midi { 104struct snd_usb_midi {
104 struct snd_usb_audio *chip; 105 struct usb_device *dev;
106 struct snd_card *card;
105 struct usb_interface *iface; 107 struct usb_interface *iface;
106 const struct snd_usb_audio_quirk *quirk; 108 const struct snd_usb_audio_quirk *quirk;
107 struct snd_rawmidi *rmidi; 109 struct snd_rawmidi *rmidi;
@@ -109,13 +111,19 @@ struct snd_usb_midi {
109 struct list_head list; 111 struct list_head list;
110 struct timer_list error_timer; 112 struct timer_list error_timer;
111 spinlock_t disc_lock; 113 spinlock_t disc_lock;
114 struct mutex mutex;
115 u32 usb_id;
116 int next_midi_device;
112 117
113 struct snd_usb_midi_endpoint { 118 struct snd_usb_midi_endpoint {
114 struct snd_usb_midi_out_endpoint *out; 119 struct snd_usb_midi_out_endpoint *out;
115 struct snd_usb_midi_in_endpoint *in; 120 struct snd_usb_midi_in_endpoint *in;
116 } endpoints[MIDI_MAX_ENDPOINTS]; 121 } endpoints[MIDI_MAX_ENDPOINTS];
117 unsigned long input_triggered; 122 unsigned long input_triggered;
123 unsigned int opened;
118 unsigned char disconnected; 124 unsigned char disconnected;
125
126 struct snd_kcontrol *roland_load_ctl;
119}; 127};
120 128
121struct snd_usb_midi_out_endpoint { 129struct snd_usb_midi_out_endpoint {
@@ -255,7 +263,7 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb)
255 } 263 }
256 } 264 }
257 265
258 urb->dev = ep->umidi->chip->dev; 266 urb->dev = ep->umidi->dev;
259 snd_usbmidi_submit_urb(urb, GFP_ATOMIC); 267 snd_usbmidi_submit_urb(urb, GFP_ATOMIC);
260} 268}
261 269
@@ -296,7 +304,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep)
296 unsigned long flags; 304 unsigned long flags;
297 305
298 spin_lock_irqsave(&ep->buffer_lock, flags); 306 spin_lock_irqsave(&ep->buffer_lock, flags);
299 if (ep->umidi->chip->shutdown) { 307 if (ep->umidi->disconnected) {
300 spin_unlock_irqrestore(&ep->buffer_lock, flags); 308 spin_unlock_irqrestore(&ep->buffer_lock, flags);
301 return; 309 return;
302 } 310 }
@@ -312,7 +320,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep)
312 320
313 dump_urb("sending", urb->transfer_buffer, 321 dump_urb("sending", urb->transfer_buffer,
314 urb->transfer_buffer_length); 322 urb->transfer_buffer_length);
315 urb->dev = ep->umidi->chip->dev; 323 urb->dev = ep->umidi->dev;
316 if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0) 324 if (snd_usbmidi_submit_urb(urb, GFP_ATOMIC) < 0)
317 break; 325 break;
318 ep->active_urbs |= 1 << urb_index; 326 ep->active_urbs |= 1 << urb_index;
@@ -349,7 +357,7 @@ static void snd_usbmidi_error_timer(unsigned long data)
349 if (in && in->error_resubmit) { 357 if (in && in->error_resubmit) {
350 in->error_resubmit = 0; 358 in->error_resubmit = 0;
351 for (j = 0; j < INPUT_URBS; ++j) { 359 for (j = 0; j < INPUT_URBS; ++j) {
352 in->urbs[j]->dev = umidi->chip->dev; 360 in->urbs[j]->dev = umidi->dev;
353 snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC); 361 snd_usbmidi_submit_urb(in->urbs[j], GFP_ATOMIC);
354 } 362 }
355 } 363 }
@@ -369,7 +377,7 @@ static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep,
369 return -ENOMEM; 377 return -ENOMEM;
370 dump_urb("sending", buf, len); 378 dump_urb("sending", buf, len);
371 if (ep->urbs[0].urb) 379 if (ep->urbs[0].urb)
372 err = usb_bulk_msg(ep->umidi->chip->dev, ep->urbs[0].urb->pipe, 380 err = usb_bulk_msg(ep->umidi->dev, ep->urbs[0].urb->pipe,
373 buf, len, NULL, 250); 381 buf, len, NULL, 250);
374 kfree(buf); 382 kfree(buf);
375 return err; 383 return err;
@@ -724,8 +732,7 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
724 732
725 if (!ep->ports[0].active) 733 if (!ep->ports[0].active)
726 return; 734 return;
727 count = snd_usb_get_speed(ep->umidi->chip->dev) == USB_SPEED_HIGH 735 count = snd_usb_get_speed(ep->umidi->dev) == USB_SPEED_HIGH ? 1 : 2;
728 ? 1 : 2;
729 count = snd_rawmidi_transmit(ep->ports[0].substream, 736 count = snd_rawmidi_transmit(ep->ports[0].substream,
730 urb->transfer_buffer, 737 urb->transfer_buffer,
731 count); 738 count);
@@ -879,6 +886,50 @@ static struct usb_protocol_ops snd_usbmidi_emagic_ops = {
879}; 886};
880 887
881 888
889static void update_roland_altsetting(struct snd_usb_midi* umidi)
890{
891 struct usb_interface *intf;
892 struct usb_host_interface *hostif;
893 struct usb_interface_descriptor *intfd;
894 int is_light_load;
895
896 intf = umidi->iface;
897 is_light_load = intf->cur_altsetting != intf->altsetting;
898 if (umidi->roland_load_ctl->private_value == is_light_load)
899 return;
900 hostif = &intf->altsetting[umidi->roland_load_ctl->private_value];
901 intfd = get_iface_desc(hostif);
902 snd_usbmidi_input_stop(&umidi->list);
903 usb_set_interface(umidi->dev, intfd->bInterfaceNumber,
904 intfd->bAlternateSetting);
905 snd_usbmidi_input_start(&umidi->list);
906}
907
908static void substream_open(struct snd_rawmidi_substream *substream, int open)
909{
910 struct snd_usb_midi* umidi = substream->rmidi->private_data;
911 struct snd_kcontrol *ctl;
912
913 mutex_lock(&umidi->mutex);
914 if (open) {
915 if (umidi->opened++ == 0 && umidi->roland_load_ctl) {
916 ctl = umidi->roland_load_ctl;
917 ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
918 snd_ctl_notify(umidi->card,
919 SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
920 update_roland_altsetting(umidi);
921 }
922 } else {
923 if (--umidi->opened == 0 && umidi->roland_load_ctl) {
924 ctl = umidi->roland_load_ctl;
925 ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
926 snd_ctl_notify(umidi->card,
927 SNDRV_CTL_EVENT_MASK_INFO, &ctl->id);
928 }
929 }
930 mutex_unlock(&umidi->mutex);
931}
932
882static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream) 933static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
883{ 934{
884 struct snd_usb_midi* umidi = substream->rmidi->private_data; 935 struct snd_usb_midi* umidi = substream->rmidi->private_data;
@@ -898,11 +949,13 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
898 } 949 }
899 substream->runtime->private_data = port; 950 substream->runtime->private_data = port;
900 port->state = STATE_UNKNOWN; 951 port->state = STATE_UNKNOWN;
952 substream_open(substream, 1);
901 return 0; 953 return 0;
902} 954}
903 955
904static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream) 956static int snd_usbmidi_output_close(struct snd_rawmidi_substream *substream)
905{ 957{
958 substream_open(substream, 0);
906 return 0; 959 return 0;
907} 960}
908 961
@@ -912,7 +965,7 @@ static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream,
912 965
913 port->active = up; 966 port->active = up;
914 if (up) { 967 if (up) {
915 if (port->ep->umidi->chip->shutdown) { 968 if (port->ep->umidi->disconnected) {
916 /* gobble up remaining bytes to prevent wait in 969 /* gobble up remaining bytes to prevent wait in
917 * snd_rawmidi_drain_output */ 970 * snd_rawmidi_drain_output */
918 while (!snd_rawmidi_transmit_empty(substream)) 971 while (!snd_rawmidi_transmit_empty(substream))
@@ -954,11 +1007,13 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
954 1007
955static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream) 1008static int snd_usbmidi_input_open(struct snd_rawmidi_substream *substream)
956{ 1009{
1010 substream_open(substream, 1);
957 return 0; 1011 return 0;
958} 1012}
959 1013
960static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream) 1014static int snd_usbmidi_input_close(struct snd_rawmidi_substream *substream)
961{ 1015{
1016 substream_open(substream, 0);
962 return 0; 1017 return 0;
963} 1018}
964 1019
@@ -988,7 +1043,7 @@ static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
988static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb, 1043static void free_urb_and_buffer(struct snd_usb_midi *umidi, struct urb *urb,
989 unsigned int buffer_length) 1044 unsigned int buffer_length)
990{ 1045{
991 usb_buffer_free(umidi->chip->dev, buffer_length, 1046 usb_buffer_free(umidi->dev, buffer_length,
992 urb->transfer_buffer, urb->transfer_dma); 1047 urb->transfer_buffer, urb->transfer_dma);
993 usb_free_urb(urb); 1048 usb_free_urb(urb);
994} 1049}
@@ -1035,24 +1090,24 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
1035 } 1090 }
1036 } 1091 }
1037 if (ep_info->in_interval) 1092 if (ep_info->in_interval)
1038 pipe = usb_rcvintpipe(umidi->chip->dev, ep_info->in_ep); 1093 pipe = usb_rcvintpipe(umidi->dev, ep_info->in_ep);
1039 else 1094 else
1040 pipe = usb_rcvbulkpipe(umidi->chip->dev, ep_info->in_ep); 1095 pipe = usb_rcvbulkpipe(umidi->dev, ep_info->in_ep);
1041 length = usb_maxpacket(umidi->chip->dev, pipe, 0); 1096 length = usb_maxpacket(umidi->dev, pipe, 0);
1042 for (i = 0; i < INPUT_URBS; ++i) { 1097 for (i = 0; i < INPUT_URBS; ++i) {
1043 buffer = usb_buffer_alloc(umidi->chip->dev, length, GFP_KERNEL, 1098 buffer = usb_buffer_alloc(umidi->dev, length, GFP_KERNEL,
1044 &ep->urbs[i]->transfer_dma); 1099 &ep->urbs[i]->transfer_dma);
1045 if (!buffer) { 1100 if (!buffer) {
1046 snd_usbmidi_in_endpoint_delete(ep); 1101 snd_usbmidi_in_endpoint_delete(ep);
1047 return -ENOMEM; 1102 return -ENOMEM;
1048 } 1103 }
1049 if (ep_info->in_interval) 1104 if (ep_info->in_interval)
1050 usb_fill_int_urb(ep->urbs[i], umidi->chip->dev, 1105 usb_fill_int_urb(ep->urbs[i], umidi->dev,
1051 pipe, buffer, length, 1106 pipe, buffer, length,
1052 snd_usbmidi_in_urb_complete, 1107 snd_usbmidi_in_urb_complete,
1053 ep, ep_info->in_interval); 1108 ep, ep_info->in_interval);
1054 else 1109 else
1055 usb_fill_bulk_urb(ep->urbs[i], umidi->chip->dev, 1110 usb_fill_bulk_urb(ep->urbs[i], umidi->dev,
1056 pipe, buffer, length, 1111 pipe, buffer, length,
1057 snd_usbmidi_in_urb_complete, ep); 1112 snd_usbmidi_in_urb_complete, ep);
1058 ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP; 1113 ep->urbs[i]->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
@@ -1062,15 +1117,6 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
1062 return 0; 1117 return 0;
1063} 1118}
1064 1119
1065static unsigned int snd_usbmidi_count_bits(unsigned int x)
1066{
1067 unsigned int bits;
1068
1069 for (bits = 0; x; ++bits)
1070 x &= x - 1;
1071 return bits;
1072}
1073
1074/* 1120/*
1075 * Frees an output endpoint. 1121 * Frees an output endpoint.
1076 * May be called when ep hasn't been initialized completely. 1122 * May be called when ep hasn't been initialized completely.
@@ -1113,15 +1159,15 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1113 ep->urbs[i].ep = ep; 1159 ep->urbs[i].ep = ep;
1114 } 1160 }
1115 if (ep_info->out_interval) 1161 if (ep_info->out_interval)
1116 pipe = usb_sndintpipe(umidi->chip->dev, ep_info->out_ep); 1162 pipe = usb_sndintpipe(umidi->dev, ep_info->out_ep);
1117 else 1163 else
1118 pipe = usb_sndbulkpipe(umidi->chip->dev, ep_info->out_ep); 1164 pipe = usb_sndbulkpipe(umidi->dev, ep_info->out_ep);
1119 if (umidi->chip->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */ 1165 if (umidi->usb_id == USB_ID(0x0a92, 0x1020)) /* ESI M4U */
1120 ep->max_transfer = 4; 1166 ep->max_transfer = 4;
1121 else 1167 else
1122 ep->max_transfer = usb_maxpacket(umidi->chip->dev, pipe, 1); 1168 ep->max_transfer = usb_maxpacket(umidi->dev, pipe, 1);
1123 for (i = 0; i < OUTPUT_URBS; ++i) { 1169 for (i = 0; i < OUTPUT_URBS; ++i) {
1124 buffer = usb_buffer_alloc(umidi->chip->dev, 1170 buffer = usb_buffer_alloc(umidi->dev,
1125 ep->max_transfer, GFP_KERNEL, 1171 ep->max_transfer, GFP_KERNEL,
1126 &ep->urbs[i].urb->transfer_dma); 1172 &ep->urbs[i].urb->transfer_dma);
1127 if (!buffer) { 1173 if (!buffer) {
@@ -1129,12 +1175,12 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1129 return -ENOMEM; 1175 return -ENOMEM;
1130 } 1176 }
1131 if (ep_info->out_interval) 1177 if (ep_info->out_interval)
1132 usb_fill_int_urb(ep->urbs[i].urb, umidi->chip->dev, 1178 usb_fill_int_urb(ep->urbs[i].urb, umidi->dev,
1133 pipe, buffer, ep->max_transfer, 1179 pipe, buffer, ep->max_transfer,
1134 snd_usbmidi_out_urb_complete, 1180 snd_usbmidi_out_urb_complete,
1135 &ep->urbs[i], ep_info->out_interval); 1181 &ep->urbs[i], ep_info->out_interval);
1136 else 1182 else
1137 usb_fill_bulk_urb(ep->urbs[i].urb, umidi->chip->dev, 1183 usb_fill_bulk_urb(ep->urbs[i].urb, umidi->dev,
1138 pipe, buffer, ep->max_transfer, 1184 pipe, buffer, ep->max_transfer,
1139 snd_usbmidi_out_urb_complete, 1185 snd_usbmidi_out_urb_complete,
1140 &ep->urbs[i]); 1186 &ep->urbs[i]);
@@ -1172,6 +1218,7 @@ static void snd_usbmidi_free(struct snd_usb_midi* umidi)
1172 if (ep->in) 1218 if (ep->in)
1173 snd_usbmidi_in_endpoint_delete(ep->in); 1219 snd_usbmidi_in_endpoint_delete(ep->in);
1174 } 1220 }
1221 mutex_destroy(&umidi->mutex);
1175 kfree(umidi); 1222 kfree(umidi);
1176} 1223}
1177 1224
@@ -1367,7 +1414,7 @@ static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
1367 int i; 1414 int i;
1368 1415
1369 for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) { 1416 for (i = 0; i < ARRAY_SIZE(snd_usbmidi_port_info); ++i) {
1370 if (snd_usbmidi_port_info[i].id == umidi->chip->usb_id && 1417 if (snd_usbmidi_port_info[i].id == umidi->usb_id &&
1371 snd_usbmidi_port_info[i].port == number) 1418 snd_usbmidi_port_info[i].port == number)
1372 return &snd_usbmidi_port_info[i]; 1419 return &snd_usbmidi_port_info[i];
1373 } 1420 }
@@ -1405,7 +1452,7 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,
1405 port_info = find_port_info(umidi, number); 1452 port_info = find_port_info(umidi, number);
1406 name_format = port_info ? port_info->name : "%s MIDI %d"; 1453 name_format = port_info ? port_info->name : "%s MIDI %d";
1407 snprintf(substream->name, sizeof(substream->name), 1454 snprintf(substream->name, sizeof(substream->name),
1408 name_format, umidi->chip->card->shortname, number + 1); 1455 name_format, umidi->card->shortname, number + 1);
1409 1456
1410 *rsubstream = substream; 1457 *rsubstream = substream;
1411} 1458}
@@ -1503,7 +1550,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1503 endpoints[epidx].out_ep = usb_endpoint_num(ep); 1550 endpoints[epidx].out_ep = usb_endpoint_num(ep);
1504 if (usb_endpoint_xfer_int(ep)) 1551 if (usb_endpoint_xfer_int(ep))
1505 endpoints[epidx].out_interval = ep->bInterval; 1552 endpoints[epidx].out_interval = ep->bInterval;
1506 else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW) 1553 else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW)
1507 /* 1554 /*
1508 * Low speed bulk transfers don't exist, so 1555 * Low speed bulk transfers don't exist, so
1509 * force interrupt transfers for devices like 1556 * force interrupt transfers for devices like
@@ -1523,7 +1570,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1523 endpoints[epidx].in_ep = usb_endpoint_num(ep); 1570 endpoints[epidx].in_ep = usb_endpoint_num(ep);
1524 if (usb_endpoint_xfer_int(ep)) 1571 if (usb_endpoint_xfer_int(ep))
1525 endpoints[epidx].in_interval = ep->bInterval; 1572 endpoints[epidx].in_interval = ep->bInterval;
1526 else if (snd_usb_get_speed(umidi->chip->dev) == USB_SPEED_LOW) 1573 else if (snd_usb_get_speed(umidi->dev) == USB_SPEED_LOW)
1527 endpoints[epidx].in_interval = 1; 1574 endpoints[epidx].in_interval = 1;
1528 endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1; 1575 endpoints[epidx].in_cables = (1 << ms_ep->bNumEmbMIDIJack) - 1;
1529 snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n", 1576 snd_printdd(KERN_INFO "EP %02X: %d jack(s)\n",
@@ -1533,6 +1580,52 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
1533 return 0; 1580 return 0;
1534} 1581}
1535 1582
1583static int roland_load_info(struct snd_kcontrol *kcontrol,
1584 struct snd_ctl_elem_info *info)
1585{
1586 static const char *const names[] = { "High Load", "Light Load" };
1587
1588 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1589 info->count = 1;
1590 info->value.enumerated.items = 2;
1591 if (info->value.enumerated.item > 1)
1592 info->value.enumerated.item = 1;
1593 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
1594 return 0;
1595}
1596
1597static int roland_load_get(struct snd_kcontrol *kcontrol,
1598 struct snd_ctl_elem_value *value)
1599{
1600 value->value.enumerated.item[0] = kcontrol->private_value;
1601 return 0;
1602}
1603
1604static int roland_load_put(struct snd_kcontrol *kcontrol,
1605 struct snd_ctl_elem_value *value)
1606{
1607 struct snd_usb_midi* umidi = kcontrol->private_data;
1608 int changed;
1609
1610 if (value->value.enumerated.item[0] > 1)
1611 return -EINVAL;
1612 mutex_lock(&umidi->mutex);
1613 changed = value->value.enumerated.item[0] != kcontrol->private_value;
1614 if (changed)
1615 kcontrol->private_value = value->value.enumerated.item[0];
1616 mutex_unlock(&umidi->mutex);
1617 return changed;
1618}
1619
1620static struct snd_kcontrol_new roland_load_ctl = {
1621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1622 .name = "MIDI Input Mode",
1623 .info = roland_load_info,
1624 .get = roland_load_get,
1625 .put = roland_load_put,
1626 .private_value = 1,
1627};
1628
1536/* 1629/*
1537 * On Roland devices, use the second alternate setting to be able to use 1630 * On Roland devices, use the second alternate setting to be able to use
1538 * the interrupt input endpoint. 1631 * the interrupt input endpoint.
@@ -1556,8 +1649,12 @@ static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi* umidi)
1556 1649
1557 snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n", 1650 snd_printdd(KERN_INFO "switching to altsetting %d with int ep\n",
1558 intfd->bAlternateSetting); 1651 intfd->bAlternateSetting);
1559 usb_set_interface(umidi->chip->dev, intfd->bInterfaceNumber, 1652 usb_set_interface(umidi->dev, intfd->bInterfaceNumber,
1560 intfd->bAlternateSetting); 1653 intfd->bAlternateSetting);
1654
1655 umidi->roland_load_ctl = snd_ctl_new1(&roland_load_ctl, umidi);
1656 if (snd_ctl_add(umidi->card, umidi->roland_load_ctl) < 0)
1657 umidi->roland_load_ctl = NULL;
1561} 1658}
1562 1659
1563/* 1660/*
@@ -1573,7 +1670,7 @@ static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi,
1573 struct usb_endpoint_descriptor* epd; 1670 struct usb_endpoint_descriptor* epd;
1574 int i, out_eps = 0, in_eps = 0; 1671 int i, out_eps = 0, in_eps = 0;
1575 1672
1576 if (USB_ID_VENDOR(umidi->chip->usb_id) == 0x0582) 1673 if (USB_ID_VENDOR(umidi->usb_id) == 0x0582)
1577 snd_usbmidi_switch_roland_altsetting(umidi); 1674 snd_usbmidi_switch_roland_altsetting(umidi);
1578 1675
1579 if (endpoint[0].out_ep || endpoint[0].in_ep) 1676 if (endpoint[0].out_ep || endpoint[0].in_ep)
@@ -1760,12 +1857,12 @@ static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi,
1760 struct snd_rawmidi *rmidi; 1857 struct snd_rawmidi *rmidi;
1761 int err; 1858 int err;
1762 1859
1763 err = snd_rawmidi_new(umidi->chip->card, "USB MIDI", 1860 err = snd_rawmidi_new(umidi->card, "USB MIDI",
1764 umidi->chip->next_midi_device++, 1861 umidi->next_midi_device++,
1765 out_ports, in_ports, &rmidi); 1862 out_ports, in_ports, &rmidi);
1766 if (err < 0) 1863 if (err < 0)
1767 return err; 1864 return err;
1768 strcpy(rmidi->name, umidi->chip->card->shortname); 1865 strcpy(rmidi->name, umidi->card->shortname);
1769 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT | 1866 rmidi->info_flags = SNDRV_RAWMIDI_INFO_OUTPUT |
1770 SNDRV_RAWMIDI_INFO_INPUT | 1867 SNDRV_RAWMIDI_INFO_INPUT |
1771 SNDRV_RAWMIDI_INFO_DUPLEX; 1868 SNDRV_RAWMIDI_INFO_DUPLEX;
@@ -1804,7 +1901,7 @@ static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep)
1804 return; 1901 return;
1805 for (i = 0; i < INPUT_URBS; ++i) { 1902 for (i = 0; i < INPUT_URBS; ++i) {
1806 struct urb* urb = ep->urbs[i]; 1903 struct urb* urb = ep->urbs[i];
1807 urb->dev = ep->umidi->chip->dev; 1904 urb->dev = ep->umidi->dev;
1808 snd_usbmidi_submit_urb(urb, GFP_KERNEL); 1905 snd_usbmidi_submit_urb(urb, GFP_KERNEL);
1809 } 1906 }
1810} 1907}
@@ -1825,9 +1922,10 @@ void snd_usbmidi_input_start(struct list_head* p)
1825/* 1922/*
1826 * Creates and registers everything needed for a MIDI streaming interface. 1923 * Creates and registers everything needed for a MIDI streaming interface.
1827 */ 1924 */
1828int snd_usb_create_midi_interface(struct snd_usb_audio* chip, 1925int snd_usbmidi_create(struct snd_card *card,
1829 struct usb_interface* iface, 1926 struct usb_interface* iface,
1830 const struct snd_usb_audio_quirk* quirk) 1927 struct list_head *midi_list,
1928 const struct snd_usb_audio_quirk* quirk)
1831{ 1929{
1832 struct snd_usb_midi* umidi; 1930 struct snd_usb_midi* umidi;
1833 struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS]; 1931 struct snd_usb_midi_endpoint_info endpoints[MIDI_MAX_ENDPOINTS];
@@ -1837,12 +1935,16 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1837 umidi = kzalloc(sizeof(*umidi), GFP_KERNEL); 1935 umidi = kzalloc(sizeof(*umidi), GFP_KERNEL);
1838 if (!umidi) 1936 if (!umidi)
1839 return -ENOMEM; 1937 return -ENOMEM;
1840 umidi->chip = chip; 1938 umidi->dev = interface_to_usbdev(iface);
1939 umidi->card = card;
1841 umidi->iface = iface; 1940 umidi->iface = iface;
1842 umidi->quirk = quirk; 1941 umidi->quirk = quirk;
1843 umidi->usb_protocol_ops = &snd_usbmidi_standard_ops; 1942 umidi->usb_protocol_ops = &snd_usbmidi_standard_ops;
1844 init_timer(&umidi->error_timer); 1943 init_timer(&umidi->error_timer);
1845 spin_lock_init(&umidi->disc_lock); 1944 spin_lock_init(&umidi->disc_lock);
1945 mutex_init(&umidi->mutex);
1946 umidi->usb_id = USB_ID(le16_to_cpu(umidi->dev->descriptor.idVendor),
1947 le16_to_cpu(umidi->dev->descriptor.idProduct));
1846 umidi->error_timer.function = snd_usbmidi_error_timer; 1948 umidi->error_timer.function = snd_usbmidi_error_timer;
1847 umidi->error_timer.data = (unsigned long)umidi; 1949 umidi->error_timer.data = (unsigned long)umidi;
1848 1950
@@ -1851,7 +1953,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1851 switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) { 1953 switch (quirk ? quirk->type : QUIRK_MIDI_STANDARD_INTERFACE) {
1852 case QUIRK_MIDI_STANDARD_INTERFACE: 1954 case QUIRK_MIDI_STANDARD_INTERFACE:
1853 err = snd_usbmidi_get_ms_info(umidi, endpoints); 1955 err = snd_usbmidi_get_ms_info(umidi, endpoints);
1854 if (chip->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */ 1956 if (umidi->usb_id == USB_ID(0x0763, 0x0150)) /* M-Audio Uno */
1855 umidi->usb_protocol_ops = 1957 umidi->usb_protocol_ops =
1856 &snd_usbmidi_maudio_broken_running_status_ops; 1958 &snd_usbmidi_maudio_broken_running_status_ops;
1857 break; 1959 break;
@@ -1887,7 +1989,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1887 * interface 0, so we have to make sure that the USB core looks 1989 * interface 0, so we have to make sure that the USB core looks
1888 * again at interface 0 by calling usb_set_interface() on it. 1990 * again at interface 0 by calling usb_set_interface() on it.
1889 */ 1991 */
1890 usb_set_interface(umidi->chip->dev, 0, 0); 1992 usb_set_interface(umidi->dev, 0, 0);
1891 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints); 1993 err = snd_usbmidi_detect_per_port_endpoints(umidi, endpoints);
1892 break; 1994 break;
1893 case QUIRK_MIDI_EMAGIC: 1995 case QUIRK_MIDI_EMAGIC:
@@ -1914,8 +2016,8 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1914 out_ports = 0; 2016 out_ports = 0;
1915 in_ports = 0; 2017 in_ports = 0;
1916 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) { 2018 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) {
1917 out_ports += snd_usbmidi_count_bits(endpoints[i].out_cables); 2019 out_ports += hweight16(endpoints[i].out_cables);
1918 in_ports += snd_usbmidi_count_bits(endpoints[i].in_cables); 2020 in_ports += hweight16(endpoints[i].in_cables);
1919 } 2021 }
1920 err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports); 2022 err = snd_usbmidi_create_rawmidi(umidi, out_ports, in_ports);
1921 if (err < 0) { 2023 if (err < 0) {
@@ -1933,14 +2035,14 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
1933 return err; 2035 return err;
1934 } 2036 }
1935 2037
1936 list_add(&umidi->list, &umidi->chip->midi_list); 2038 list_add_tail(&umidi->list, midi_list);
1937 2039
1938 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i) 2040 for (i = 0; i < MIDI_MAX_ENDPOINTS; ++i)
1939 snd_usbmidi_input_start_ep(umidi->endpoints[i].in); 2041 snd_usbmidi_input_start_ep(umidi->endpoints[i].in);
1940 return 0; 2042 return 0;
1941} 2043}
1942 2044
1943EXPORT_SYMBOL(snd_usb_create_midi_interface); 2045EXPORT_SYMBOL(snd_usbmidi_create);
1944EXPORT_SYMBOL(snd_usbmidi_input_stop); 2046EXPORT_SYMBOL(snd_usbmidi_input_stop);
1945EXPORT_SYMBOL(snd_usbmidi_input_start); 2047EXPORT_SYMBOL(snd_usbmidi_input_start);
1946EXPORT_SYMBOL(snd_usbmidi_disconnect); 2048EXPORT_SYMBOL(snd_usbmidi_disconnect);
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 9efcfd08d747..c998220b99c6 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -1071,6 +1071,15 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, unsig
1071 channels = (ftr[0] - 7) / csize - 1; 1071 channels = (ftr[0] - 7) / csize - 1;
1072 1072
1073 master_bits = snd_usb_combine_bytes(ftr + 6, csize); 1073 master_bits = snd_usb_combine_bytes(ftr + 6, csize);
1074 /* master configuration quirks */
1075 switch (state->chip->usb_id) {
1076 case USB_ID(0x08bb, 0x2702):
1077 snd_printk(KERN_INFO
1078 "usbmixer: master volume quirk for PCM2702 chip\n");
1079 /* disable non-functional volume control */
1080 master_bits &= ~(1 << (USB_FEATURE_VOLUME - 1));
1081 break;
1082 }
1074 if (channels > 0) 1083 if (channels > 0)
1075 first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize); 1084 first_ch_bits = snd_usb_combine_bytes(ftr + 6 + csize, csize);
1076 else 1085 else
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c
index 3e5d66cf1f5a..77c35885e21c 100644
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/usbmixer_maps.c
@@ -277,6 +277,22 @@ static struct usbmix_name_map scratch_live_map[] = {
277 { 0 } /* terminator */ 277 { 0 } /* terminator */
278}; 278};
279 279
280/* "Gamesurround Muse Pocket LT" looks same like "Sound Blaster MP3+"
281 * most importand difference is SU[8], it should be set to "Capture Source"
282 * to make alsamixer and PA working properly.
283 * FIXME: or mp3plus_map should use "Capture Source" too,
284 * so this maps can be merget
285 */
286static struct usbmix_name_map hercules_usb51_map[] = {
287 { 8, "Capture Source" }, /* SU, default "PCM Capture Source" */
288 { 9, "Master Playback" }, /* FU, default "Speaker Playback" */
289 { 10, "Mic Boost", 7 }, /* FU, default "Auto Gain Input" */
290 { 11, "Line Capture" }, /* FU, default "PCM Capture" */
291 { 13, "Mic Bypass Playback" }, /* FU, default "Mic Playback" */
292 { 14, "Line Bypass Playback" }, /* FU, default "Line Playback" */
293 { 0 } /* terminator */
294};
295
280/* 296/*
281 * Control map entries 297 * Control map entries
282 */ 298 */
@@ -316,6 +332,13 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
316 .ignore_ctl_error = 1, 332 .ignore_ctl_error = 1,
317 }, 333 },
318 { 334 {
335 /* Hercules Gamesurround Muse Pocket LT
336 * (USB 5.1 Channel Audio Adapter)
337 */
338 .id = USB_ID(0x06f8, 0xc000),
339 .map = hercules_usb51_map,
340 },
341 {
319 .id = USB_ID(0x08bb, 0x2702), 342 .id = USB_ID(0x08bb, 0x2702),
320 .map = linex_map, 343 .map = linex_map,
321 .ignore_ctl_error = 1, 344 .ignore_ctl_error = 1,
diff --git a/sound/usb/usbquirks.h b/sound/usb/usbquirks.h
index f6f201eb24ce..a892bda03df9 100644
--- a/sound/usb/usbquirks.h
+++ b/sound/usb/usbquirks.h
@@ -1563,6 +1563,29 @@ YAMAHA_DEVICE(0x7010, "UB99"),
1563 } 1563 }
1564 } 1564 }
1565}, 1565},
1566{
1567 /* has ID 0x00ea when not in Advanced Driver mode */
1568 USB_DEVICE_VENDOR_SPEC(0x0582, 0x00e9),
1569 .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
1570 /* .vendor_name = "Roland", */
1571 /* .product_name = "UA-1G", */
1572 .ifnum = QUIRK_ANY_INTERFACE,
1573 .type = QUIRK_COMPOSITE,
1574 .data = (const struct snd_usb_audio_quirk[]) {
1575 {
1576 .ifnum = 0,
1577 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1578 },
1579 {
1580 .ifnum = 1,
1581 .type = QUIRK_AUDIO_STANDARD_INTERFACE
1582 },
1583 {
1584 .ifnum = -1
1585 }
1586 }
1587 }
1588},
1566 1589
1567/* Guillemot devices */ 1590/* Guillemot devices */
1568{ 1591{
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 00cd54c236b4..91bb29666d26 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -59,11 +59,11 @@ static int us122l_create_usbmidi(struct snd_card *card)
59 .type = QUIRK_MIDI_US122L, 59 .type = QUIRK_MIDI_US122L,
60 .data = &quirk_data 60 .data = &quirk_data
61 }; 61 };
62 struct usb_device *dev = US122L(card)->chip.dev; 62 struct usb_device *dev = US122L(card)->dev;
63 struct usb_interface *iface = usb_ifnum_to_if(dev, 1); 63 struct usb_interface *iface = usb_ifnum_to_if(dev, 1);
64 64
65 return snd_usb_create_midi_interface(&US122L(card)->chip, 65 return snd_usbmidi_create(card, iface,
66 iface, &quirk); 66 &US122L(card)->midi_list, &quirk);
67} 67}
68 68
69static int us144_create_usbmidi(struct snd_card *card) 69static int us144_create_usbmidi(struct snd_card *card)
@@ -81,11 +81,11 @@ static int us144_create_usbmidi(struct snd_card *card)
81 .type = QUIRK_MIDI_US122L, 81 .type = QUIRK_MIDI_US122L,
82 .data = &quirk_data 82 .data = &quirk_data
83 }; 83 };
84 struct usb_device *dev = US122L(card)->chip.dev; 84 struct usb_device *dev = US122L(card)->dev;
85 struct usb_interface *iface = usb_ifnum_to_if(dev, 0); 85 struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
86 86
87 return snd_usb_create_midi_interface(&US122L(card)->chip, 87 return snd_usbmidi_create(card, iface,
88 iface, &quirk); 88 &US122L(card)->midi_list, &quirk);
89} 89}
90 90
91/* 91/*
@@ -194,11 +194,12 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
194 if (!us122l->first) 194 if (!us122l->first)
195 us122l->first = file; 195 us122l->first = file;
196 196
197 if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) { 197 if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
198 iface = usb_ifnum_to_if(us122l->chip.dev, 0); 198 us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
199 iface = usb_ifnum_to_if(us122l->dev, 0);
199 usb_autopm_get_interface(iface); 200 usb_autopm_get_interface(iface);
200 } 201 }
201 iface = usb_ifnum_to_if(us122l->chip.dev, 1); 202 iface = usb_ifnum_to_if(us122l->dev, 1);
202 usb_autopm_get_interface(iface); 203 usb_autopm_get_interface(iface);
203 return 0; 204 return 0;
204} 205}
@@ -209,11 +210,12 @@ static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
209 struct usb_interface *iface; 210 struct usb_interface *iface;
210 snd_printdd(KERN_DEBUG "%p %p\n", hw, file); 211 snd_printdd(KERN_DEBUG "%p %p\n", hw, file);
211 212
212 if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) { 213 if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
213 iface = usb_ifnum_to_if(us122l->chip.dev, 0); 214 us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
215 iface = usb_ifnum_to_if(us122l->dev, 0);
214 usb_autopm_put_interface(iface); 216 usb_autopm_put_interface(iface);
215 } 217 }
216 iface = usb_ifnum_to_if(us122l->chip.dev, 1); 218 iface = usb_ifnum_to_if(us122l->dev, 1);
217 usb_autopm_put_interface(iface); 219 usb_autopm_put_interface(iface);
218 if (us122l->first == file) 220 if (us122l->first == file)
219 us122l->first = NULL; 221 us122l->first = NULL;
@@ -297,7 +299,7 @@ static unsigned int usb_stream_hwdep_poll(struct snd_hwdep *hw,
297static void us122l_stop(struct us122l *us122l) 299static void us122l_stop(struct us122l *us122l)
298{ 300{
299 struct list_head *p; 301 struct list_head *p;
300 list_for_each(p, &us122l->chip.midi_list) 302 list_for_each(p, &us122l->midi_list)
301 snd_usbmidi_input_stop(p); 303 snd_usbmidi_input_stop(p);
302 304
303 usb_stream_stop(&us122l->sk); 305 usb_stream_stop(&us122l->sk);
@@ -330,7 +332,7 @@ static bool us122l_start(struct us122l *us122l,
330 unsigned use_packsize = 0; 332 unsigned use_packsize = 0;
331 bool success = false; 333 bool success = false;
332 334
333 if (us122l->chip.dev->speed == USB_SPEED_HIGH) { 335 if (us122l->dev->speed == USB_SPEED_HIGH) {
334 /* The us-122l's descriptor defaults to iso max_packsize 78, 336 /* The us-122l's descriptor defaults to iso max_packsize 78,
335 which isn't needed for samplerates <= 48000. 337 which isn't needed for samplerates <= 48000.
336 Lets save some memory: 338 Lets save some memory:
@@ -347,11 +349,11 @@ static bool us122l_start(struct us122l *us122l,
347 break; 349 break;
348 } 350 }
349 } 351 }
350 if (!usb_stream_new(&us122l->sk, us122l->chip.dev, 1, 2, 352 if (!usb_stream_new(&us122l->sk, us122l->dev, 1, 2,
351 rate, use_packsize, period_frames, 6)) 353 rate, use_packsize, period_frames, 6))
352 goto out; 354 goto out;
353 355
354 err = us122l_set_sample_rate(us122l->chip.dev, rate); 356 err = us122l_set_sample_rate(us122l->dev, rate);
355 if (err < 0) { 357 if (err < 0) {
356 us122l_stop(us122l); 358 us122l_stop(us122l);
357 snd_printk(KERN_ERR "us122l_set_sample_rate error \n"); 359 snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
@@ -363,7 +365,7 @@ static bool us122l_start(struct us122l *us122l,
363 snd_printk(KERN_ERR "us122l_start error %i \n", err); 365 snd_printk(KERN_ERR "us122l_start error %i \n", err);
364 goto out; 366 goto out;
365 } 367 }
366 list_for_each(p, &us122l->chip.midi_list) 368 list_for_each(p, &us122l->midi_list)
367 snd_usbmidi_input_start(p); 369 snd_usbmidi_input_start(p);
368 success = true; 370 success = true;
369out: 371out:
@@ -390,7 +392,7 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
390 err = -ENXIO; 392 err = -ENXIO;
391 goto free; 393 goto free;
392 } 394 }
393 high_speed = us122l->chip.dev->speed == USB_SPEED_HIGH; 395 high_speed = us122l->dev->speed == USB_SPEED_HIGH;
394 if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000 && 396 if ((cfg->sample_rate != 44100 && cfg->sample_rate != 48000 &&
395 (!high_speed || 397 (!high_speed ||
396 (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) || 398 (cfg->sample_rate != 88200 && cfg->sample_rate != 96000))) ||
@@ -450,7 +452,7 @@ static int usb_stream_hwdep_new(struct snd_card *card)
450{ 452{
451 int err; 453 int err;
452 struct snd_hwdep *hw; 454 struct snd_hwdep *hw;
453 struct usb_device *dev = US122L(card)->chip.dev; 455 struct usb_device *dev = US122L(card)->dev;
454 456
455 err = snd_hwdep_new(card, SND_USB_STREAM_ID, 0, &hw); 457 err = snd_hwdep_new(card, SND_USB_STREAM_ID, 0, &hw);
456 if (err < 0) 458 if (err < 0)
@@ -476,26 +478,28 @@ static bool us122l_create_card(struct snd_card *card)
476 int err; 478 int err;
477 struct us122l *us122l = US122L(card); 479 struct us122l *us122l = US122L(card);
478 480
479 if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) { 481 if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
480 err = usb_set_interface(us122l->chip.dev, 0, 1); 482 us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
483 err = usb_set_interface(us122l->dev, 0, 1);
481 if (err) { 484 if (err) {
482 snd_printk(KERN_ERR "usb_set_interface error \n"); 485 snd_printk(KERN_ERR "usb_set_interface error \n");
483 return false; 486 return false;
484 } 487 }
485 } 488 }
486 err = usb_set_interface(us122l->chip.dev, 1, 1); 489 err = usb_set_interface(us122l->dev, 1, 1);
487 if (err) { 490 if (err) {
488 snd_printk(KERN_ERR "usb_set_interface error \n"); 491 snd_printk(KERN_ERR "usb_set_interface error \n");
489 return false; 492 return false;
490 } 493 }
491 494
492 pt_info_set(us122l->chip.dev, 0x11); 495 pt_info_set(us122l->dev, 0x11);
493 pt_info_set(us122l->chip.dev, 0x10); 496 pt_info_set(us122l->dev, 0x10);
494 497
495 if (!us122l_start(us122l, 44100, 256)) 498 if (!us122l_start(us122l, 44100, 256))
496 return false; 499 return false;
497 500
498 if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) 501 if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
502 us122l->dev->descriptor.idProduct == USB_ID_US144MKII)
499 err = us144_create_usbmidi(card); 503 err = us144_create_usbmidi(card);
500 else 504 else
501 err = us122l_create_usbmidi(card); 505 err = us122l_create_usbmidi(card);
@@ -508,7 +512,7 @@ static bool us122l_create_card(struct snd_card *card)
508 if (err < 0) { 512 if (err < 0) {
509/* release the midi resources */ 513/* release the midi resources */
510 struct list_head *p; 514 struct list_head *p;
511 list_for_each(p, &us122l->chip.midi_list) 515 list_for_each(p, &us122l->midi_list)
512 snd_usbmidi_disconnect(p); 516 snd_usbmidi_disconnect(p);
513 517
514 us122l_stop(us122l); 518 us122l_stop(us122l);
@@ -520,7 +524,7 @@ static bool us122l_create_card(struct snd_card *card)
520static void snd_us122l_free(struct snd_card *card) 524static void snd_us122l_free(struct snd_card *card)
521{ 525{
522 struct us122l *us122l = US122L(card); 526 struct us122l *us122l = US122L(card);
523 int index = us122l->chip.index; 527 int index = us122l->card_index;
524 if (index >= 0 && index < SNDRV_CARDS) 528 if (index >= 0 && index < SNDRV_CARDS)
525 snd_us122l_card_used[index] = 0; 529 snd_us122l_card_used[index] = 0;
526} 530}
@@ -540,13 +544,12 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
540 sizeof(struct us122l), &card); 544 sizeof(struct us122l), &card);
541 if (err < 0) 545 if (err < 0)
542 return err; 546 return err;
543 snd_us122l_card_used[US122L(card)->chip.index = dev] = 1; 547 snd_us122l_card_used[US122L(card)->card_index = dev] = 1;
544 card->private_free = snd_us122l_free; 548 card->private_free = snd_us122l_free;
545 US122L(card)->chip.dev = device; 549 US122L(card)->dev = device;
546 US122L(card)->chip.card = card;
547 mutex_init(&US122L(card)->mutex); 550 mutex_init(&US122L(card)->mutex);
548 init_waitqueue_head(&US122L(card)->sk.sleep); 551 init_waitqueue_head(&US122L(card)->sk.sleep);
549 INIT_LIST_HEAD(&US122L(card)->chip.midi_list); 552 INIT_LIST_HEAD(&US122L(card)->midi_list);
550 strcpy(card->driver, "USB "NAME_ALLCAPS""); 553 strcpy(card->driver, "USB "NAME_ALLCAPS"");
551 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); 554 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
552 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", 555 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
@@ -554,8 +557,8 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
554 le16_to_cpu(device->descriptor.idVendor), 557 le16_to_cpu(device->descriptor.idVendor),
555 le16_to_cpu(device->descriptor.idProduct), 558 le16_to_cpu(device->descriptor.idProduct),
556 0, 559 0,
557 US122L(card)->chip.dev->bus->busnum, 560 US122L(card)->dev->bus->busnum,
558 US122L(card)->chip.dev->devnum 561 US122L(card)->dev->devnum
559 ); 562 );
560 *cardp = card; 563 *cardp = card;
561 return 0; 564 return 0;
@@ -598,7 +601,8 @@ static int snd_us122l_probe(struct usb_interface *intf,
598 struct snd_card *card; 601 struct snd_card *card;
599 int err; 602 int err;
600 603
601 if (device->descriptor.idProduct == USB_ID_US144 604 if ((device->descriptor.idProduct == USB_ID_US144 ||
605 device->descriptor.idProduct == USB_ID_US144MKII)
602 && device->speed == USB_SPEED_HIGH) { 606 && device->speed == USB_SPEED_HIGH) {
603 snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n"); 607 snd_printk(KERN_ERR "disable ehci-hcd to run US-144 \n");
604 return -ENODEV; 608 return -ENODEV;
@@ -635,16 +639,15 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
635 mutex_lock(&us122l->mutex); 639 mutex_lock(&us122l->mutex);
636 us122l_stop(us122l); 640 us122l_stop(us122l);
637 mutex_unlock(&us122l->mutex); 641 mutex_unlock(&us122l->mutex);
638 us122l->chip.shutdown = 1;
639 642
640/* release the midi resources */ 643/* release the midi resources */
641 list_for_each(p, &us122l->chip.midi_list) { 644 list_for_each(p, &us122l->midi_list) {
642 snd_usbmidi_disconnect(p); 645 snd_usbmidi_disconnect(p);
643 } 646 }
644 647
645 usb_put_intf(usb_ifnum_to_if(us122l->chip.dev, 0)); 648 usb_put_intf(usb_ifnum_to_if(us122l->dev, 0));
646 usb_put_intf(usb_ifnum_to_if(us122l->chip.dev, 1)); 649 usb_put_intf(usb_ifnum_to_if(us122l->dev, 1));
647 usb_put_dev(us122l->chip.dev); 650 usb_put_dev(us122l->dev);
648 651
649 while (atomic_read(&us122l->mmap_count)) 652 while (atomic_read(&us122l->mmap_count))
650 msleep(500); 653 msleep(500);
@@ -667,7 +670,7 @@ static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message)
667 if (!us122l) 670 if (!us122l)
668 return 0; 671 return 0;
669 672
670 list_for_each(p, &us122l->chip.midi_list) 673 list_for_each(p, &us122l->midi_list)
671 snd_usbmidi_input_stop(p); 674 snd_usbmidi_input_stop(p);
672 675
673 mutex_lock(&us122l->mutex); 676 mutex_lock(&us122l->mutex);
@@ -694,23 +697,24 @@ static int snd_us122l_resume(struct usb_interface *intf)
694 697
695 mutex_lock(&us122l->mutex); 698 mutex_lock(&us122l->mutex);
696 /* needed, doesn't restart without: */ 699 /* needed, doesn't restart without: */
697 if (us122l->chip.dev->descriptor.idProduct == USB_ID_US144) { 700 if (us122l->dev->descriptor.idProduct == USB_ID_US144 ||
698 err = usb_set_interface(us122l->chip.dev, 0, 1); 701 us122l->dev->descriptor.idProduct == USB_ID_US144MKII) {
702 err = usb_set_interface(us122l->dev, 0, 1);
699 if (err) { 703 if (err) {
700 snd_printk(KERN_ERR "usb_set_interface error \n"); 704 snd_printk(KERN_ERR "usb_set_interface error \n");
701 goto unlock; 705 goto unlock;
702 } 706 }
703 } 707 }
704 err = usb_set_interface(us122l->chip.dev, 1, 1); 708 err = usb_set_interface(us122l->dev, 1, 1);
705 if (err) { 709 if (err) {
706 snd_printk(KERN_ERR "usb_set_interface error \n"); 710 snd_printk(KERN_ERR "usb_set_interface error \n");
707 goto unlock; 711 goto unlock;
708 } 712 }
709 713
710 pt_info_set(us122l->chip.dev, 0x11); 714 pt_info_set(us122l->dev, 0x11);
711 pt_info_set(us122l->chip.dev, 0x10); 715 pt_info_set(us122l->dev, 0x10);
712 716
713 err = us122l_set_sample_rate(us122l->chip.dev, 717 err = us122l_set_sample_rate(us122l->dev,
714 us122l->sk.s->cfg.sample_rate); 718 us122l->sk.s->cfg.sample_rate);
715 if (err < 0) { 719 if (err < 0) {
716 snd_printk(KERN_ERR "us122l_set_sample_rate error \n"); 720 snd_printk(KERN_ERR "us122l_set_sample_rate error \n");
@@ -720,7 +724,7 @@ static int snd_us122l_resume(struct usb_interface *intf)
720 if (err) 724 if (err)
721 goto unlock; 725 goto unlock;
722 726
723 list_for_each(p, &us122l->chip.midi_list) 727 list_for_each(p, &us122l->midi_list)
724 snd_usbmidi_input_start(p); 728 snd_usbmidi_input_start(p);
725unlock: 729unlock:
726 mutex_unlock(&us122l->mutex); 730 mutex_unlock(&us122l->mutex);
@@ -739,6 +743,16 @@ static struct usb_device_id snd_us122l_usb_id_table[] = {
739 .idVendor = 0x0644, 743 .idVendor = 0x0644,
740 .idProduct = USB_ID_US144 744 .idProduct = USB_ID_US144
741 }, 745 },
746 {
747 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
748 .idVendor = 0x0644,
749 .idProduct = USB_ID_US122MKII
750 },
751 {
752 .match_flags = USB_DEVICE_ID_MATCH_DEVICE,
753 .idVendor = 0x0644,
754 .idProduct = USB_ID_US144MKII
755 },
742 { /* terminator */ } 756 { /* terminator */ }
743}; 757};
744 758
diff --git a/sound/usb/usx2y/us122l.h b/sound/usb/usx2y/us122l.h
index 3d10c4b2a0f5..f263b3f96c86 100644
--- a/sound/usb/usx2y/us122l.h
+++ b/sound/usb/usx2y/us122l.h
@@ -3,7 +3,8 @@
3 3
4 4
5struct us122l { 5struct us122l {
6 struct snd_usb_audio chip; 6 struct usb_device *dev;
7 int card_index;
7 int stride; 8 int stride;
8 struct usb_stream_kernel sk; 9 struct usb_stream_kernel sk;
9 10
@@ -12,6 +13,7 @@ struct us122l {
12 unsigned second_periods_polled; 13 unsigned second_periods_polled;
13 struct file *master; 14 struct file *master;
14 struct file *slave; 15 struct file *slave;
16 struct list_head midi_list;
15 17
16 atomic_t mmap_count; 18 atomic_t mmap_count;
17}; 19};
@@ -23,5 +25,7 @@ struct us122l {
23 25
24#define USB_ID_US122L 0x800E 26#define USB_ID_US122L 0x800E
25#define USB_ID_US144 0x800F 27#define USB_ID_US144 0x800F
28#define USB_ID_US122MKII 0x8021
29#define USB_ID_US144MKII 0x8020
26 30
27#endif 31#endif
diff --git a/sound/usb/usx2y/usX2Yhwdep.c b/sound/usb/usx2y/usX2Yhwdep.c
index 52e04b2f35d3..1879b72c40f8 100644
--- a/sound/usb/usx2y/usX2Yhwdep.c
+++ b/sound/usb/usx2y/usX2Yhwdep.c
@@ -114,7 +114,7 @@ static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
114 struct usX2Ydev *us428 = hw->private_data; 114 struct usX2Ydev *us428 = hw->private_data;
115 int id = -1; 115 int id = -1;
116 116
117 switch (le16_to_cpu(us428->chip.dev->descriptor.idProduct)) { 117 switch (le16_to_cpu(us428->dev->descriptor.idProduct)) {
118 case USB_ID_US122: 118 case USB_ID_US122:
119 id = USX2Y_TYPE_122; 119 id = USX2Y_TYPE_122;
120 break; 120 break;
@@ -164,14 +164,14 @@ static int usX2Y_create_usbmidi(struct snd_card *card)
164 .type = QUIRK_MIDI_FIXED_ENDPOINT, 164 .type = QUIRK_MIDI_FIXED_ENDPOINT,
165 .data = &quirk_data_2 165 .data = &quirk_data_2
166 }; 166 };
167 struct usb_device *dev = usX2Y(card)->chip.dev; 167 struct usb_device *dev = usX2Y(card)->dev;
168 struct usb_interface *iface = usb_ifnum_to_if(dev, 0); 168 struct usb_interface *iface = usb_ifnum_to_if(dev, 0);
169 struct snd_usb_audio_quirk *quirk = 169 struct snd_usb_audio_quirk *quirk =
170 le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ? 170 le16_to_cpu(dev->descriptor.idProduct) == USB_ID_US428 ?
171 &quirk_2 : &quirk_1; 171 &quirk_2 : &quirk_1;
172 172
173 snd_printdd("usX2Y_create_usbmidi \n"); 173 snd_printdd("usX2Y_create_usbmidi \n");
174 return snd_usb_create_midi_interface(&usX2Y(card)->chip, iface, quirk); 174 return snd_usbmidi_create(card, iface, &usX2Y(card)->midi_list, quirk);
175} 175}
176 176
177static int usX2Y_create_alsa_devices(struct snd_card *card) 177static int usX2Y_create_alsa_devices(struct snd_card *card)
@@ -202,7 +202,7 @@ static int snd_usX2Y_hwdep_dsp_load(struct snd_hwdep *hw,
202 snd_printdd( "dsp_load %s\n", dsp->name); 202 snd_printdd( "dsp_load %s\n", dsp->name);
203 203
204 if (access_ok(VERIFY_READ, dsp->image, dsp->length)) { 204 if (access_ok(VERIFY_READ, dsp->image, dsp->length)) {
205 struct usb_device* dev = priv->chip.dev; 205 struct usb_device* dev = priv->dev;
206 char *buf; 206 char *buf;
207 207
208 buf = memdup_user(dsp->image, dsp->length); 208 buf = memdup_user(dsp->image, dsp->length);
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index cb4bb8373ca2..c42350eed2eb 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -239,8 +239,8 @@ static void i_usX2Y_In04Int(struct urb *urb)
239 for (j = 0; j < URBS_AsyncSeq && !err; ++j) 239 for (j = 0; j < URBS_AsyncSeq && !err; ++j)
240 if (0 == usX2Y->AS04.urb[j]->status) { 240 if (0 == usX2Y->AS04.urb[j]->status) {
241 struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost. 241 struct us428_p4out *p4out = us428ctls->p4out + send; // FIXME if more than 1 p4out is new, 1 gets lost.
242 usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->chip.dev, 242 usb_fill_bulk_urb(usX2Y->AS04.urb[j], usX2Y->dev,
243 usb_sndbulkpipe(usX2Y->chip.dev, 0x04), &p4out->val.vol, 243 usb_sndbulkpipe(usX2Y->dev, 0x04), &p4out->val.vol,
244 p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5, 244 p4out->type == eLT_Light ? sizeof(struct us428_lights) : 5,
245 i_usX2Y_Out04Int, usX2Y); 245 i_usX2Y_Out04Int, usX2Y);
246 err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC); 246 err = usb_submit_urb(usX2Y->AS04.urb[j], GFP_ATOMIC);
@@ -253,7 +253,7 @@ static void i_usX2Y_In04Int(struct urb *urb)
253 if (err) 253 if (err)
254 snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err); 254 snd_printk(KERN_ERR "In04Int() usb_submit_urb err=%i\n", err);
255 255
256 urb->dev = usX2Y->chip.dev; 256 urb->dev = usX2Y->dev;
257 usb_submit_urb(urb, GFP_ATOMIC); 257 usb_submit_urb(urb, GFP_ATOMIC);
258} 258}
259 259
@@ -273,8 +273,8 @@ int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y)
273 err = -ENOMEM; 273 err = -ENOMEM;
274 break; 274 break;
275 } 275 }
276 usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->chip.dev, 276 usb_fill_bulk_urb( usX2Y->AS04.urb[i], usX2Y->dev,
277 usb_sndbulkpipe(usX2Y->chip.dev, 0x04), 277 usb_sndbulkpipe(usX2Y->dev, 0x04),
278 usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0, 278 usX2Y->AS04.buffer + URB_DataLen_AsyncSeq*i, 0,
279 i_usX2Y_Out04Int, usX2Y 279 i_usX2Y_Out04Int, usX2Y
280 ); 280 );
@@ -293,7 +293,7 @@ int usX2Y_In04_init(struct usX2Ydev *usX2Y)
293 } 293 }
294 294
295 init_waitqueue_head(&usX2Y->In04WaitQueue); 295 init_waitqueue_head(&usX2Y->In04WaitQueue);
296 usb_fill_int_urb(usX2Y->In04urb, usX2Y->chip.dev, usb_rcvintpipe(usX2Y->chip.dev, 0x4), 296 usb_fill_int_urb(usX2Y->In04urb, usX2Y->dev, usb_rcvintpipe(usX2Y->dev, 0x4),
297 usX2Y->In04Buf, 21, 297 usX2Y->In04Buf, 21,
298 i_usX2Y_In04Int, usX2Y, 298 i_usX2Y_In04Int, usX2Y,
299 10); 299 10);
@@ -348,13 +348,12 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
348 sizeof(struct usX2Ydev), &card); 348 sizeof(struct usX2Ydev), &card);
349 if (err < 0) 349 if (err < 0)
350 return err; 350 return err;
351 snd_usX2Y_card_used[usX2Y(card)->chip.index = dev] = 1; 351 snd_usX2Y_card_used[usX2Y(card)->card_index = dev] = 1;
352 card->private_free = snd_usX2Y_card_private_free; 352 card->private_free = snd_usX2Y_card_private_free;
353 usX2Y(card)->chip.dev = device; 353 usX2Y(card)->dev = device;
354 usX2Y(card)->chip.card = card;
355 init_waitqueue_head(&usX2Y(card)->prepare_wait_queue); 354 init_waitqueue_head(&usX2Y(card)->prepare_wait_queue);
356 mutex_init(&usX2Y(card)->prepare_mutex); 355 mutex_init(&usX2Y(card)->prepare_mutex);
357 INIT_LIST_HEAD(&usX2Y(card)->chip.midi_list); 356 INIT_LIST_HEAD(&usX2Y(card)->midi_list);
358 strcpy(card->driver, "USB "NAME_ALLCAPS""); 357 strcpy(card->driver, "USB "NAME_ALLCAPS"");
359 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS""); 358 sprintf(card->shortname, "TASCAM "NAME_ALLCAPS"");
360 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)", 359 sprintf(card->longname, "%s (%x:%x if %d at %03d/%03d)",
@@ -362,7 +361,7 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
362 le16_to_cpu(device->descriptor.idVendor), 361 le16_to_cpu(device->descriptor.idVendor),
363 le16_to_cpu(device->descriptor.idProduct), 362 le16_to_cpu(device->descriptor.idProduct),
364 0,//us428(card)->usbmidi.ifnum, 363 0,//us428(card)->usbmidi.ifnum,
365 usX2Y(card)->chip.dev->bus->busnum, usX2Y(card)->chip.dev->devnum 364 usX2Y(card)->dev->bus->busnum, usX2Y(card)->dev->devnum
366 ); 365 );
367 *cardp = card; 366 *cardp = card;
368 return 0; 367 return 0;
@@ -432,8 +431,8 @@ static void snd_usX2Y_card_private_free(struct snd_card *card)
432 usb_free_urb(usX2Y(card)->In04urb); 431 usb_free_urb(usX2Y(card)->In04urb);
433 if (usX2Y(card)->us428ctls_sharedmem) 432 if (usX2Y(card)->us428ctls_sharedmem)
434 snd_free_pages(usX2Y(card)->us428ctls_sharedmem, sizeof(*usX2Y(card)->us428ctls_sharedmem)); 433 snd_free_pages(usX2Y(card)->us428ctls_sharedmem, sizeof(*usX2Y(card)->us428ctls_sharedmem));
435 if (usX2Y(card)->chip.index >= 0 && usX2Y(card)->chip.index < SNDRV_CARDS) 434 if (usX2Y(card)->card_index >= 0 && usX2Y(card)->card_index < SNDRV_CARDS)
436 snd_usX2Y_card_used[usX2Y(card)->chip.index] = 0; 435 snd_usX2Y_card_used[usX2Y(card)->card_index] = 0;
437} 436}
438 437
439/* 438/*
@@ -445,13 +444,12 @@ static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr)
445 struct snd_card *card = ptr; 444 struct snd_card *card = ptr;
446 struct usX2Ydev *usX2Y = usX2Y(card); 445 struct usX2Ydev *usX2Y = usX2Y(card);
447 struct list_head *p; 446 struct list_head *p;
448 usX2Y->chip.shutdown = 1;
449 usX2Y->chip_status = USX2Y_STAT_CHIP_HUP; 447 usX2Y->chip_status = USX2Y_STAT_CHIP_HUP;
450 usX2Y_unlinkSeq(&usX2Y->AS04); 448 usX2Y_unlinkSeq(&usX2Y->AS04);
451 usb_kill_urb(usX2Y->In04urb); 449 usb_kill_urb(usX2Y->In04urb);
452 snd_card_disconnect(card); 450 snd_card_disconnect(card);
453 /* release the midi resources */ 451 /* release the midi resources */
454 list_for_each(p, &usX2Y->chip.midi_list) { 452 list_for_each(p, &usX2Y->midi_list) {
455 snd_usbmidi_disconnect(p); 453 snd_usbmidi_disconnect(p);
456 } 454 }
457 if (usX2Y->us428ctls_sharedmem) 455 if (usX2Y->us428ctls_sharedmem)
diff --git a/sound/usb/usx2y/usbusx2y.h b/sound/usb/usx2y/usbusx2y.h
index 456b5fdbc339..1d174cea352b 100644
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -22,7 +22,8 @@ struct snd_usX2Y_urbSeq {
22#include "usx2yhwdeppcm.h" 22#include "usx2yhwdeppcm.h"
23 23
24struct usX2Ydev { 24struct usX2Ydev {
25 struct snd_usb_audio chip; 25 struct usb_device *dev;
26 int card_index;
26 int stride; 27 int stride;
27 struct urb *In04urb; 28 struct urb *In04urb;
28 void *In04Buf; 29 void *In04Buf;
@@ -42,6 +43,9 @@ struct usX2Ydev {
42 struct snd_usX2Y_substream *subs[4]; 43 struct snd_usX2Y_substream *subs[4];
43 struct snd_usX2Y_substream * volatile prepare_subs; 44 struct snd_usX2Y_substream * volatile prepare_subs;
44 wait_queue_head_t prepare_wait_queue; 45 wait_queue_head_t prepare_wait_queue;
46 struct list_head midi_list;
47 struct list_head pcm_list;
48 int pcm_devs;
45}; 49};
46 50
47 51
diff --git a/sound/usb/usx2y/usbusx2yaudio.c b/sound/usb/usx2y/usbusx2yaudio.c
index 9efd27f6b52f..74a67a85aa81 100644
--- a/sound/usb/usx2y/usbusx2yaudio.c
+++ b/sound/usb/usx2y/usbusx2yaudio.c
@@ -199,7 +199,7 @@ static int usX2Y_urb_submit(struct snd_usX2Y_substream *subs, struct urb *urb, i
199 return -ENODEV; 199 return -ENODEV;
200 urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks 200 urb->start_frame = (frame + NRURBS * nr_of_packs()); // let hcd do rollover sanity checks
201 urb->hcpriv = NULL; 201 urb->hcpriv = NULL;
202 urb->dev = subs->usX2Y->chip.dev; /* we need to set this at each time */ 202 urb->dev = subs->usX2Y->dev; /* we need to set this at each time */
203 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { 203 if ((err = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
204 snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err); 204 snd_printk(KERN_ERR "usb_submit_urb() returned %i\n", err);
205 return err; 205 return err;
@@ -300,7 +300,7 @@ static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
300"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n" 300"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).\n"
301"Most propably some urb of usb-frame %i is still missing.\n" 301"Most propably some urb of usb-frame %i is still missing.\n"
302"Cause could be too long delays in usb-hcd interrupt handling.\n", 302"Cause could be too long delays in usb-hcd interrupt handling.\n",
303 usb_get_current_frame_number(usX2Y->chip.dev), 303 usb_get_current_frame_number(usX2Y->dev),
304 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", 304 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
305 usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame); 305 usX2Y->wait_iso_frame, urb->start_frame, usX2Y->wait_iso_frame);
306 usX2Y_clients_stop(usX2Y); 306 usX2Y_clients_stop(usX2Y);
@@ -313,7 +313,7 @@ static void i_usX2Y_urb_complete(struct urb *urb)
313 313
314 if (unlikely(atomic_read(&subs->state) < state_PREPARED)) { 314 if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
315 snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", 315 snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
316 usb_get_current_frame_number(usX2Y->chip.dev), 316 usb_get_current_frame_number(usX2Y->dev),
317 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", 317 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
318 urb->status, urb->start_frame); 318 urb->status, urb->start_frame);
319 return; 319 return;
@@ -424,7 +424,7 @@ static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
424 int i; 424 int i;
425 unsigned int pipe; 425 unsigned int pipe;
426 int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; 426 int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
427 struct usb_device *dev = subs->usX2Y->chip.dev; 427 struct usb_device *dev = subs->usX2Y->dev;
428 428
429 pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) : 429 pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
430 usb_rcvisocpipe(dev, subs->endpoint); 430 usb_rcvisocpipe(dev, subs->endpoint);
@@ -500,7 +500,7 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
500 unsigned long pack; 500 unsigned long pack;
501 if (0 == i) 501 if (0 == i)
502 atomic_set(&subs->state, state_STARTING3); 502 atomic_set(&subs->state, state_STARTING3);
503 urb->dev = usX2Y->chip.dev; 503 urb->dev = usX2Y->dev;
504 urb->transfer_flags = URB_ISO_ASAP; 504 urb->transfer_flags = URB_ISO_ASAP;
505 for (pack = 0; pack < nr_of_packs(); pack++) { 505 for (pack = 0; pack < nr_of_packs(); pack++) {
506 urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack; 506 urb->iso_frame_desc[pack].offset = subs->maxpacksize * pack;
@@ -692,7 +692,7 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
692 } 692 }
693 ((char*)(usbdata + i))[0] = ra[i].c1; 693 ((char*)(usbdata + i))[0] = ra[i].c1;
694 ((char*)(usbdata + i))[1] = ra[i].c2; 694 ((char*)(usbdata + i))[1] = ra[i].c2;
695 usb_fill_bulk_urb(us->urb[i], usX2Y->chip.dev, usb_sndbulkpipe(usX2Y->chip.dev, 4), 695 usb_fill_bulk_urb(us->urb[i], usX2Y->dev, usb_sndbulkpipe(usX2Y->dev, 4),
696 usbdata + i, 2, i_usX2Y_04Int, usX2Y); 696 usbdata + i, 2, i_usX2Y_04Int, usX2Y);
697#ifdef OLD_USB 697#ifdef OLD_USB
698 us->urb[i]->transfer_flags = USB_QUEUE_BULK; 698 us->urb[i]->transfer_flags = USB_QUEUE_BULK;
@@ -740,17 +740,17 @@ static int usX2Y_format_set(struct usX2Ydev *usX2Y, snd_pcm_format_t format)
740 alternate = 1; 740 alternate = 1;
741 usX2Y->stride = 4; 741 usX2Y->stride = 4;
742 } 742 }
743 list_for_each(p, &usX2Y->chip.midi_list) { 743 list_for_each(p, &usX2Y->midi_list) {
744 snd_usbmidi_input_stop(p); 744 snd_usbmidi_input_stop(p);
745 } 745 }
746 usb_kill_urb(usX2Y->In04urb); 746 usb_kill_urb(usX2Y->In04urb);
747 if ((err = usb_set_interface(usX2Y->chip.dev, 0, alternate))) { 747 if ((err = usb_set_interface(usX2Y->dev, 0, alternate))) {
748 snd_printk(KERN_ERR "usb_set_interface error \n"); 748 snd_printk(KERN_ERR "usb_set_interface error \n");
749 return err; 749 return err;
750 } 750 }
751 usX2Y->In04urb->dev = usX2Y->chip.dev; 751 usX2Y->In04urb->dev = usX2Y->dev;
752 err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL); 752 err = usb_submit_urb(usX2Y->In04urb, GFP_KERNEL);
753 list_for_each(p, &usX2Y->chip.midi_list) { 753 list_for_each(p, &usX2Y->midi_list) {
754 snd_usbmidi_input_start(p); 754 snd_usbmidi_input_start(p);
755 } 755 }
756 usX2Y->format = format; 756 usX2Y->format = format;
@@ -955,7 +955,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
955 struct snd_pcm *pcm; 955 struct snd_pcm *pcm;
956 int err, i; 956 int err, i;
957 struct snd_usX2Y_substream **usX2Y_substream = 957 struct snd_usX2Y_substream **usX2Y_substream =
958 usX2Y(card)->subs + 2 * usX2Y(card)->chip.pcm_devs; 958 usX2Y(card)->subs + 2 * usX2Y(card)->pcm_devs;
959 959
960 for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE; 960 for (i = playback_endpoint ? SNDRV_PCM_STREAM_PLAYBACK : SNDRV_PCM_STREAM_CAPTURE;
961 i <= SNDRV_PCM_STREAM_CAPTURE; ++i) { 961 i <= SNDRV_PCM_STREAM_CAPTURE; ++i) {
@@ -971,7 +971,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
971 usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint; 971 usX2Y_substream[SNDRV_PCM_STREAM_PLAYBACK]->endpoint = playback_endpoint;
972 usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint; 972 usX2Y_substream[SNDRV_PCM_STREAM_CAPTURE]->endpoint = capture_endpoint;
973 973
974 err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usX2Y(card)->chip.pcm_devs, 974 err = snd_pcm_new(card, NAME_ALLCAPS" Audio", usX2Y(card)->pcm_devs,
975 playback_endpoint ? 1 : 0, 1, 975 playback_endpoint ? 1 : 0, 1,
976 &pcm); 976 &pcm);
977 if (err < 0) { 977 if (err < 0) {
@@ -987,7 +987,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
987 pcm->private_free = snd_usX2Y_pcm_private_free; 987 pcm->private_free = snd_usX2Y_pcm_private_free;
988 pcm->info_flags = 0; 988 pcm->info_flags = 0;
989 989
990 sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usX2Y(card)->chip.pcm_devs); 990 sprintf(pcm->name, NAME_ALLCAPS" Audio #%d", usX2Y(card)->pcm_devs);
991 991
992 if ((playback_endpoint && 992 if ((playback_endpoint &&
993 0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, 993 0 > (err = snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream,
@@ -1001,7 +1001,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
1001 snd_usX2Y_pcm_private_free(pcm); 1001 snd_usX2Y_pcm_private_free(pcm);
1002 return err; 1002 return err;
1003 } 1003 }
1004 usX2Y(card)->chip.pcm_devs++; 1004 usX2Y(card)->pcm_devs++;
1005 1005
1006 return 0; 1006 return 0;
1007} 1007}
@@ -1013,14 +1013,14 @@ int usX2Y_audio_create(struct snd_card *card)
1013{ 1013{
1014 int err = 0; 1014 int err = 0;
1015 1015
1016 INIT_LIST_HEAD(&usX2Y(card)->chip.pcm_list); 1016 INIT_LIST_HEAD(&usX2Y(card)->pcm_list);
1017 1017
1018 if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8))) 1018 if (0 > (err = usX2Y_audio_stream_new(card, 0xA, 0x8)))
1019 return err; 1019 return err;
1020 if (le16_to_cpu(usX2Y(card)->chip.dev->descriptor.idProduct) == USB_ID_US428) 1020 if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) == USB_ID_US428)
1021 if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA))) 1021 if (0 > (err = usX2Y_audio_stream_new(card, 0, 0xA)))
1022 return err; 1022 return err;
1023 if (le16_to_cpu(usX2Y(card)->chip.dev->descriptor.idProduct) != USB_ID_US122) 1023 if (le16_to_cpu(usX2Y(card)->dev->descriptor.idProduct) != USB_ID_US122)
1024 err = usX2Y_rate_set(usX2Y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122. 1024 err = usX2Y_rate_set(usX2Y(card), 44100); // Lets us428 recognize output-volume settings, disturbs us122.
1025 return err; 1025 return err;
1026} 1026}
diff --git a/sound/usb/usx2y/usx2yhwdeppcm.c b/sound/usb/usx2y/usx2yhwdeppcm.c
index 4b2304c2e02d..9ed6c3956ca7 100644
--- a/sound/usb/usx2y/usx2yhwdeppcm.c
+++ b/sound/usb/usx2y/usx2yhwdeppcm.c
@@ -234,7 +234,7 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)
234 234
235 if (unlikely(atomic_read(&subs->state) < state_PREPARED)) { 235 if (unlikely(atomic_read(&subs->state) < state_PREPARED)) {
236 snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n", 236 snd_printdd("hcd_frame=%i ep=%i%s status=%i start_frame=%i\n",
237 usb_get_current_frame_number(usX2Y->chip.dev), 237 usb_get_current_frame_number(usX2Y->dev),
238 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out", 238 subs->endpoint, usb_pipein(urb->pipe) ? "in" : "out",
239 urb->status, urb->start_frame); 239 urb->status, urb->start_frame);
240 return; 240 return;
@@ -318,7 +318,7 @@ static int usX2Y_usbpcm_urbs_allocate(struct snd_usX2Y_substream *subs)
318 int i; 318 int i;
319 unsigned int pipe; 319 unsigned int pipe;
320 int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK]; 320 int is_playback = subs == subs->usX2Y->subs[SNDRV_PCM_STREAM_PLAYBACK];
321 struct usb_device *dev = subs->usX2Y->chip.dev; 321 struct usb_device *dev = subs->usX2Y->dev;
322 322
323 pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) : 323 pipe = is_playback ? usb_sndisocpipe(dev, subs->endpoint) :
324 usb_rcvisocpipe(dev, subs->endpoint); 324 usb_rcvisocpipe(dev, subs->endpoint);
@@ -441,7 +441,7 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
441 unsigned long pack; 441 unsigned long pack;
442 if (0 == u) 442 if (0 == u)
443 atomic_set(&subs->state, state_STARTING3); 443 atomic_set(&subs->state, state_STARTING3);
444 urb->dev = usX2Y->chip.dev; 444 urb->dev = usX2Y->dev;
445 urb->transfer_flags = URB_ISO_ASAP; 445 urb->transfer_flags = URB_ISO_ASAP;
446 for (pack = 0; pack < nr_of_packs(); pack++) { 446 for (pack = 0; pack < nr_of_packs(); pack++) {
447 urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs()); 447 urb->iso_frame_desc[pack].offset = subs->maxpacksize * (pack + u * nr_of_packs());
@@ -741,7 +741,7 @@ int usX2Y_hwdep_pcm_new(struct snd_card *card)
741 int err; 741 int err;
742 struct snd_hwdep *hw; 742 struct snd_hwdep *hw;
743 struct snd_pcm *pcm; 743 struct snd_pcm *pcm;
744 struct usb_device *dev = usX2Y(card)->chip.dev; 744 struct usb_device *dev = usX2Y(card)->dev;
745 if (1 != nr_of_packs()) 745 if (1 != nr_of_packs())
746 return 0; 746 return 0;
747 747