aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/ac97_bus.c1
-rw-r--r--sound/aoa/codecs/Makefile4
-rw-r--r--sound/aoa/codecs/onyx.c (renamed from sound/aoa/codecs/snd-aoa-codec-onyx.c)12
-rw-r--r--sound/aoa/codecs/onyx.h (renamed from sound/aoa/codecs/snd-aoa-codec-onyx.h)0
-rw-r--r--sound/aoa/codecs/tas-basstreble.h (renamed from sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h)0
-rw-r--r--sound/aoa/codecs/tas-gain-table.h (renamed from sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h)0
-rw-r--r--sound/aoa/codecs/tas.c (renamed from sound/aoa/codecs/snd-aoa-codec-tas.c)8
-rw-r--r--sound/aoa/codecs/tas.h (renamed from sound/aoa/codecs/snd-aoa-codec-tas.h)0
-rw-r--r--sound/aoa/codecs/toonie.c (renamed from sound/aoa/codecs/snd-aoa-codec-toonie.c)2
-rw-r--r--sound/aoa/core/Makefile8
-rw-r--r--sound/aoa/core/alsa.c (renamed from sound/aoa/core/snd-aoa-alsa.c)4
-rw-r--r--sound/aoa/core/alsa.h (renamed from sound/aoa/core/snd-aoa-alsa.h)0
-rw-r--r--sound/aoa/core/core.c (renamed from sound/aoa/core/snd-aoa-core.c)2
-rw-r--r--sound/aoa/core/gpio-feature.c (renamed from sound/aoa/core/snd-aoa-gpio-feature.c)2
-rw-r--r--sound/aoa/core/gpio-pmf.c (renamed from sound/aoa/core/snd-aoa-gpio-pmf.c)0
-rw-r--r--sound/aoa/fabrics/Makefile2
-rw-r--r--sound/aoa/fabrics/layout.c (renamed from sound/aoa/fabrics/snd-aoa-fabric-layout.c)2
-rw-r--r--sound/aoa/soundbus/i2sbus/Makefile2
-rw-r--r--sound/aoa/soundbus/i2sbus/control.c (renamed from sound/aoa/soundbus/i2sbus/i2sbus-control.c)0
-rw-r--r--sound/aoa/soundbus/i2sbus/core.c (renamed from sound/aoa/soundbus/i2sbus/i2sbus-core.c)4
-rw-r--r--sound/aoa/soundbus/i2sbus/i2sbus.h2
-rw-r--r--sound/aoa/soundbus/i2sbus/interface.h (renamed from sound/aoa/soundbus/i2sbus/i2sbus-interface.h)0
-rw-r--r--sound/aoa/soundbus/i2sbus/pcm.c (renamed from sound/aoa/soundbus/i2sbus/i2sbus-pcm.c)0
-rw-r--r--sound/core/Kconfig21
-rw-r--r--sound/core/Makefile2
-rw-r--r--sound/core/device.c4
-rw-r--r--sound/core/hrtimer.c155
-rw-r--r--sound/core/info.c17
-rw-r--r--sound/core/init.c71
-rw-r--r--sound/core/jack.c15
-rw-r--r--sound/core/rawmidi.c4
-rw-r--r--sound/core/rtctimer.c2
-rw-r--r--sound/core/seq/seq.c4
-rw-r--r--sound/core/timer.c2
-rw-r--r--sound/drivers/Kconfig2
-rw-r--r--sound/drivers/pcsp/pcsp.c8
-rw-r--r--sound/drivers/pcsp/pcsp.h3
-rw-r--r--sound/drivers/pcsp/pcsp_lib.c168
-rw-r--r--sound/drivers/vx/vx_core.c2
-rw-r--r--sound/drivers/vx/vx_pcm.c2
-rw-r--r--sound/isa/sb/sb8.c4
-rw-r--r--sound/pci/Kconfig127
-rw-r--r--sound/pci/ac97/ac97_codec.c2
-rw-r--r--sound/pci/ac97/ac97_patch.c7
-rw-r--r--sound/pci/ca0106/ca0106.h30
-rw-r--r--sound/pci/ca0106/ca0106_main.c550
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c263
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c5
-rw-r--r--sound/pci/cs5535audio/Makefile3
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c12
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h39
-rw-r--r--sound/pci/cs5535audio/cs5535audio_olpc.c179
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c15
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c494
-rw-r--r--sound/pci/emu10k1/emumixer.c46
-rw-r--r--sound/pci/es1968.c2
-rw-r--r--sound/pci/hda/Kconfig188
-rw-r--r--sound/pci/hda/Makefile75
-rw-r--r--sound/pci/hda/hda_beep.c2
-rw-r--r--sound/pci/hda/hda_codec.c781
-rw-r--r--sound/pci/hda/hda_codec.h107
-rw-r--r--sound/pci/hda/hda_eld.c590
-rw-r--r--sound/pci/hda/hda_generic.c21
-rw-r--r--sound/pci/hda/hda_hwdep.c234
-rw-r--r--sound/pci/hda/hda_intel.c348
-rw-r--r--sound/pci/hda/hda_local.h100
-rw-r--r--sound/pci/hda/hda_patch.h22
-rw-r--r--sound/pci/hda/hda_proc.c91
-rw-r--r--sound/pci/hda/patch_analog.c132
-rw-r--r--sound/pci/hda/patch_atihdmi.c40
-rw-r--r--sound/pci/hda/patch_cmedia.c27
-rw-r--r--sound/pci/hda/patch_conexant.c39
-rw-r--r--sound/pci/hda/patch_intelhdmi.c711
-rw-r--r--sound/pci/hda/patch_nvhdmi.c32
-rw-r--r--sound/pci/hda/patch_realtek.c1663
-rw-r--r--sound/pci/hda/patch_si3054.c35
-rw-r--r--sound/pci/hda/patch_sigmatel.c1331
-rw-r--r--sound/pci/hda/patch_via.c171
-rw-r--r--sound/pci/ice1712/ice1724.c23
-rw-r--r--sound/pci/maestro3.c2
-rw-r--r--sound/pci/mixart/mixart.c4
-rw-r--r--sound/pci/mixart/mixart_core.c2
-rw-r--r--sound/pci/oxygen/oxygen.c4
-rw-r--r--sound/pci/pcxhr/Makefile2
-rw-r--r--sound/pci/pcxhr/pcxhr.c558
-rw-r--r--sound/pci/pcxhr/pcxhr.h76
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c293
-rw-r--r--sound/pci/pcxhr/pcxhr_core.h5
-rw-r--r--sound/pci/pcxhr/pcxhr_hwdep.c158
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.c820
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.h56
-rw-r--r--sound/pci/pcxhr/pcxhr_mixer.c556
-rw-r--r--sound/pci/riptide/riptide.c4
-rw-r--r--sound/pci/rme9652/hdsp.c4
-rw-r--r--sound/pci/rme9652/hdspm.c4
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_irq.c2
-rw-r--r--sound/ppc/pmac.c2
-rw-r--r--sound/ppc/tumbler.c3
-rw-r--r--sound/soc/Kconfig13
-rw-r--r--sound/soc/Makefile12
-rw-r--r--sound/soc/at32/Kconfig34
-rw-r--r--sound/soc/at32/Makefile11
-rw-r--r--sound/soc/at32/at32-pcm.c492
-rw-r--r--sound/soc/at32/at32-pcm.h79
-rw-r--r--sound/soc/at32/at32-ssc.c849
-rw-r--r--sound/soc/at32/at32-ssc.h59
-rw-r--r--sound/soc/at91/Kconfig10
-rw-r--r--sound/soc/at91/Makefile6
-rw-r--r--sound/soc/at91/at91-pcm.c434
-rw-r--r--sound/soc/at91/at91-pcm.h72
-rw-r--r--sound/soc/at91/at91-ssc.c791
-rw-r--r--sound/soc/at91/at91-ssc.h27
-rw-r--r--sound/soc/atmel/Kconfig43
-rw-r--r--sound/soc/atmel/Makefile15
-rw-r--r--sound/soc/atmel/atmel-pcm.c494
-rw-r--r--sound/soc/atmel/atmel-pcm.h86
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.c790
-rw-r--r--sound/soc/atmel/atmel_ssc_dai.h121
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c (renamed from sound/soc/at32/playpaq_wm8510.c)11
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c328
-rw-r--r--sound/soc/au1x/dbdma2.c3
-rw-r--r--sound/soc/au1x/psc-ac97.c16
-rw-r--r--sound/soc/au1x/psc-i2s.c18
-rw-r--r--sound/soc/au1x/sample-ac97.c4
-rw-r--r--sound/soc/blackfin/Kconfig22
-rw-r--r--sound/soc/blackfin/bf5xx-ac97-pcm.c113
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.c178
-rw-r--r--sound/soc/blackfin/bf5xx-ac97.h35
-rw-r--r--sound/soc/blackfin/bf5xx-ad1980.c8
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c10
-rw-r--r--sound/soc/blackfin/bf5xx-i2s-pcm.c12
-rw-r--r--sound/soc/blackfin/bf5xx-i2s.c31
-rw-r--r--sound/soc/blackfin/bf5xx-sport.h2
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c14
-rw-r--r--sound/soc/codecs/Kconfig69
-rw-r--r--sound/soc/codecs/Makefile12
-rw-r--r--sound/soc/codecs/ac97.c7
-rw-r--r--sound/soc/codecs/ad1980.c24
-rw-r--r--sound/soc/codecs/ad73311.c18
-rw-r--r--sound/soc/codecs/ak4535.c19
-rw-r--r--sound/soc/codecs/cs4270.c38
-rw-r--r--sound/soc/codecs/l3.c91
-rw-r--r--sound/soc/codecs/pcm3008.c212
-rw-r--r--sound/soc/codecs/pcm3008.h25
-rw-r--r--sound/soc/codecs/ssm2602.c57
-rw-r--r--sound/soc/codecs/tlv320aic23.c262
-rw-r--r--sound/soc/codecs/tlv320aic26.c22
-rw-r--r--sound/soc/codecs/tlv320aic3x.c166
-rw-r--r--sound/soc/codecs/tlv320aic3x.h60
-rw-r--r--sound/soc/codecs/twl4030.c1317
-rw-r--r--sound/soc/codecs/twl4030.h219
-rw-r--r--sound/soc/codecs/uda134x.c668
-rw-r--r--sound/soc/codecs/uda134x.h36
-rw-r--r--sound/soc/codecs/uda1380.c29
-rw-r--r--sound/soc/codecs/wm8350.c1583
-rw-r--r--sound/soc/codecs/wm8350.h20
-rw-r--r--sound/soc/codecs/wm8510.c19
-rw-r--r--sound/soc/codecs/wm8580.c134
-rw-r--r--sound/soc/codecs/wm8580.h1
-rw-r--r--sound/soc/codecs/wm8728.c585
-rw-r--r--sound/soc/codecs/wm8728.h30
-rw-r--r--sound/soc/codecs/wm8731.c25
-rw-r--r--sound/soc/codecs/wm8750.c19
-rw-r--r--sound/soc/codecs/wm8753.c39
-rw-r--r--sound/soc/codecs/wm8900.c262
-rw-r--r--sound/soc/codecs/wm8900.h6
-rw-r--r--sound/soc/codecs/wm8903.c268
-rw-r--r--sound/soc/codecs/wm8903.h5
-rw-r--r--sound/soc/codecs/wm8971.c19
-rw-r--r--sound/soc/codecs/wm8990.c43
-rw-r--r--sound/soc/codecs/wm8990.h4
-rw-r--r--sound/soc/codecs/wm9712.c12
-rw-r--r--sound/soc/codecs/wm9713.c46
-rw-r--r--sound/soc/davinci/Kconfig10
-rw-r--r--sound/soc/davinci/Makefile2
-rw-r--r--sound/soc/davinci/davinci-evm.c14
-rw-r--r--sound/soc/davinci/davinci-i2s.c257
-rw-r--r--sound/soc/davinci/davinci-pcm.c30
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c157
-rw-r--r--sound/soc/fsl/Kconfig2
-rw-r--r--sound/soc/fsl/fsl_dma.c14
-rw-r--r--sound/soc/fsl/fsl_ssi.c24
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c22
-rw-r--r--sound/soc/fsl/mpc8610_hpcd.c8
-rw-r--r--sound/soc/fsl/soc-of-simple.c12
-rw-r--r--sound/soc/omap/Kconfig35
-rw-r--r--sound/soc/omap/Makefile8
-rw-r--r--sound/soc/omap/n810.c10
-rw-r--r--sound/soc/omap/omap-mcbsp.c61
-rw-r--r--sound/soc/omap/omap-pcm.c16
-rw-r--r--sound/soc/omap/omap2evm.c151
-rw-r--r--sound/soc/omap/omap3beagle.c149
-rw-r--r--sound/soc/omap/omap3pandora.c311
-rw-r--r--sound/soc/omap/osk5912.c10
-rw-r--r--sound/soc/omap/overo.c148
-rw-r--r--sound/soc/omap/sdp3430.c152
-rw-r--r--sound/soc/pxa/Kconfig22
-rw-r--r--sound/soc/pxa/Makefile6
-rw-r--r--sound/soc/pxa/corgi.c12
-rw-r--r--sound/soc/pxa/e800_wm9712.c8
-rw-r--r--sound/soc/pxa/em-x270.c7
-rw-r--r--sound/soc/pxa/palm27x.c269
-rw-r--r--sound/soc/pxa/poodle.c6
-rw-r--r--sound/soc/pxa/pxa-ssp.c931
-rw-r--r--sound/soc/pxa/pxa-ssp.h47
-rw-r--r--sound/soc/pxa/pxa2xx-ac97.c33
-rw-r--r--sound/soc/pxa/pxa2xx-i2s.c35
-rw-r--r--sound/soc/pxa/pxa2xx-pcm.c14
-rw-r--r--sound/soc/pxa/spitz.c6
-rw-r--r--sound/soc/pxa/tosa.c38
-rw-r--r--sound/soc/pxa/zylonite.c219
-rw-r--r--sound/soc/s3c24xx/Kconfig5
-rw-r--r--sound/soc/s3c24xx/Makefile2
-rw-r--r--sound/soc/s3c24xx/ln2440sbc_alc650.c8
-rw-r--r--sound/soc/s3c24xx/neo1973_wm8753.c9
-rw-r--r--sound/soc/s3c24xx/s3c2412-i2s.c38
-rw-r--r--sound/soc/s3c24xx/s3c2443-ac97.c30
-rw-r--r--sound/soc/s3c24xx/s3c24xx-i2s.c35
-rw-r--r--sound/soc/s3c24xx/s3c24xx-pcm.c12
-rw-r--r--sound/soc/s3c24xx/s3c24xx_uda134x.c373
-rw-r--r--sound/soc/s3c24xx/smdk2443_wm9710.c8
-rw-r--r--sound/soc/sh/dma-sh7760.c12
-rw-r--r--sound/soc/sh/hac.c19
-rw-r--r--sound/soc/sh/sh7760-ac97.c6
-rw-r--r--sound/soc/sh/ssi.c30
-rw-r--r--sound/soc/soc-core.c840
-rw-r--r--sound/soc/soc-dapm.c82
-rw-r--r--sound/sound_core.c1
-rw-r--r--sound/usb/caiaq/caiaq-control.c73
-rw-r--r--sound/usb/caiaq/caiaq-device.c2
-rw-r--r--sound/usb/usbmidi.c2
-rw-r--r--sound/usb/usx2y/usb_stream.c3
232 files changed, 20714 insertions, 7479 deletions
diff --git a/sound/ac97_bus.c b/sound/ac97_bus.c
index 7fa37e15f196..a351dd0a09c7 100644
--- a/sound/ac97_bus.c
+++ b/sound/ac97_bus.c
@@ -15,6 +15,7 @@
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <sound/ac97_codec.h>
18 19
19/* 20/*
20 * Let drivers decide whether they want to support given codec from their 21 * Let drivers decide whether they want to support given codec from their
diff --git a/sound/aoa/codecs/Makefile b/sound/aoa/codecs/Makefile
index 31cbe68fd42f..c3ee77fc4b2d 100644
--- a/sound/aoa/codecs/Makefile
+++ b/sound/aoa/codecs/Makefile
@@ -1,3 +1,7 @@
1snd-aoa-codec-onyx-objs := onyx.o
2snd-aoa-codec-tas-objs := tas.o
3snd-aoa-codec-toonie-objs := toonie.o
4
1obj-$(CONFIG_SND_AOA_ONYX) += snd-aoa-codec-onyx.o 5obj-$(CONFIG_SND_AOA_ONYX) += snd-aoa-codec-onyx.o
2obj-$(CONFIG_SND_AOA_TAS) += snd-aoa-codec-tas.o 6obj-$(CONFIG_SND_AOA_TAS) += snd-aoa-codec-tas.o
3obj-$(CONFIG_SND_AOA_TOONIE) += snd-aoa-codec-toonie.o 7obj-$(CONFIG_SND_AOA_TOONIE) += snd-aoa-codec-toonie.o
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.c b/sound/aoa/codecs/onyx.c
index 6a3837d480e5..15500b9d2da0 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -37,7 +37,7 @@ MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa"); 38MODULE_DESCRIPTION("pcm3052 (onyx) codec driver for snd-aoa");
39 39
40#include "snd-aoa-codec-onyx.h" 40#include "onyx.h"
41#include "../aoa.h" 41#include "../aoa.h"
42#include "../soundbus/soundbus.h" 42#include "../soundbus/soundbus.h"
43 43
@@ -292,7 +292,7 @@ static int onyx_snd_capture_source_put(struct snd_kcontrol *kcontrol,
292static struct snd_kcontrol_new capture_source_control = { 292static struct snd_kcontrol_new capture_source_control = {
293 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 293 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
294 /* If we name this 'Input Source', it properly shows up in 294 /* If we name this 'Input Source', it properly shows up in
295 * alsamixer as a selection, * but it's shown under the 295 * alsamixer as a selection, * but it's shown under the
296 * 'Playback' category. 296 * 'Playback' category.
297 * If I name it 'Capture Source', it shows up in strange 297 * If I name it 'Capture Source', it shows up in strange
298 * ways (two bools of which one can be selected at a 298 * ways (two bools of which one can be selected at a
@@ -477,7 +477,7 @@ static int onyx_spdif_mask_get(struct snd_kcontrol *kcontrol,
477 477
478 ucontrol->value.iec958.status[3] = 0x3f; 478 ucontrol->value.iec958.status[3] = 0x3f;
479 ucontrol->value.iec958.status[4] = 0x0f; 479 ucontrol->value.iec958.status[4] = 0x0f;
480 480
481 return 0; 481 return 0;
482} 482}
483 483
@@ -682,7 +682,7 @@ static int onyx_usable(struct codec_info_item *cii,
682 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v); 682 onyx_read_register(onyx, ONYX_REG_DIG_INFO4, &v);
683 spdif_enabled = !!(v & ONYX_SPDIF_ENABLE); 683 spdif_enabled = !!(v & ONYX_SPDIF_ENABLE);
684 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v); 684 onyx_read_register(onyx, ONYX_REG_DAC_CONTROL, &v);
685 analog_enabled = 685 analog_enabled =
686 (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT)) 686 (v & (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT))
687 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT); 687 != (ONYX_MUTE_RIGHT|ONYX_MUTE_LEFT);
688 mutex_unlock(&onyx->mutex); 688 mutex_unlock(&onyx->mutex);
@@ -882,7 +882,7 @@ static int onyx_init_codec(struct aoa_codec *codec)
882 msleep(1); 882 msleep(1);
883 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0); 883 onyx->codec.gpio->methods->set_hw_reset(onyx->codec.gpio, 0);
884 msleep(1); 884 msleep(1);
885 885
886 if (onyx_register_init(onyx)) { 886 if (onyx_register_init(onyx)) {
887 printk(KERN_ERR PFX "failed to initialise onyx registers\n"); 887 printk(KERN_ERR PFX "failed to initialise onyx registers\n");
888 return -ENODEV; 888 return -ENODEV;
@@ -1069,7 +1069,7 @@ static int onyx_i2c_attach(struct i2c_adapter *adapter)
1069 1069
1070 /* if that didn't work, try desperate mode for older 1070 /* if that didn't work, try desperate mode for older
1071 * machines that have stuff missing from the device tree */ 1071 * machines that have stuff missing from the device tree */
1072 1072
1073 if (!of_device_is_compatible(busnode, "k2-i2c")) 1073 if (!of_device_is_compatible(busnode, "k2-i2c"))
1074 return -ENODEV; 1074 return -ENODEV;
1075 1075
diff --git a/sound/aoa/codecs/snd-aoa-codec-onyx.h b/sound/aoa/codecs/onyx.h
index ffd20254ff76..ffd20254ff76 100644
--- a/sound/aoa/codecs/snd-aoa-codec-onyx.h
+++ b/sound/aoa/codecs/onyx.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h b/sound/aoa/codecs/tas-basstreble.h
index 69b61136fd54..69b61136fd54 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas-basstreble.h
+++ b/sound/aoa/codecs/tas-basstreble.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h b/sound/aoa/codecs/tas-gain-table.h
index 4cfa6757715e..4cfa6757715e 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas-gain-table.h
+++ b/sound/aoa/codecs/tas-gain-table.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.c b/sound/aoa/codecs/tas.c
index 6c515b2b8bbd..008e0f85097d 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -71,9 +71,9 @@ MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
71MODULE_LICENSE("GPL"); 71MODULE_LICENSE("GPL");
72MODULE_DESCRIPTION("tas codec driver for snd-aoa"); 72MODULE_DESCRIPTION("tas codec driver for snd-aoa");
73 73
74#include "snd-aoa-codec-tas.h" 74#include "tas.h"
75#include "snd-aoa-codec-tas-gain-table.h" 75#include "tas-gain-table.h"
76#include "snd-aoa-codec-tas-basstreble.h" 76#include "tas-basstreble.h"
77#include "../aoa.h" 77#include "../aoa.h"
78#include "../soundbus/soundbus.h" 78#include "../soundbus/soundbus.h"
79 79
@@ -880,7 +880,7 @@ static void tas_exit_codec(struct aoa_codec *codec)
880 return; 880 return;
881 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas); 881 tas->codec.soundbus_dev->detach_codec(tas->codec.soundbus_dev, tas);
882} 882}
883 883
884 884
885static struct i2c_driver tas_driver; 885static struct i2c_driver tas_driver;
886 886
diff --git a/sound/aoa/codecs/snd-aoa-codec-tas.h b/sound/aoa/codecs/tas.h
index ae177e3466e6..ae177e3466e6 100644
--- a/sound/aoa/codecs/snd-aoa-codec-tas.h
+++ b/sound/aoa/codecs/tas.h
diff --git a/sound/aoa/codecs/snd-aoa-codec-toonie.c b/sound/aoa/codecs/toonie.c
index 3c7d1d8a9a6f..f13827e17562 100644
--- a/sound/aoa/codecs/snd-aoa-codec-toonie.c
+++ b/sound/aoa/codecs/toonie.c
@@ -131,7 +131,7 @@ static int __init toonie_init(void)
131 toonie->codec.owner = THIS_MODULE; 131 toonie->codec.owner = THIS_MODULE;
132 toonie->codec.init = toonie_init_codec; 132 toonie->codec.init = toonie_init_codec;
133 toonie->codec.exit = toonie_exit_codec; 133 toonie->codec.exit = toonie_exit_codec;
134 134
135 if (aoa_codec_register(&toonie->codec)) { 135 if (aoa_codec_register(&toonie->codec)) {
136 kfree(toonie); 136 kfree(toonie);
137 return -EINVAL; 137 return -EINVAL;
diff --git a/sound/aoa/core/Makefile b/sound/aoa/core/Makefile
index 62dc7287f663..a1596e88c718 100644
--- a/sound/aoa/core/Makefile
+++ b/sound/aoa/core/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_SND_AOA) += snd-aoa.o 1obj-$(CONFIG_SND_AOA) += snd-aoa.o
2snd-aoa-objs := snd-aoa-core.o \ 2snd-aoa-objs := core.o \
3 snd-aoa-alsa.o \ 3 alsa.o \
4 snd-aoa-gpio-pmf.o \ 4 gpio-pmf.o \
5 snd-aoa-gpio-feature.o 5 gpio-feature.o
diff --git a/sound/aoa/core/snd-aoa-alsa.c b/sound/aoa/core/alsa.c
index 17fe689ed287..617850463582 100644
--- a/sound/aoa/core/snd-aoa-alsa.c
+++ b/sound/aoa/core/alsa.c
@@ -6,7 +6,7 @@
6 * GPL v2, can be found in COPYING. 6 * GPL v2, can be found in COPYING.
7 */ 7 */
8#include <linux/module.h> 8#include <linux/module.h>
9#include "snd-aoa-alsa.h" 9#include "alsa.h"
10 10
11static int index = -1; 11static int index = -1;
12module_param(index, int, 0444); 12module_param(index, int, 0444);
@@ -64,7 +64,7 @@ int aoa_snd_device_new(snd_device_type_t type,
64{ 64{
65 struct snd_card *card = aoa_get_card(); 65 struct snd_card *card = aoa_get_card();
66 int err; 66 int err;
67 67
68 if (!card) return -ENOMEM; 68 if (!card) return -ENOMEM;
69 69
70 err = snd_device_new(card, type, device_data, ops); 70 err = snd_device_new(card, type, device_data, ops);
diff --git a/sound/aoa/core/snd-aoa-alsa.h b/sound/aoa/core/alsa.h
index 9669e4489cab..9669e4489cab 100644
--- a/sound/aoa/core/snd-aoa-alsa.h
+++ b/sound/aoa/core/alsa.h
diff --git a/sound/aoa/core/snd-aoa-core.c b/sound/aoa/core/core.c
index 19fdae400687..10bec6c61382 100644
--- a/sound/aoa/core/snd-aoa-core.c
+++ b/sound/aoa/core/core.c
@@ -10,7 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/list.h> 11#include <linux/list.h>
12#include "../aoa.h" 12#include "../aoa.h"
13#include "snd-aoa-alsa.h" 13#include "alsa.h"
14 14
15MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver"); 15MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
16MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>"); 16MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
diff --git a/sound/aoa/core/snd-aoa-gpio-feature.c b/sound/aoa/core/gpio-feature.c
index 805dcbff2257..c93ad5dec66b 100644
--- a/sound/aoa/core/snd-aoa-gpio-feature.c
+++ b/sound/aoa/core/gpio-feature.c
@@ -5,7 +5,7 @@
5 * 5 *
6 * GPL v2, can be found in COPYING. 6 * GPL v2, can be found in COPYING.
7 * 7 *
8 * This file contains the GPIO control routines for 8 * This file contains the GPIO control routines for
9 * direct (through feature calls) access to the GPIO 9 * direct (through feature calls) access to the GPIO
10 * registers. 10 * registers.
11 */ 11 */
diff --git a/sound/aoa/core/snd-aoa-gpio-pmf.c b/sound/aoa/core/gpio-pmf.c
index 5ca2220eac7d..5ca2220eac7d 100644
--- a/sound/aoa/core/snd-aoa-gpio-pmf.c
+++ b/sound/aoa/core/gpio-pmf.c
diff --git a/sound/aoa/fabrics/Makefile b/sound/aoa/fabrics/Makefile
index 55fc5e7e52cf..da37c10eca51 100644
--- a/sound/aoa/fabrics/Makefile
+++ b/sound/aoa/fabrics/Makefile
@@ -1 +1,3 @@
1snd-aoa-fabric-layout-objs += layout.o
2
1obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o 3obj-$(CONFIG_SND_AOA_FABRIC_LAYOUT) += snd-aoa-fabric-layout.o
diff --git a/sound/aoa/fabrics/snd-aoa-fabric-layout.c b/sound/aoa/fabrics/layout.c
index dea7abb082cd..ad60f5d10e82 100644
--- a/sound/aoa/fabrics/snd-aoa-fabric-layout.c
+++ b/sound/aoa/fabrics/layout.c
@@ -66,7 +66,7 @@ struct layout {
66 unsigned int layout_id; 66 unsigned int layout_id;
67 struct codec_connect_info codecs[MAX_CODECS_PER_BUS]; 67 struct codec_connect_info codecs[MAX_CODECS_PER_BUS];
68 int flags; 68 int flags;
69 69
70 /* if busname is not assigned, we use 'Master' below, 70 /* if busname is not assigned, we use 'Master' below,
71 * so that our layout table doesn't need to be filled 71 * so that our layout table doesn't need to be filled
72 * too much. 72 * too much.
diff --git a/sound/aoa/soundbus/i2sbus/Makefile b/sound/aoa/soundbus/i2sbus/Makefile
index e57a5cf65655..1b949b2a4028 100644
--- a/sound/aoa/soundbus/i2sbus/Makefile
+++ b/sound/aoa/soundbus/i2sbus/Makefile
@@ -1,2 +1,2 @@
1obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += snd-aoa-i2sbus.o 1obj-$(CONFIG_SND_AOA_SOUNDBUS_I2S) += snd-aoa-i2sbus.o
2snd-aoa-i2sbus-objs := i2sbus-core.o i2sbus-pcm.o i2sbus-control.o 2snd-aoa-i2sbus-objs := core.o pcm.o control.o
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-control.c b/sound/aoa/soundbus/i2sbus/control.c
index 87beb4ad4d63..87beb4ad4d63 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-control.c
+++ b/sound/aoa/soundbus/i2sbus/control.c
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-core.c b/sound/aoa/soundbus/i2sbus/core.c
index b4590df07466..be468edf3ecb 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-core.c
+++ b/sound/aoa/soundbus/i2sbus/core.c
@@ -64,7 +64,7 @@ static void free_dbdma_descriptor_ring(struct i2sbus_dev *i2sdev,
64 struct dbdma_command_mem *r) 64 struct dbdma_command_mem *r)
65{ 65{
66 if (!r->space) return; 66 if (!r->space) return;
67 67
68 dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev, 68 dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev,
69 r->size, r->space, r->bus_addr); 69 r->size, r->space, r->bus_addr);
70} 70}
@@ -247,7 +247,7 @@ static int i2sbus_add_dev(struct macio_dev *macio,
247 * but request_resource doesn't know about parents and 247 * but request_resource doesn't know about parents and
248 * contained resources... 248 * contained resources...
249 */ 249 */
250 dev->allocated_resource[i] = 250 dev->allocated_resource[i] =
251 request_mem_region(dev->resources[i].start, 251 request_mem_region(dev->resources[i].start,
252 dev->resources[i].end - 252 dev->resources[i].end -
253 dev->resources[i].start + 1, 253 dev->resources[i].start + 1,
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus.h b/sound/aoa/soundbus/i2sbus/i2sbus.h
index ff29654782c9..befefd99e271 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus.h
+++ b/sound/aoa/soundbus/i2sbus/i2sbus.h
@@ -18,7 +18,7 @@
18#include <asm/pmac_feature.h> 18#include <asm/pmac_feature.h>
19#include <asm/dbdma.h> 19#include <asm/dbdma.h>
20 20
21#include "i2sbus-interface.h" 21#include "interface.h"
22#include "../soundbus.h" 22#include "../soundbus.h"
23 23
24struct i2sbus_control { 24struct i2sbus_control {
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-interface.h b/sound/aoa/soundbus/i2sbus/interface.h
index c6b5f5452d20..c6b5f5452d20 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-interface.h
+++ b/sound/aoa/soundbus/i2sbus/interface.h
diff --git a/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c b/sound/aoa/soundbus/i2sbus/pcm.c
index 59bacd365733..59bacd365733 100644
--- a/sound/aoa/soundbus/i2sbus/i2sbus-pcm.c
+++ b/sound/aoa/soundbus/i2sbus/pcm.c
diff --git a/sound/core/Kconfig b/sound/core/Kconfig
index 66348c92f88d..7bbdda041a99 100644
--- a/sound/core/Kconfig
+++ b/sound/core/Kconfig
@@ -95,6 +95,26 @@ config SND_SEQUENCER_OSS
95 this will be compiled as a module. The module will be called 95 this will be compiled as a module. The module will be called
96 snd-seq-oss. 96 snd-seq-oss.
97 97
98config SND_HRTIMER
99 tristate "HR-timer backend support"
100 depends on HIGH_RES_TIMERS
101 select SND_TIMER
102 help
103 Say Y here to enable HR-timer backend for ALSA timer. ALSA uses
104 the hrtimer as a precise timing source. The ALSA sequencer code
105 also can use this timing source.
106
107 To compile this driver as a module, choose M here: the module
108 will be called snd-hrtimer.
109
110config SND_SEQ_HRTIMER_DEFAULT
111 bool "Use HR-timer as default sequencer timer"
112 depends on SND_HRTIMER && SND_SEQUENCER
113 default y
114 help
115 Say Y here to use the HR-timer backend as the default sequencer
116 timer.
117
98config SND_RTCTIMER 118config SND_RTCTIMER
99 tristate "RTC Timer support" 119 tristate "RTC Timer support"
100 depends on RTC 120 depends on RTC
@@ -114,6 +134,7 @@ config SND_RTCTIMER
114config SND_SEQ_RTCTIMER_DEFAULT 134config SND_SEQ_RTCTIMER_DEFAULT
115 bool "Use RTC as default sequencer timer" 135 bool "Use RTC as default sequencer timer"
116 depends on SND_RTCTIMER && SND_SEQUENCER 136 depends on SND_RTCTIMER && SND_SEQUENCER
137 depends on !SND_SEQ_HRTIMER_DEFAULT
117 default y 138 default y
118 help 139 help
119 Say Y here to use the RTC timer as the default sequencer 140 Say Y here to use the RTC timer as the default sequencer
diff --git a/sound/core/Makefile b/sound/core/Makefile
index d57125a5687d..4229052e7b91 100644
--- a/sound/core/Makefile
+++ b/sound/core/Makefile
@@ -17,12 +17,14 @@ snd-page-alloc-$(CONFIG_HAS_DMA) += sgbuf.o
17 17
18snd-rawmidi-objs := rawmidi.o 18snd-rawmidi-objs := rawmidi.o
19snd-timer-objs := timer.o 19snd-timer-objs := timer.o
20snd-hrtimer-objs := hrtimer.o
20snd-rtctimer-objs := rtctimer.o 21snd-rtctimer-objs := rtctimer.o
21snd-hwdep-objs := hwdep.o 22snd-hwdep-objs := hwdep.o
22 23
23obj-$(CONFIG_SND) += snd.o 24obj-$(CONFIG_SND) += snd.o
24obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o 25obj-$(CONFIG_SND_HWDEP) += snd-hwdep.o
25obj-$(CONFIG_SND_TIMER) += snd-timer.o 26obj-$(CONFIG_SND_TIMER) += snd-timer.o
27obj-$(CONFIG_SND_HRTIMER) += snd-hrtimer.o
26obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o 28obj-$(CONFIG_SND_RTCTIMER) += snd-rtctimer.o
27obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o 29obj-$(CONFIG_SND_PCM) += snd-pcm.o snd-page-alloc.o
28obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o 30obj-$(CONFIG_SND_RAWMIDI) += snd-rawmidi.o
diff --git a/sound/core/device.c b/sound/core/device.c
index c58d8227254c..a67dfac08c03 100644
--- a/sound/core/device.c
+++ b/sound/core/device.c
@@ -98,7 +98,7 @@ int snd_device_free(struct snd_card *card, void *device_data)
98 kfree(dev); 98 kfree(dev);
99 return 0; 99 return 0;
100 } 100 }
101 snd_printd("device free %p (from %p), not found\n", device_data, 101 snd_printd("device free %p (from %pF), not found\n", device_data,
102 __builtin_return_address(0)); 102 __builtin_return_address(0));
103 return -ENXIO; 103 return -ENXIO;
104} 104}
@@ -135,7 +135,7 @@ int snd_device_disconnect(struct snd_card *card, void *device_data)
135 } 135 }
136 return 0; 136 return 0;
137 } 137 }
138 snd_printd("device disconnect %p (from %p), not found\n", device_data, 138 snd_printd("device disconnect %p (from %pF), not found\n", device_data,
139 __builtin_return_address(0)); 139 __builtin_return_address(0));
140 return -ENXIO; 140 return -ENXIO;
141} 141}
diff --git a/sound/core/hrtimer.c b/sound/core/hrtimer.c
new file mode 100644
index 000000000000..c1d285921f80
--- /dev/null
+++ b/sound/core/hrtimer.c
@@ -0,0 +1,155 @@
1/*
2 * ALSA timer back-end using hrtimer
3 * Copyright (C) 2008 Takashi Iwai
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 */
20
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/hrtimer.h>
25#include <sound/core.h>
26#include <sound/timer.h>
27
28MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
29MODULE_DESCRIPTION("ALSA hrtimer backend");
30MODULE_LICENSE("GPL");
31
32MODULE_ALIAS("snd-timer-" __stringify(SNDRV_TIMER_GLOBAL_HRTIMER));
33
34#define NANO_SEC 1000000000UL /* 10^9 in sec */
35static unsigned int resolution;
36
37struct snd_hrtimer {
38 struct snd_timer *timer;
39 struct hrtimer hrt;
40};
41
42static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt)
43{
44 struct snd_hrtimer *stime = container_of(hrt, struct snd_hrtimer, hrt);
45 struct snd_timer *t = stime->timer;
46 hrtimer_forward_now(hrt, ns_to_ktime(t->sticks * resolution));
47 snd_timer_interrupt(stime->timer, t->sticks);
48 return HRTIMER_RESTART;
49}
50
51static int snd_hrtimer_open(struct snd_timer *t)
52{
53 struct snd_hrtimer *stime;
54
55 stime = kmalloc(sizeof(*stime), GFP_KERNEL);
56 if (!stime)
57 return -ENOMEM;
58 hrtimer_init(&stime->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
59 stime->timer = t;
60 stime->hrt.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
61 stime->hrt.function = snd_hrtimer_callback;
62 t->private_data = stime;
63 return 0;
64}
65
66static int snd_hrtimer_close(struct snd_timer *t)
67{
68 struct snd_hrtimer *stime = t->private_data;
69
70 if (stime) {
71 hrtimer_cancel(&stime->hrt);
72 kfree(stime);
73 t->private_data = NULL;
74 }
75 return 0;
76}
77
78static int snd_hrtimer_start(struct snd_timer *t)
79{
80 struct snd_hrtimer *stime = t->private_data;
81
82 hrtimer_start(&stime->hrt, ns_to_ktime(t->sticks * resolution),
83 HRTIMER_MODE_REL);
84 return 0;
85}
86
87static int snd_hrtimer_stop(struct snd_timer *t)
88{
89 struct snd_hrtimer *stime = t->private_data;
90
91 hrtimer_cancel(&stime->hrt);
92 return 0;
93}
94
95static struct snd_timer_hardware hrtimer_hw = {
96 .flags = SNDRV_TIMER_HW_AUTO,
97 .open = snd_hrtimer_open,
98 .close = snd_hrtimer_close,
99 .start = snd_hrtimer_start,
100 .stop = snd_hrtimer_stop,
101};
102
103/*
104 * entry functions
105 */
106
107static struct snd_timer *mytimer;
108
109static int __init snd_hrtimer_init(void)
110{
111 struct snd_timer *timer;
112 struct timespec tp;
113 int err;
114
115 hrtimer_get_res(CLOCK_MONOTONIC, &tp);
116 if (tp.tv_sec > 0 || !tp.tv_nsec) {
117 snd_printk(KERN_ERR
118 "snd-hrtimer: Invalid resolution %u.%09u",
119 (unsigned)tp.tv_sec, (unsigned)tp.tv_nsec);
120 return -EINVAL;
121 }
122 resolution = tp.tv_nsec;
123
124 /* Create a new timer and set up the fields */
125 err = snd_timer_global_new("hrtimer", SNDRV_TIMER_GLOBAL_HRTIMER,
126 &timer);
127 if (err < 0)
128 return err;
129
130 timer->module = THIS_MODULE;
131 strcpy(timer->name, "HR timer");
132 timer->hw = hrtimer_hw;
133 timer->hw.resolution = resolution;
134 timer->hw.ticks = NANO_SEC / resolution;
135
136 err = snd_timer_global_register(timer);
137 if (err < 0) {
138 snd_timer_global_free(timer);
139 return err;
140 }
141 mytimer = timer; /* remember this */
142
143 return 0;
144}
145
146static void __exit snd_hrtimer_exit(void)
147{
148 if (mytimer) {
149 snd_timer_global_free(mytimer);
150 mytimer = NULL;
151 }
152}
153
154module_init(snd_hrtimer_init);
155module_exit(snd_hrtimer_exit);
diff --git a/sound/core/info.c b/sound/core/info.c
index 527b207462b0..70fa87189f36 100644
--- a/sound/core/info.c
+++ b/sound/core/info.c
@@ -653,6 +653,23 @@ int snd_info_card_register(struct snd_card *card)
653} 653}
654 654
655/* 655/*
656 * called on card->id change
657 */
658void snd_info_card_id_change(struct snd_card *card)
659{
660 mutex_lock(&info_mutex);
661 if (card->proc_root_link) {
662 snd_remove_proc_entry(snd_proc_root, card->proc_root_link);
663 card->proc_root_link = NULL;
664 }
665 if (strcmp(card->id, card->proc_root->name))
666 card->proc_root_link = proc_symlink(card->id,
667 snd_proc_root,
668 card->proc_root->name);
669 mutex_unlock(&info_mutex);
670}
671
672/*
656 * de-register the card proc file 673 * de-register the card proc file
657 * called from init.c 674 * called from init.c
658 */ 675 */
diff --git a/sound/core/init.c b/sound/core/init.c
index b47ff8b44be8..0d5520c415d3 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -533,6 +533,65 @@ static void choose_default_id(struct snd_card *card)
533 } 533 }
534} 534}
535 535
536#ifndef CONFIG_SYSFS_DEPRECATED
537static ssize_t
538card_id_show_attr(struct device *dev,
539 struct device_attribute *attr, char *buf)
540{
541 struct snd_card *card = dev_get_drvdata(dev);
542 return snprintf(buf, PAGE_SIZE, "%s\n", card ? card->id : "(null)");
543}
544
545static ssize_t
546card_id_store_attr(struct device *dev, struct device_attribute *attr,
547 const char *buf, size_t count)
548{
549 struct snd_card *card = dev_get_drvdata(dev);
550 char buf1[sizeof(card->id)];
551 size_t copy = count > sizeof(card->id) - 1 ?
552 sizeof(card->id) - 1 : count;
553 size_t idx;
554 int c;
555
556 for (idx = 0; idx < copy; idx++) {
557 c = buf[idx];
558 if (!isalnum(c) && c != '_' && c != '-')
559 return -EINVAL;
560 }
561 memcpy(buf1, buf, copy);
562 buf1[copy] = '\0';
563 mutex_lock(&snd_card_mutex);
564 if (!snd_info_check_reserved_words(buf1)) {
565 __exist:
566 mutex_unlock(&snd_card_mutex);
567 return -EEXIST;
568 }
569 for (idx = 0; idx < snd_ecards_limit; idx++) {
570 if (snd_cards[idx] && !strcmp(snd_cards[idx]->id, buf1))
571 goto __exist;
572 }
573 strcpy(card->id, buf1);
574 snd_info_card_id_change(card);
575 mutex_unlock(&snd_card_mutex);
576
577 return count;
578}
579
580static struct device_attribute card_id_attrs =
581 __ATTR(id, S_IRUGO | S_IWUSR, card_id_show_attr, card_id_store_attr);
582
583static ssize_t
584card_number_show_attr(struct device *dev,
585 struct device_attribute *attr, char *buf)
586{
587 struct snd_card *card = dev_get_drvdata(dev);
588 return snprintf(buf, PAGE_SIZE, "%i\n", card ? card->number : -1);
589}
590
591static struct device_attribute card_number_attrs =
592 __ATTR(number, S_IRUGO, card_number_show_attr, NULL);
593#endif /* CONFIG_SYSFS_DEPRECATED */
594
536/** 595/**
537 * snd_card_register - register the soundcard 596 * snd_card_register - register the soundcard
538 * @card: soundcard structure 597 * @card: soundcard structure
@@ -553,7 +612,7 @@ int snd_card_register(struct snd_card *card)
553#ifndef CONFIG_SYSFS_DEPRECATED 612#ifndef CONFIG_SYSFS_DEPRECATED
554 if (!card->card_dev) { 613 if (!card->card_dev) {
555 card->card_dev = device_create(sound_class, card->dev, 614 card->card_dev = device_create(sound_class, card->dev,
556 MKDEV(0, 0), NULL, 615 MKDEV(0, 0), card,
557 "card%i", card->number); 616 "card%i", card->number);
558 if (IS_ERR(card->card_dev)) 617 if (IS_ERR(card->card_dev))
559 card->card_dev = NULL; 618 card->card_dev = NULL;
@@ -576,6 +635,16 @@ int snd_card_register(struct snd_card *card)
576 if (snd_mixer_oss_notify_callback) 635 if (snd_mixer_oss_notify_callback)
577 snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER); 636 snd_mixer_oss_notify_callback(card, SND_MIXER_OSS_NOTIFY_REGISTER);
578#endif 637#endif
638#ifndef CONFIG_SYSFS_DEPRECATED
639 if (card->card_dev) {
640 err = device_create_file(card->card_dev, &card_id_attrs);
641 if (err < 0)
642 return err;
643 err = device_create_file(card->card_dev, &card_number_attrs);
644 if (err < 0)
645 return err;
646 }
647#endif
579 return 0; 648 return 0;
580} 649}
581 650
diff --git a/sound/core/jack.c b/sound/core/jack.c
index bd2d9e6b55e9..dd4a12dc09aa 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -34,6 +34,7 @@ static int snd_jack_dev_free(struct snd_device *device)
34 else 34 else
35 input_free_device(jack->input_dev); 35 input_free_device(jack->input_dev);
36 36
37 kfree(jack->id);
37 kfree(jack); 38 kfree(jack);
38 39
39 return 0; 40 return 0;
@@ -87,7 +88,7 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
87 if (jack == NULL) 88 if (jack == NULL)
88 return -ENOMEM; 89 return -ENOMEM;
89 90
90 jack->id = id; 91 jack->id = kstrdup(id, GFP_KERNEL);
91 92
92 jack->input_dev = input_allocate_device(); 93 jack->input_dev = input_allocate_device();
93 if (jack->input_dev == NULL) { 94 if (jack->input_dev == NULL) {
@@ -102,9 +103,15 @@ int snd_jack_new(struct snd_card *card, const char *id, int type,
102 if (type & SND_JACK_HEADPHONE) 103 if (type & SND_JACK_HEADPHONE)
103 input_set_capability(jack->input_dev, EV_SW, 104 input_set_capability(jack->input_dev, EV_SW,
104 SW_HEADPHONE_INSERT); 105 SW_HEADPHONE_INSERT);
106 if (type & SND_JACK_LINEOUT)
107 input_set_capability(jack->input_dev, EV_SW,
108 SW_LINEOUT_INSERT);
105 if (type & SND_JACK_MICROPHONE) 109 if (type & SND_JACK_MICROPHONE)
106 input_set_capability(jack->input_dev, EV_SW, 110 input_set_capability(jack->input_dev, EV_SW,
107 SW_MICROPHONE_INSERT); 111 SW_MICROPHONE_INSERT);
112 if (type & SND_JACK_MECHANICAL)
113 input_set_capability(jack->input_dev, EV_SW,
114 SW_JACK_PHYSICAL_INSERT);
108 115
109 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops); 116 err = snd_device_new(card, SNDRV_DEV_JACK, jack, &ops);
110 if (err < 0) 117 if (err < 0)
@@ -153,9 +160,15 @@ void snd_jack_report(struct snd_jack *jack, int status)
153 if (jack->type & SND_JACK_HEADPHONE) 160 if (jack->type & SND_JACK_HEADPHONE)
154 input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT, 161 input_report_switch(jack->input_dev, SW_HEADPHONE_INSERT,
155 status & SND_JACK_HEADPHONE); 162 status & SND_JACK_HEADPHONE);
163 if (jack->type & SND_JACK_LINEOUT)
164 input_report_switch(jack->input_dev, SW_LINEOUT_INSERT,
165 status & SND_JACK_LINEOUT);
156 if (jack->type & SND_JACK_MICROPHONE) 166 if (jack->type & SND_JACK_MICROPHONE)
157 input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT, 167 input_report_switch(jack->input_dev, SW_MICROPHONE_INSERT,
158 status & SND_JACK_MICROPHONE); 168 status & SND_JACK_MICROPHONE);
169 if (jack->type & SND_JACK_MECHANICAL)
170 input_report_switch(jack->input_dev, SW_JACK_PHYSICAL_INSERT,
171 status & SND_JACK_MECHANICAL);
159 172
160 input_sync(jack->input_dev); 173 input_sync(jack->input_dev);
161} 174}
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 39672f68ce5d..002777ba336a 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -151,7 +151,7 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs
151 if (!substream->opened) 151 if (!substream->opened)
152 return; 152 return;
153 if (up) { 153 if (up) {
154 tasklet_hi_schedule(&substream->runtime->tasklet); 154 tasklet_schedule(&substream->runtime->tasklet);
155 } else { 155 } else {
156 tasklet_kill(&substream->runtime->tasklet); 156 tasklet_kill(&substream->runtime->tasklet);
157 substream->ops->trigger(substream, 0); 157 substream->ops->trigger(substream, 0);
@@ -908,7 +908,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
908 } 908 }
909 if (result > 0) { 909 if (result > 0) {
910 if (runtime->event) 910 if (runtime->event)
911 tasklet_hi_schedule(&runtime->tasklet); 911 tasklet_schedule(&runtime->tasklet);
912 else if (snd_rawmidi_ready(substream)) 912 else if (snd_rawmidi_ready(substream))
913 wake_up(&runtime->sleep); 913 wake_up(&runtime->sleep);
914 } 914 }
diff --git a/sound/core/rtctimer.c b/sound/core/rtctimer.c
index 51e64e30dd3b..0851cd13e303 100644
--- a/sound/core/rtctimer.c
+++ b/sound/core/rtctimer.c
@@ -118,7 +118,7 @@ static void rtctimer_tasklet(unsigned long data)
118 */ 118 */
119static void rtctimer_interrupt(void *private_data) 119static void rtctimer_interrupt(void *private_data)
120{ 120{
121 tasklet_hi_schedule(private_data); 121 tasklet_schedule(private_data);
122} 122}
123 123
124 124
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index ee0f8405ab35..bf09a5ad1865 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -43,7 +43,9 @@ int seq_default_timer_class = SNDRV_TIMER_CLASS_GLOBAL;
43int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE; 43int seq_default_timer_sclass = SNDRV_TIMER_SCLASS_NONE;
44int seq_default_timer_card = -1; 44int seq_default_timer_card = -1;
45int seq_default_timer_device = 45int seq_default_timer_device =
46#ifdef CONFIG_SND_SEQ_RTCTIMER_DEFAULT 46#ifdef CONFIG_SND_SEQ_HRTIMER_DEFAULT
47 SNDRV_TIMER_GLOBAL_HRTIMER
48#elif defined(CONFIG_SND_SEQ_RTCTIMER_DEFAULT)
47 SNDRV_TIMER_GLOBAL_RTC 49 SNDRV_TIMER_GLOBAL_RTC
48#else 50#else
49 SNDRV_TIMER_GLOBAL_SYSTEM 51 SNDRV_TIMER_GLOBAL_SYSTEM
diff --git a/sound/core/timer.c b/sound/core/timer.c
index c584408c9f17..796532081e81 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -743,7 +743,7 @@ void snd_timer_interrupt(struct snd_timer * timer, unsigned long ticks_left)
743 spin_unlock_irqrestore(&timer->lock, flags); 743 spin_unlock_irqrestore(&timer->lock, flags);
744 744
745 if (use_tasklet) 745 if (use_tasklet)
746 tasklet_hi_schedule(&timer->task_queue); 746 tasklet_schedule(&timer->task_queue);
747} 747}
748 748
749/* 749/*
diff --git a/sound/drivers/Kconfig b/sound/drivers/Kconfig
index 255fd18b9aec..0bcf14640fde 100644
--- a/sound/drivers/Kconfig
+++ b/sound/drivers/Kconfig
@@ -163,7 +163,7 @@ config SND_ML403_AC97CR
163 163
164config SND_AC97_POWER_SAVE 164config SND_AC97_POWER_SAVE
165 bool "AC97 Power-Saving Mode" 165 bool "AC97 Power-Saving Mode"
166 depends on SND_AC97_CODEC && EXPERIMENTAL 166 depends on SND_AC97_CODEC
167 default n 167 default n
168 help 168 help
169 Say Y here to enable the aggressive power-saving support of 169 Say Y here to enable the aggressive power-saving support of
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 1899cf0685bc..2a02f704f366 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -96,7 +96,7 @@ static int __devinit snd_card_pcsp_probe(int devnum, struct device *dev)
96 return -EINVAL; 96 return -EINVAL;
97 97
98 hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 98 hrtimer_init(&pcsp_chip.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
99 pcsp_chip.timer.cb_mode = HRTIMER_CB_SOFTIRQ; 99 pcsp_chip.timer.cb_mode = HRTIMER_CB_IRQSAFE_UNLOCKED;
100 pcsp_chip.timer.function = pcsp_do_timer; 100 pcsp_chip.timer.function = pcsp_do_timer;
101 101
102 card = snd_card_new(index, id, THIS_MODULE, 0); 102 card = snd_card_new(index, id, THIS_MODULE, 0);
@@ -188,10 +188,8 @@ static int __devexit pcsp_remove(struct platform_device *dev)
188 188
189static void pcsp_stop_beep(struct snd_pcsp *chip) 189static void pcsp_stop_beep(struct snd_pcsp *chip)
190{ 190{
191 spin_lock_irq(&chip->substream_lock); 191 pcsp_sync_stop(chip);
192 if (!chip->playback_substream) 192 pcspkr_stop_sound();
193 pcspkr_stop_sound();
194 spin_unlock_irq(&chip->substream_lock);
195} 193}
196 194
197#ifdef CONFIG_PM 195#ifdef CONFIG_PM
diff --git a/sound/drivers/pcsp/pcsp.h b/sound/drivers/pcsp/pcsp.h
index 1d661f795e8c..cdef2664218f 100644
--- a/sound/drivers/pcsp/pcsp.h
+++ b/sound/drivers/pcsp/pcsp.h
@@ -62,6 +62,8 @@ struct snd_pcsp {
62 unsigned short port, irq, dma; 62 unsigned short port, irq, dma;
63 spinlock_t substream_lock; 63 spinlock_t substream_lock;
64 struct snd_pcm_substream *playback_substream; 64 struct snd_pcm_substream *playback_substream;
65 unsigned int fmt_size;
66 unsigned int is_signed;
65 size_t playback_ptr; 67 size_t playback_ptr;
66 size_t period_ptr; 68 size_t period_ptr;
67 atomic_t timer_active; 69 atomic_t timer_active;
@@ -77,6 +79,7 @@ struct snd_pcsp {
77extern struct snd_pcsp pcsp_chip; 79extern struct snd_pcsp pcsp_chip;
78 80
79extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle); 81extern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle);
82extern void pcsp_sync_stop(struct snd_pcsp *chip);
80 83
81extern int snd_pcsp_new_pcm(struct snd_pcsp *chip); 84extern int snd_pcsp_new_pcm(struct snd_pcsp *chip);
82extern int snd_pcsp_new_mixer(struct snd_pcsp *chip); 85extern int snd_pcsp_new_mixer(struct snd_pcsp *chip);
diff --git a/sound/drivers/pcsp/pcsp_lib.c b/sound/drivers/pcsp/pcsp_lib.c
index 1f42e4063118..84cc2658c05b 100644
--- a/sound/drivers/pcsp/pcsp_lib.c
+++ b/sound/drivers/pcsp/pcsp_lib.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/moduleparam.h> 10#include <linux/moduleparam.h>
11#include <linux/interrupt.h>
11#include <sound/pcm.h> 12#include <sound/pcm.h>
12#include <asm/io.h> 13#include <asm/io.h>
13#include "pcsp.h" 14#include "pcsp.h"
@@ -19,61 +20,57 @@ MODULE_PARM_DESC(nforce_wa, "Apply NForce chipset workaround "
19 20
20#define DMIX_WANTS_S16 1 21#define DMIX_WANTS_S16 1
21 22
22enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle) 23/*
24 * Call snd_pcm_period_elapsed in a tasklet
25 * This avoids spinlock messes and long-running irq contexts
26 */
27static void pcsp_call_pcm_elapsed(unsigned long priv)
28{
29 if (atomic_read(&pcsp_chip.timer_active)) {
30 struct snd_pcm_substream *substream;
31 substream = pcsp_chip.playback_substream;
32 if (substream)
33 snd_pcm_period_elapsed(substream);
34 }
35}
36
37static DECLARE_TASKLET(pcsp_pcm_tasklet, pcsp_call_pcm_elapsed, 0);
38
39/* write the port and returns the next expire time in ns;
40 * called at the trigger-start and in hrtimer callback
41 */
42static unsigned long pcsp_timer_update(struct hrtimer *handle)
23{ 43{
24 unsigned char timer_cnt, val; 44 unsigned char timer_cnt, val;
25 int fmt_size, periods_elapsed;
26 u64 ns; 45 u64 ns;
27 size_t period_bytes, buffer_bytes;
28 struct snd_pcm_substream *substream; 46 struct snd_pcm_substream *substream;
29 struct snd_pcm_runtime *runtime; 47 struct snd_pcm_runtime *runtime;
30 struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer); 48 struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
49 unsigned long flags;
31 50
32 if (chip->thalf) { 51 if (chip->thalf) {
33 outb(chip->val61, 0x61); 52 outb(chip->val61, 0x61);
34 chip->thalf = 0; 53 chip->thalf = 0;
35 if (!atomic_read(&chip->timer_active)) 54 if (!atomic_read(&chip->timer_active))
36 return HRTIMER_NORESTART; 55 return 0;
37 hrtimer_forward(&chip->timer, hrtimer_get_expires(&chip->timer), 56 return chip->ns_rem;
38 ktime_set(0, chip->ns_rem));
39 return HRTIMER_RESTART;
40 } 57 }
41 58
42 spin_lock_irq(&chip->substream_lock);
43 /* Takashi Iwai says regarding this extra lock:
44
45 If the irq handler handles some data on the DMA buffer, it should
46 do snd_pcm_stream_lock().
47 That protects basically against all races among PCM callbacks, yes.
48 However, there are two remaining issues:
49 1. The substream pointer you try to lock isn't protected _before_
50 this lock yet.
51 2. snd_pcm_period_elapsed() itself acquires the lock.
52 The requirement of another lock is because of 1. When you get
53 chip->playback_substream, it's not protected.
54 Keeping this lock while snd_pcm_period_elapsed() assures the substream
55 is still protected (at least, not released). And the other status is
56 handled properly inside snd_pcm_stream_lock() in
57 snd_pcm_period_elapsed().
58
59 */
60 if (!chip->playback_substream)
61 goto exit_nr_unlock1;
62 substream = chip->playback_substream;
63 snd_pcm_stream_lock(substream);
64 if (!atomic_read(&chip->timer_active)) 59 if (!atomic_read(&chip->timer_active))
65 goto exit_nr_unlock2; 60 return 0;
61 substream = chip->playback_substream;
62 if (!substream)
63 return 0;
66 64
67 runtime = substream->runtime; 65 runtime = substream->runtime;
68 fmt_size = snd_pcm_format_physical_width(runtime->format) >> 3;
69 /* assume it is mono! */ 66 /* assume it is mono! */
70 val = runtime->dma_area[chip->playback_ptr + fmt_size - 1]; 67 val = runtime->dma_area[chip->playback_ptr + chip->fmt_size - 1];
71 if (snd_pcm_format_signed(runtime->format)) 68 if (chip->is_signed)
72 val ^= 0x80; 69 val ^= 0x80;
73 timer_cnt = val * CUR_DIV() / 256; 70 timer_cnt = val * CUR_DIV() / 256;
74 71
75 if (timer_cnt && chip->enable) { 72 if (timer_cnt && chip->enable) {
76 spin_lock(&i8253_lock); 73 spin_lock_irqsave(&i8253_lock, flags);
77 if (!nforce_wa) { 74 if (!nforce_wa) {
78 outb_p(chip->val61, 0x61); 75 outb_p(chip->val61, 0x61);
79 outb_p(timer_cnt, 0x42); 76 outb_p(timer_cnt, 0x42);
@@ -82,12 +79,39 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
82 outb(chip->val61 ^ 2, 0x61); 79 outb(chip->val61 ^ 2, 0x61);
83 chip->thalf = 1; 80 chip->thalf = 1;
84 } 81 }
85 spin_unlock(&i8253_lock); 82 spin_unlock_irqrestore(&i8253_lock, flags);
86 } 83 }
87 84
85 chip->ns_rem = PCSP_PERIOD_NS();
86 ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
87 chip->ns_rem -= ns;
88 return ns;
89}
90
91enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
92{
93 struct snd_pcsp *chip = container_of(handle, struct snd_pcsp, timer);
94 struct snd_pcm_substream *substream;
95 int periods_elapsed, pointer_update;
96 size_t period_bytes, buffer_bytes;
97 unsigned long ns;
98 unsigned long flags;
99
100 pointer_update = !chip->thalf;
101 ns = pcsp_timer_update(handle);
102 if (!ns)
103 return HRTIMER_NORESTART;
104
105 /* update the playback position */
106 substream = chip->playback_substream;
107 if (!substream)
108 return HRTIMER_NORESTART;
109
88 period_bytes = snd_pcm_lib_period_bytes(substream); 110 period_bytes = snd_pcm_lib_period_bytes(substream);
89 buffer_bytes = snd_pcm_lib_buffer_bytes(substream); 111 buffer_bytes = snd_pcm_lib_buffer_bytes(substream);
90 chip->playback_ptr += PCSP_INDEX_INC() * fmt_size; 112
113 spin_lock_irqsave(&chip->substream_lock, flags);
114 chip->playback_ptr += PCSP_INDEX_INC() * chip->fmt_size;
91 periods_elapsed = chip->playback_ptr - chip->period_ptr; 115 periods_elapsed = chip->playback_ptr - chip->period_ptr;
92 if (periods_elapsed < 0) { 116 if (periods_elapsed < 0) {
93#if PCSP_DEBUG 117#if PCSP_DEBUG
@@ -102,41 +126,30 @@ enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle)
102 * or ALSA will BUG on us. */ 126 * or ALSA will BUG on us. */
103 chip->playback_ptr %= buffer_bytes; 127 chip->playback_ptr %= buffer_bytes;
104 128
105 snd_pcm_stream_unlock(substream);
106
107 if (periods_elapsed) { 129 if (periods_elapsed) {
108 snd_pcm_period_elapsed(substream);
109 chip->period_ptr += periods_elapsed * period_bytes; 130 chip->period_ptr += periods_elapsed * period_bytes;
110 chip->period_ptr %= buffer_bytes; 131 chip->period_ptr %= buffer_bytes;
111 } 132 }
133 spin_unlock_irqrestore(&chip->substream_lock, flags);
112 134
113 spin_unlock_irq(&chip->substream_lock); 135 if (periods_elapsed)
136 tasklet_schedule(&pcsp_pcm_tasklet);
114 137
115 if (!atomic_read(&chip->timer_active)) 138 hrtimer_forward(handle, hrtimer_get_expires(handle), ns_to_ktime(ns));
116 return HRTIMER_NORESTART;
117 139
118 chip->ns_rem = PCSP_PERIOD_NS();
119 ns = (chip->thalf ? PCSP_CALC_NS(timer_cnt) : chip->ns_rem);
120 chip->ns_rem -= ns;
121 hrtimer_forward(&chip->timer, hrtimer_get_expires(&chip->timer),
122 ktime_set(0, ns));
123 return HRTIMER_RESTART; 140 return HRTIMER_RESTART;
124
125exit_nr_unlock2:
126 snd_pcm_stream_unlock(substream);
127exit_nr_unlock1:
128 spin_unlock_irq(&chip->substream_lock);
129 return HRTIMER_NORESTART;
130} 141}
131 142
132static void pcsp_start_playing(struct snd_pcsp *chip) 143static int pcsp_start_playing(struct snd_pcsp *chip)
133{ 144{
145 unsigned long ns;
146
134#if PCSP_DEBUG 147#if PCSP_DEBUG
135 printk(KERN_INFO "PCSP: start_playing called\n"); 148 printk(KERN_INFO "PCSP: start_playing called\n");
136#endif 149#endif
137 if (atomic_read(&chip->timer_active)) { 150 if (atomic_read(&chip->timer_active)) {
138 printk(KERN_ERR "PCSP: Timer already active\n"); 151 printk(KERN_ERR "PCSP: Timer already active\n");
139 return; 152 return -EIO;
140 } 153 }
141 154
142 spin_lock(&i8253_lock); 155 spin_lock(&i8253_lock);
@@ -146,7 +159,12 @@ static void pcsp_start_playing(struct snd_pcsp *chip)
146 atomic_set(&chip->timer_active, 1); 159 atomic_set(&chip->timer_active, 1);
147 chip->thalf = 0; 160 chip->thalf = 0;
148 161
149 hrtimer_start(&pcsp_chip.timer, ktime_set(0, 0), HRTIMER_MODE_REL); 162 ns = pcsp_timer_update(&pcsp_chip.timer);
163 if (!ns)
164 return -EIO;
165
166 hrtimer_start(&pcsp_chip.timer, ktime_set(0, ns), HRTIMER_MODE_REL);
167 return 0;
150} 168}
151 169
152static void pcsp_stop_playing(struct snd_pcsp *chip) 170static void pcsp_stop_playing(struct snd_pcsp *chip)
@@ -165,26 +183,35 @@ static void pcsp_stop_playing(struct snd_pcsp *chip)
165 spin_unlock(&i8253_lock); 183 spin_unlock(&i8253_lock);
166} 184}
167 185
186/*
187 * Force to stop and sync the stream
188 */
189void pcsp_sync_stop(struct snd_pcsp *chip)
190{
191 local_irq_disable();
192 pcsp_stop_playing(chip);
193 local_irq_enable();
194 hrtimer_cancel(&chip->timer);
195 tasklet_kill(&pcsp_pcm_tasklet);
196}
197
168static int snd_pcsp_playback_close(struct snd_pcm_substream *substream) 198static int snd_pcsp_playback_close(struct snd_pcm_substream *substream)
169{ 199{
170 struct snd_pcsp *chip = snd_pcm_substream_chip(substream); 200 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
171#if PCSP_DEBUG 201#if PCSP_DEBUG
172 printk(KERN_INFO "PCSP: close called\n"); 202 printk(KERN_INFO "PCSP: close called\n");
173#endif 203#endif
174 if (atomic_read(&chip->timer_active)) { 204 pcsp_sync_stop(chip);
175 printk(KERN_ERR "PCSP: timer still active\n");
176 pcsp_stop_playing(chip);
177 }
178 spin_lock_irq(&chip->substream_lock);
179 chip->playback_substream = NULL; 205 chip->playback_substream = NULL;
180 spin_unlock_irq(&chip->substream_lock);
181 return 0; 206 return 0;
182} 207}
183 208
184static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream, 209static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
185 struct snd_pcm_hw_params *hw_params) 210 struct snd_pcm_hw_params *hw_params)
186{ 211{
212 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
187 int err; 213 int err;
214 pcsp_sync_stop(chip);
188 err = snd_pcm_lib_malloc_pages(substream, 215 err = snd_pcm_lib_malloc_pages(substream,
189 params_buffer_bytes(hw_params)); 216 params_buffer_bytes(hw_params));
190 if (err < 0) 217 if (err < 0)
@@ -194,9 +221,11 @@ static int snd_pcsp_playback_hw_params(struct snd_pcm_substream *substream,
194 221
195static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream) 222static int snd_pcsp_playback_hw_free(struct snd_pcm_substream *substream)
196{ 223{
224 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
197#if PCSP_DEBUG 225#if PCSP_DEBUG
198 printk(KERN_INFO "PCSP: hw_free called\n"); 226 printk(KERN_INFO "PCSP: hw_free called\n");
199#endif 227#endif
228 pcsp_sync_stop(chip);
200 return snd_pcm_lib_free_pages(substream); 229 return snd_pcm_lib_free_pages(substream);
201} 230}
202 231
@@ -212,8 +241,12 @@ static int snd_pcsp_playback_prepare(struct snd_pcm_substream *substream)
212 snd_pcm_lib_period_bytes(substream), 241 snd_pcm_lib_period_bytes(substream),
213 substream->runtime->periods); 242 substream->runtime->periods);
214#endif 243#endif
244 pcsp_sync_stop(chip);
215 chip->playback_ptr = 0; 245 chip->playback_ptr = 0;
216 chip->period_ptr = 0; 246 chip->period_ptr = 0;
247 chip->fmt_size =
248 snd_pcm_format_physical_width(substream->runtime->format) >> 3;
249 chip->is_signed = snd_pcm_format_signed(substream->runtime->format);
217 return 0; 250 return 0;
218} 251}
219 252
@@ -226,8 +259,7 @@ static int snd_pcsp_trigger(struct snd_pcm_substream *substream, int cmd)
226 switch (cmd) { 259 switch (cmd) {
227 case SNDRV_PCM_TRIGGER_START: 260 case SNDRV_PCM_TRIGGER_START:
228 case SNDRV_PCM_TRIGGER_RESUME: 261 case SNDRV_PCM_TRIGGER_RESUME:
229 pcsp_start_playing(chip); 262 return pcsp_start_playing(chip);
230 break;
231 case SNDRV_PCM_TRIGGER_STOP: 263 case SNDRV_PCM_TRIGGER_STOP:
232 case SNDRV_PCM_TRIGGER_SUSPEND: 264 case SNDRV_PCM_TRIGGER_SUSPEND:
233 pcsp_stop_playing(chip); 265 pcsp_stop_playing(chip);
@@ -242,7 +274,11 @@ static snd_pcm_uframes_t snd_pcsp_playback_pointer(struct snd_pcm_substream
242 *substream) 274 *substream)
243{ 275{
244 struct snd_pcsp *chip = snd_pcm_substream_chip(substream); 276 struct snd_pcsp *chip = snd_pcm_substream_chip(substream);
245 return bytes_to_frames(substream->runtime, chip->playback_ptr); 277 unsigned int pos;
278 spin_lock(&chip->substream_lock);
279 pos = chip->playback_ptr;
280 spin_unlock(&chip->substream_lock);
281 return bytes_to_frames(substream->runtime, pos);
246} 282}
247 283
248static struct snd_pcm_hardware snd_pcsp_playback = { 284static struct snd_pcm_hardware snd_pcsp_playback = {
@@ -279,9 +315,7 @@ static int snd_pcsp_playback_open(struct snd_pcm_substream *substream)
279 return -EBUSY; 315 return -EBUSY;
280 } 316 }
281 runtime->hw = snd_pcsp_playback; 317 runtime->hw = snd_pcsp_playback;
282 spin_lock_irq(&chip->substream_lock);
283 chip->playback_substream = substream; 318 chip->playback_substream = substream;
284 spin_unlock_irq(&chip->substream_lock);
285 return 0; 319 return 0;
286} 320}
287 321
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index 473b07f6ae85..14e3354be43a 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -548,7 +548,7 @@ irqreturn_t snd_vx_irq_handler(int irq, void *dev)
548 (chip->chip_status & VX_STAT_IS_STALE)) 548 (chip->chip_status & VX_STAT_IS_STALE))
549 return IRQ_NONE; 549 return IRQ_NONE;
550 if (! vx_test_and_ack(chip)) 550 if (! vx_test_and_ack(chip))
551 tasklet_hi_schedule(&chip->tq); 551 tasklet_schedule(&chip->tq);
552 return IRQ_HANDLED; 552 return IRQ_HANDLED;
553} 553}
554 554
diff --git a/sound/drivers/vx/vx_pcm.c b/sound/drivers/vx/vx_pcm.c
index 27de574c08f7..6644d0034fba 100644
--- a/sound/drivers/vx/vx_pcm.c
+++ b/sound/drivers/vx/vx_pcm.c
@@ -823,7 +823,7 @@ static int vx_pcm_trigger(struct snd_pcm_substream *subs, int cmd)
823 * we trigger the pipe using tasklet, so that the interrupts are 823 * we trigger the pipe using tasklet, so that the interrupts are
824 * issued surely after the trigger is completed. 824 * issued surely after the trigger is completed.
825 */ 825 */
826 tasklet_hi_schedule(&pipe->start_tq); 826 tasklet_schedule(&pipe->start_tq);
827 chip->pcm_running++; 827 chip->pcm_running++;
828 pipe->running = 1; 828 pipe->running = 1;
829 break; 829 break;
diff --git a/sound/isa/sb/sb8.c b/sound/isa/sb/sb8.c
index 667eccc676a4..ea06877be4b1 100644
--- a/sound/isa/sb/sb8.c
+++ b/sound/isa/sb/sb8.c
@@ -140,8 +140,10 @@ static int __devinit snd_sb8_probe(struct device *pdev, unsigned int dev)
140 break; 140 break;
141 } 141 }
142 } 142 }
143 if (i >= ARRAY_SIZE(possible_ports)) 143 if (i >= ARRAY_SIZE(possible_ports)) {
144 err = -EINVAL;
144 goto _err; 145 goto _err;
146 }
145 } 147 }
146 acard->chip = chip; 148 acard->chip = chip;
147 149
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 7003711f4fcc..6e3a1848447c 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -208,7 +208,8 @@ config SND_OXYGEN
208 * AuzenTech X-Meridian 208 * AuzenTech X-Meridian
209 * Bgears b-Enspirer 209 * Bgears b-Enspirer
210 * Club3D Theatron DTS 210 * Club3D Theatron DTS
211 * HT-Omega Claro 211 * HT-Omega Claro (plus)
212 * HT-Omega Claro halo (XT)
212 * Razer Barracuda AC-1 213 * Razer Barracuda AC-1
213 * Sondigo Inferno 214 * Sondigo Inferno
214 215
@@ -497,129 +498,7 @@ config SND_FM801_TEA575X
497 depends on SND_FM801_TEA575X_BOOL 498 depends on SND_FM801_TEA575X_BOOL
498 default SND_FM801 499 default SND_FM801
499 500
500config SND_HDA_INTEL 501source "sound/pci/hda/Kconfig"
501 tristate "Intel HD Audio"
502 select SND_PCM
503 select SND_VMASTER
504 help
505 Say Y here to include support for Intel "High Definition
506 Audio" (Azalia) motherboard devices.
507
508 To compile this driver as a module, choose M here: the module
509 will be called snd-hda-intel.
510
511config SND_HDA_HWDEP
512 bool "Build hwdep interface for HD-audio driver"
513 depends on SND_HDA_INTEL
514 select SND_HWDEP
515 help
516 Say Y here to build a hwdep interface for HD-audio driver.
517 This interface can be used for out-of-band communication
518 with codecs for debugging purposes.
519
520config SND_HDA_INPUT_BEEP
521 bool "Support digital beep via input layer"
522 depends on SND_HDA_INTEL
523 depends on INPUT=y || INPUT=SND_HDA_INTEL
524 help
525 Say Y here to build a digital beep interface for HD-audio
526 driver. This interface is used to generate digital beeps.
527
528config SND_HDA_CODEC_REALTEK
529 bool "Build Realtek HD-audio codec support"
530 depends on SND_HDA_INTEL
531 default y
532 help
533 Say Y here to include Realtek HD-audio codec support in
534 snd-hda-intel driver, such as ALC880.
535
536config SND_HDA_CODEC_ANALOG
537 bool "Build Analog Device HD-audio codec support"
538 depends on SND_HDA_INTEL
539 default y
540 help
541 Say Y here to include Analog Device HD-audio codec support in
542 snd-hda-intel driver, such as AD1986A.
543
544config SND_HDA_CODEC_SIGMATEL
545 bool "Build IDT/Sigmatel HD-audio codec support"
546 depends on SND_HDA_INTEL
547 default y
548 help
549 Say Y here to include IDT (Sigmatel) HD-audio codec support in
550 snd-hda-intel driver, such as STAC9200.
551
552config SND_HDA_CODEC_VIA
553 bool "Build VIA HD-audio codec support"
554 depends on SND_HDA_INTEL
555 default y
556 help
557 Say Y here to include VIA HD-audio codec support in
558 snd-hda-intel driver, such as VT1708.
559
560config SND_HDA_CODEC_ATIHDMI
561 bool "Build ATI HDMI HD-audio codec support"
562 depends on SND_HDA_INTEL
563 default y
564 help
565 Say Y here to include ATI HDMI HD-audio codec support in
566 snd-hda-intel driver, such as ATI RS600 HDMI.
567
568config SND_HDA_CODEC_NVHDMI
569 bool "Build NVIDIA HDMI HD-audio codec support"
570 depends on SND_HDA_INTEL
571 default y
572 help
573 Say Y here to include NVIDIA HDMI HD-audio codec support in
574 snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
575
576config SND_HDA_CODEC_CONEXANT
577 bool "Build Conexant HD-audio codec support"
578 depends on SND_HDA_INTEL
579 default y
580 help
581 Say Y here to include Conexant HD-audio codec support in
582 snd-hda-intel driver, such as CX20549.
583
584config SND_HDA_CODEC_CMEDIA
585 bool "Build C-Media HD-audio codec support"
586 depends on SND_HDA_INTEL
587 default y
588 help
589 Say Y here to include C-Media HD-audio codec support in
590 snd-hda-intel driver, such as CMI9880.
591
592config SND_HDA_CODEC_SI3054
593 bool "Build Silicon Labs 3054 HD-modem codec support"
594 depends on SND_HDA_INTEL
595 default y
596 help
597 Say Y here to include Silicon Labs 3054 HD-modem codec
598 (and compatibles) support in snd-hda-intel driver.
599
600config SND_HDA_GENERIC
601 bool "Enable generic HD-audio codec parser"
602 depends on SND_HDA_INTEL
603 default y
604 help
605 Say Y here to enable the generic HD-audio codec parser
606 in snd-hda-intel driver.
607
608config SND_HDA_POWER_SAVE
609 bool "Aggressive power-saving on HD-audio"
610 depends on SND_HDA_INTEL && EXPERIMENTAL
611 help
612 Say Y here to enable more aggressive power-saving mode on
613 HD-audio driver. The power-saving timeout can be configured
614 via power_save option or over sysfs on-the-fly.
615
616config SND_HDA_POWER_SAVE_DEFAULT
617 int "Default time-out for HD-audio power-save mode"
618 depends on SND_HDA_POWER_SAVE
619 default 0
620 help
621 The default time-out value in seconds for HD-audio automatic
622 power-save mode. 0 means to disable the power-save mode.
623 502
624config SND_HDSP 503config SND_HDSP
625 tristate "RME Hammerfall DSP Audio" 504 tristate "RME Hammerfall DSP Audio"
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index bd510eceff1f..e2b843b4f9d0 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -175,7 +175,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
175{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL}, 175{ 0x574d4C04, 0xffffffff, "WM9704M,WM9704Q", patch_wolfson04, NULL},
176{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL}, 176{ 0x574d4C05, 0xffffffff, "WM9705,WM9710", patch_wolfson05, NULL},
177{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL}, 177{ 0x574d4C09, 0xffffffff, "WM9709", NULL, NULL},
178{ 0x574d4C12, 0xffffffff, "WM9711,WM9712", patch_wolfson11, NULL}, 178{ 0x574d4C12, 0xffffffff, "WM9711,WM9712,WM9715", patch_wolfson11, NULL},
179{ 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF}, 179{ 0x574d4c13, 0xffffffff, "WM9713,WM9714", patch_wolfson13, NULL, AC97_DEFAULT_POWER_OFF},
180{ 0x594d4800, 0xffffffff, "YMF743", patch_yamaha_ymf743, NULL }, 180{ 0x594d4800, 0xffffffff, "YMF743", patch_yamaha_ymf743, NULL },
181{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL }, 181{ 0x594d4802, 0xffffffff, "YMF752", NULL, NULL },
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 6e831aff1bd0..81bc93e5f1e3 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -2054,8 +2054,9 @@ static const struct snd_kcontrol_new snd_ac97_ad1888_controls[] = {
2054 .get = snd_ac97_ad1888_lohpsel_get, 2054 .get = snd_ac97_ad1888_lohpsel_get,
2055 .put = snd_ac97_ad1888_lohpsel_put 2055 .put = snd_ac97_ad1888_lohpsel_put
2056 }, 2056 },
2057 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, 2, 1, 1), 2057 AC97_SINGLE("V_REFOUT Enable", AC97_AD_MISC, AC97_AD_VREFD_SHIFT, 1, 1),
2058 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1), 2058 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2,
2059 AC97_AD_HPFD_SHIFT, 1, 1),
2059 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0), 2060 AC97_SINGLE("Spread Front to Surround and Center/LFE", AC97_AD_MISC, 7, 1, 0),
2060 { 2061 {
2061 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2062 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2832,6 +2833,8 @@ static int patch_alc655(struct snd_ac97 * ac97)
2832 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ 2833 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
2833 else 2834 else
2834 val |= (1 << 1); /* Pin 47 is spdif input pin */ 2835 val |= (1 << 1); /* Pin 47 is spdif input pin */
2836 /* this seems missing on some hardwares */
2837 ac97->ext_id |= AC97_EI_SPDIF;
2835 } 2838 }
2836 val &= ~(1 << 12); /* vref enable */ 2839 val &= ~(1 << 12); /* vref enable */
2837 snd_ac97_write_cache(ac97, 0x7a, val); 2840 snd_ac97_write_cache(ac97, 0x7a, val);
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index 74175fc80c7f..14b8d9a91aae 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -664,10 +664,14 @@ struct snd_ca0106_pcm {
664struct snd_ca0106_details { 664struct snd_ca0106_details {
665 u32 serial; 665 u32 serial;
666 char * name; 666 char * name;
667 int ac97; 667 int ac97; /* ac97 = 0 -> Select MIC, Line in, TAD in, AUX in.
668 int gpio_type; 668 ac97 = 1 -> Default to AC97 in. */
669 int i2c_adc; 669 int gpio_type; /* gpio_type = 1 -> shared mic-in/line-in
670 int spi_dac; 670 gpio_type = 2 -> shared side-out/line-in. */
671 int i2c_adc; /* with i2c_adc=1, the driver adds some capture volume
672 controls, phone, mic, line-in and aux. */
673 int spi_dac; /* spi_dac=1 adds the mute switch for each analog
674 output, front, rear, etc. */
671}; 675};
672 676
673// definition of the chip-specific record 677// definition of the chip-specific record
@@ -686,11 +690,12 @@ struct snd_ca0106 {
686 spinlock_t emu_lock; 690 spinlock_t emu_lock;
687 691
688 struct snd_ac97 *ac97; 692 struct snd_ac97 *ac97;
689 struct snd_pcm *pcm; 693 struct snd_pcm *pcm[4];
690 694
691 struct snd_ca0106_channel playback_channels[4]; 695 struct snd_ca0106_channel playback_channels[4];
692 struct snd_ca0106_channel capture_channels[4]; 696 struct snd_ca0106_channel capture_channels[4];
693 u32 spdif_bits[4]; /* s/pdif out setup */ 697 u32 spdif_bits[4]; /* s/pdif out default setup */
698 u32 spdif_str_bits[4]; /* s/pdif out per-stream setup */
694 int spdif_enable; 699 int spdif_enable;
695 int capture_source; 700 int capture_source;
696 int i2c_capture_source; 701 int i2c_capture_source;
@@ -703,6 +708,11 @@ struct snd_ca0106 {
703 struct snd_ca_midi midi2; 708 struct snd_ca_midi midi2;
704 709
705 u16 spi_dac_reg[16]; 710 u16 spi_dac_reg[16];
711
712#ifdef CONFIG_PM
713#define NUM_SAVED_VOLUMES 9
714 unsigned int saved_vol[NUM_SAVED_VOLUMES];
715#endif
706}; 716};
707 717
708int snd_ca0106_mixer(struct snd_ca0106 *emu); 718int snd_ca0106_mixer(struct snd_ca0106 *emu);
@@ -721,3 +731,11 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
721 731
722int snd_ca0106_spi_write(struct snd_ca0106 * emu, 732int snd_ca0106_spi_write(struct snd_ca0106 * emu,
723 unsigned int data); 733 unsigned int data);
734
735#ifdef CONFIG_PM
736void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip);
737void snd_ca0106_mixer_resume(struct snd_ca0106 *chip);
738#else
739#define snd_ca0106_mixer_suspend(chip) do { } while (0)
740#define snd_ca0106_mixer_resume(chip) do { } while (0)
741#endif
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index 88fbf285d2b7..0e62205d4081 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -254,7 +254,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = {
254 .name = "MSI K8N Diamond MB", 254 .name = "MSI K8N Diamond MB",
255 .gpio_type = 2, 255 .gpio_type = 2,
256 .i2c_adc = 1, 256 .i2c_adc = 1,
257 .spi_dac = 2 } , 257 .spi_dac = 1 } ,
258 /* Shuttle XPC SD31P which has an onboard Creative Labs 258 /* Shuttle XPC SD31P which has an onboard Creative Labs
259 * Sound Blaster Live! 24-bit EAX 259 * Sound Blaster Live! 24-bit EAX
260 * high-definition 7.1 audio processor". 260 * high-definition 7.1 audio processor".
@@ -305,9 +305,15 @@ static struct snd_pcm_hardware snd_ca0106_capture_hw = {
305 SNDRV_PCM_INFO_BLOCK_TRANSFER | 305 SNDRV_PCM_INFO_BLOCK_TRANSFER |
306 SNDRV_PCM_INFO_MMAP_VALID), 306 SNDRV_PCM_INFO_MMAP_VALID),
307 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, 307 .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE,
308#if 0 /* FIXME: looks like 44.1kHz capture causes noisy output on 48kHz */
308 .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | 309 .rates = (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
309 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000), 310 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
310 .rate_min = 44100, 311 .rate_min = 44100,
312#else
313 .rates = (SNDRV_PCM_RATE_48000 |
314 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000),
315 .rate_min = 48000,
316#endif /* FIXME */
311 .rate_max = 192000, 317 .rate_max = 192000,
312 .channels_min = 2, 318 .channels_min = 2,
313 .channels_max = 2, 319 .channels_max = 2,
@@ -479,6 +485,15 @@ static const int spi_dacd_bit[] = {
479 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT, 485 [PCM_UNKNOWN_CHANNEL] = SPI_DACD1_BIT,
480}; 486};
481 487
488static void restore_spdif_bits(struct snd_ca0106 *chip, int idx)
489{
490 if (chip->spdif_str_bits[idx] != chip->spdif_bits[idx]) {
491 chip->spdif_str_bits[idx] = chip->spdif_bits[idx];
492 snd_ca0106_ptr_write(chip, SPCS0 + idx, 0,
493 chip->spdif_str_bits[idx]);
494 }
495}
496
482/* open_playback callback */ 497/* open_playback callback */
483static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream, 498static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substream,
484 int channel_id) 499 int channel_id)
@@ -524,6 +539,9 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
524 if (err < 0) 539 if (err < 0)
525 return err; 540 return err;
526 } 541 }
542
543 restore_spdif_bits(chip, channel_id);
544
527 return 0; 545 return 0;
528} 546}
529 547
@@ -535,6 +553,8 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
535 struct snd_ca0106_pcm *epcm = runtime->private_data; 553 struct snd_ca0106_pcm *epcm = runtime->private_data;
536 chip->playback_channels[epcm->channel_id].use = 0; 554 chip->playback_channels[epcm->channel_id].use = 0;
537 555
556 restore_spdif_bits(chip, epcm->channel_id);
557
538 if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) { 558 if (chip->details->spi_dac && epcm->channel_id != PCM_FRONT_CHANNEL) {
539 const int reg = spi_dacd_reg[epcm->channel_id]; 559 const int reg = spi_dacd_reg[epcm->channel_id];
540 560
@@ -847,15 +867,18 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
847 struct snd_pcm_substream *s; 867 struct snd_pcm_substream *s;
848 u32 basic = 0; 868 u32 basic = 0;
849 u32 extended = 0; 869 u32 extended = 0;
850 int running=0; 870 u32 bits;
871 int running = 0;
851 872
852 switch (cmd) { 873 switch (cmd) {
853 case SNDRV_PCM_TRIGGER_START: 874 case SNDRV_PCM_TRIGGER_START:
854 running=1; 875 case SNDRV_PCM_TRIGGER_RESUME:
876 running = 1;
855 break; 877 break;
856 case SNDRV_PCM_TRIGGER_STOP: 878 case SNDRV_PCM_TRIGGER_STOP:
879 case SNDRV_PCM_TRIGGER_SUSPEND:
857 default: 880 default:
858 running=0; 881 running = 0;
859 break; 882 break;
860 } 883 }
861 snd_pcm_group_for_each_entry(s, substream) { 884 snd_pcm_group_for_each_entry(s, substream) {
@@ -865,22 +888,32 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream,
865 runtime = s->runtime; 888 runtime = s->runtime;
866 epcm = runtime->private_data; 889 epcm = runtime->private_data;
867 channel = epcm->channel_id; 890 channel = epcm->channel_id;
868 //snd_printk("channel=%d\n",channel); 891 /* snd_printk("channel=%d\n",channel); */
869 epcm->running = running; 892 epcm->running = running;
870 basic |= (0x1<<channel); 893 basic |= (0x1 << channel);
871 extended |= (0x10<<channel); 894 extended |= (0x10 << channel);
872 snd_pcm_trigger_done(s, substream); 895 snd_pcm_trigger_done(s, substream);
873 } 896 }
874 //snd_printk("basic=0x%x, extended=0x%x\n",basic, extended); 897 /* snd_printk("basic=0x%x, extended=0x%x\n",basic, extended); */
875 898
876 switch (cmd) { 899 switch (cmd) {
877 case SNDRV_PCM_TRIGGER_START: 900 case SNDRV_PCM_TRIGGER_START:
878 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) | (extended)); 901 case SNDRV_PCM_TRIGGER_RESUME:
879 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0)|(basic)); 902 bits = snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0);
903 bits |= extended;
904 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, bits);
905 bits = snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0);
906 bits |= basic;
907 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, bits);
880 break; 908 break;
881 case SNDRV_PCM_TRIGGER_STOP: 909 case SNDRV_PCM_TRIGGER_STOP:
882 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0) & ~(basic)); 910 case SNDRV_PCM_TRIGGER_SUSPEND:
883 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0) & ~(extended)); 911 bits = snd_ca0106_ptr_read(emu, BASIC_INTERRUPT, 0);
912 bits &= ~basic;
913 snd_ca0106_ptr_write(emu, BASIC_INTERRUPT, 0, bits);
914 bits = snd_ca0106_ptr_read(emu, EXTENDED_INT_MASK, 0);
915 bits &= ~extended;
916 snd_ca0106_ptr_write(emu, EXTENDED_INT_MASK, 0, bits);
884 break; 917 break;
885 default: 918 default:
886 result = -EINVAL; 919 result = -EINVAL;
@@ -1103,21 +1136,13 @@ static int snd_ca0106_ac97(struct snd_ca0106 *chip)
1103 return snd_ac97_mixer(pbus, &ac97, &chip->ac97); 1136 return snd_ac97_mixer(pbus, &ac97, &chip->ac97);
1104} 1137}
1105 1138
1139static void ca0106_stop_chip(struct snd_ca0106 *chip);
1140
1106static int snd_ca0106_free(struct snd_ca0106 *chip) 1141static int snd_ca0106_free(struct snd_ca0106 *chip)
1107{ 1142{
1108 if (chip->res_port != NULL) { /* avoid access to already used hardware */ 1143 if (chip->res_port != NULL) {
1109 // disable interrupts 1144 /* avoid access to already used hardware */
1110 snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0); 1145 ca0106_stop_chip(chip);
1111 outl(0, chip->port + INTE);
1112 snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
1113 udelay(1000);
1114 // disable audio
1115 //outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG);
1116 outl(0, chip->port + HCFG);
1117 /* FIXME: We need to stop and DMA transfers here.
1118 * But as I am not sure how yet, we cannot from the dma pages.
1119 * So we can fix: snd-malloc: Memory leak? pages not freed = 8
1120 */
1121 } 1146 }
1122 if (chip->irq >= 0) 1147 if (chip->irq >= 0)
1123 free_irq(chip->irq, chip); 1148 free_irq(chip->irq, chip);
@@ -1203,15 +1228,14 @@ static irqreturn_t snd_ca0106_interrupt(int irq, void *dev_id)
1203 return IRQ_HANDLED; 1228 return IRQ_HANDLED;
1204} 1229}
1205 1230
1206static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct snd_pcm **rpcm) 1231static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device)
1207{ 1232{
1208 struct snd_pcm *pcm; 1233 struct snd_pcm *pcm;
1209 struct snd_pcm_substream *substream; 1234 struct snd_pcm_substream *substream;
1210 int err; 1235 int err;
1211 1236
1212 if (rpcm) 1237 err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm);
1213 *rpcm = NULL; 1238 if (err < 0)
1214 if ((err = snd_pcm_new(emu->card, "ca0106", device, 1, 1, &pcm)) < 0)
1215 return err; 1239 return err;
1216 1240
1217 pcm->private_data = emu; 1241 pcm->private_data = emu;
@@ -1238,7 +1262,6 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s
1238 pcm->info_flags = 0; 1262 pcm->info_flags = 0;
1239 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX; 1263 pcm->dev_subclass = SNDRV_PCM_SUBCLASS_GENERIC_MIX;
1240 strcpy(pcm->name, "CA0106"); 1264 strcpy(pcm->name, "CA0106");
1241 emu->pcm = pcm;
1242 1265
1243 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 1266 for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream;
1244 substream; 1267 substream;
@@ -1260,8 +1283,7 @@ static int __devinit snd_ca0106_pcm(struct snd_ca0106 *emu, int device, struct s
1260 return err; 1283 return err;
1261 } 1284 }
1262 1285
1263 if (rpcm) 1286 emu->pcm[device] = pcm;
1264 *rpcm = pcm;
1265 1287
1266 return 0; 1288 return 0;
1267} 1289}
@@ -1301,89 +1323,10 @@ static unsigned int i2c_adc_init[][2] = {
1301 { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */ 1323 { 0x15, ADC_MUX_LINEIN }, /* ADC Mixer control */
1302}; 1324};
1303 1325
1304static int __devinit snd_ca0106_create(int dev, struct snd_card *card, 1326static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
1305 struct pci_dev *pci,
1306 struct snd_ca0106 **rchip)
1307{ 1327{
1308 struct snd_ca0106 *chip;
1309 struct snd_ca0106_details *c;
1310 int err;
1311 int ch; 1328 int ch;
1312 static struct snd_device_ops ops = { 1329 unsigned int def_bits;
1313 .dev_free = snd_ca0106_dev_free,
1314 };
1315
1316 *rchip = NULL;
1317
1318 if ((err = pci_enable_device(pci)) < 0)
1319 return err;
1320 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
1321 pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
1322 printk(KERN_ERR "error to set 32bit mask DMA\n");
1323 pci_disable_device(pci);
1324 return -ENXIO;
1325 }
1326
1327 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1328 if (chip == NULL) {
1329 pci_disable_device(pci);
1330 return -ENOMEM;
1331 }
1332
1333 chip->card = card;
1334 chip->pci = pci;
1335 chip->irq = -1;
1336
1337 spin_lock_init(&chip->emu_lock);
1338
1339 chip->port = pci_resource_start(pci, 0);
1340 if ((chip->res_port = request_region(chip->port, 0x20,
1341 "snd_ca0106")) == NULL) {
1342 snd_ca0106_free(chip);
1343 printk(KERN_ERR "cannot allocate the port\n");
1344 return -EBUSY;
1345 }
1346
1347 if (request_irq(pci->irq, snd_ca0106_interrupt,
1348 IRQF_SHARED, "snd_ca0106", chip)) {
1349 snd_ca0106_free(chip);
1350 printk(KERN_ERR "cannot grab irq\n");
1351 return -EBUSY;
1352 }
1353 chip->irq = pci->irq;
1354
1355 /* This stores the periods table. */
1356 if(snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 1024, &chip->buffer) < 0) {
1357 snd_ca0106_free(chip);
1358 return -ENOMEM;
1359 }
1360
1361 pci_set_master(pci);
1362 /* read serial */
1363 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
1364 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
1365#if 1
1366 printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n", chip->model,
1367 pci->revision, chip->serial);
1368#endif
1369 strcpy(card->driver, "CA0106");
1370 strcpy(card->shortname, "CA0106");
1371
1372 for (c = ca0106_chip_details; c->serial; c++) {
1373 if (subsystem[dev]) {
1374 if (c->serial == subsystem[dev])
1375 break;
1376 } else if (c->serial == chip->serial)
1377 break;
1378 }
1379 chip->details = c;
1380 if (subsystem[dev]) {
1381 printk(KERN_INFO "snd-ca0106: Sound card name=%s, subsystem=0x%x. Forced to subsystem=0x%x\n",
1382 c->name, chip->serial, subsystem[dev]);
1383 }
1384
1385 sprintf(card->longname, "%s at 0x%lx irq %i",
1386 c->name, chip->port, chip->irq);
1387 1330
1388 outl(0, chip->port + INTE); 1331 outl(0, chip->port + INTE);
1389 1332
@@ -1401,31 +1344,22 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1401 * AN = 0 (Audio data) 1344 * AN = 0 (Audio data)
1402 * P = 0 (Consumer) 1345 * P = 0 (Consumer)
1403 */ 1346 */
1404 snd_ca0106_ptr_write(chip, SPCS0, 0, 1347 def_bits =
1405 chip->spdif_bits[0] = 1348 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1406 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | 1349 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1407 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 1350 SPCS_GENERATIONSTATUS | 0x00001200 |
1408 SPCS_GENERATIONSTATUS | 0x00001200 | 1351 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT;
1409 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT); 1352 if (!resume) {
1353 chip->spdif_str_bits[0] = chip->spdif_bits[0] = def_bits;
1354 chip->spdif_str_bits[1] = chip->spdif_bits[1] = def_bits;
1355 chip->spdif_str_bits[2] = chip->spdif_bits[2] = def_bits;
1356 chip->spdif_str_bits[3] = chip->spdif_bits[3] = def_bits;
1357 }
1410 /* Only SPCS1 has been tested */ 1358 /* Only SPCS1 has been tested */
1411 snd_ca0106_ptr_write(chip, SPCS1, 0, 1359 snd_ca0106_ptr_write(chip, SPCS1, 0, chip->spdif_str_bits[1]);
1412 chip->spdif_bits[1] = 1360 snd_ca0106_ptr_write(chip, SPCS0, 0, chip->spdif_str_bits[0]);
1413 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 | 1361 snd_ca0106_ptr_write(chip, SPCS2, 0, chip->spdif_str_bits[2]);
1414 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | 1362 snd_ca0106_ptr_write(chip, SPCS3, 0, chip->spdif_str_bits[3]);
1415 SPCS_GENERATIONSTATUS | 0x00001200 |
1416 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1417 snd_ca0106_ptr_write(chip, SPCS2, 0,
1418 chip->spdif_bits[2] =
1419 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1420 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1421 SPCS_GENERATIONSTATUS | 0x00001200 |
1422 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1423 snd_ca0106_ptr_write(chip, SPCS3, 0,
1424 chip->spdif_bits[3] =
1425 SPCS_CLKACCY_1000PPM | SPCS_SAMPLERATE_48 |
1426 SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC |
1427 SPCS_GENERATIONSTATUS | 0x00001200 |
1428 0x00000000 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT);
1429 1363
1430 snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000); 1364 snd_ca0106_ptr_write(chip, PLAYBACK_MUTE, 0, 0x00fc0000);
1431 snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000); 1365 snd_ca0106_ptr_write(chip, CAPTURE_MUTE, 0, 0x00fc0000);
@@ -1433,92 +1367,124 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1433 /* Write 0x8000 to AC97_REC_GAIN to mute it. */ 1367 /* Write 0x8000 to AC97_REC_GAIN to mute it. */
1434 outb(AC97_REC_GAIN, chip->port + AC97ADDRESS); 1368 outb(AC97_REC_GAIN, chip->port + AC97ADDRESS);
1435 outw(0x8000, chip->port + AC97DATA); 1369 outw(0x8000, chip->port + AC97DATA);
1436#if 0 1370#if 0 /* FIXME: what are these? */
1437 snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006); 1371 snd_ca0106_ptr_write(chip, SPCS0, 0, 0x2108006);
1438 snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006); 1372 snd_ca0106_ptr_write(chip, 0x42, 0, 0x2108006);
1439 snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006); 1373 snd_ca0106_ptr_write(chip, 0x43, 0, 0x2108006);
1440 snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006); 1374 snd_ca0106_ptr_write(chip, 0x44, 0, 0x2108006);
1441#endif 1375#endif
1442 1376
1443 //snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); /* OSS drivers set this. */ 1377 /* OSS drivers set this. */
1378 /* snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0xf0f003f); */
1379
1444 /* Analog or Digital output */ 1380 /* Analog or Digital output */
1445 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf); 1381 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf);
1446 snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers. Use 0x000f0000 for surround71 */ 1382 /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers.
1383 * Use 0x000f0000 for surround71
1384 */
1385 snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000);
1386
1447 chip->spdif_enable = 0; /* Set digital SPDIF output off */ 1387 chip->spdif_enable = 0; /* Set digital SPDIF output off */
1448 //snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */ 1388 /*snd_ca0106_ptr_write(chip, 0x45, 0, 0);*/ /* Analogue out */
1449 //snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */ 1389 /*snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00);*/ /* Digital out */
1390
1391 /* goes to 0x40c80000 when doing SPDIF IN/OUT */
1392 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000);
1393 /* (Mute) CAPTURE feedback into PLAYBACK volume.
1394 * Only lower 16 bits matter.
1395 */
1396 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff);
1397 /* SPDIF IN Volume */
1398 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000);
1399 /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
1400 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000);
1450 1401
1451 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 0, 0x40c81000); /* goes to 0x40c80000 when doing SPDIF IN/OUT */
1452 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 1, 0xffffffff); /* (Mute) CAPTURE feedback into PLAYBACK volume. Only lower 16 bits matter. */
1453 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 2, 0x30300000); /* SPDIF IN Volume */
1454 snd_ca0106_ptr_write(chip, CAPTURE_CONTROL, 3, 0x00700000); /* SPDIF IN Volume, 0x70 = (vol & 0x3f) | 0x40 */
1455 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410); 1402 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING1, 0, 0x32765410);
1456 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676); 1403 snd_ca0106_ptr_write(chip, PLAYBACK_ROUTING2, 0, 0x76767676);
1457 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410); 1404 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING1, 0, 0x32765410);
1458 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676); 1405 snd_ca0106_ptr_write(chip, CAPTURE_ROUTING2, 0, 0x76767676);
1459 for(ch = 0; ch < 4; ch++) { 1406
1460 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030); /* Only high 16 bits matter */ 1407 for (ch = 0; ch < 4; ch++) {
1408 /* Only high 16 bits matter */
1409 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME1, ch, 0x30303030);
1461 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030); 1410 snd_ca0106_ptr_write(chip, CAPTURE_VOLUME2, ch, 0x30303030);
1462 //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040); /* Mute */ 1411#if 0 /* Mute */
1463 //snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040); /* Mute */ 1412 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0x40404040);
1464 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */ 1413 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0x40404040);
1465 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */ 1414 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff);
1415 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff);
1416#endif
1466 } 1417 }
1467 if (chip->details->i2c_adc == 1) { 1418 if (chip->details->i2c_adc == 1) {
1468 /* Select MIC, Line in, TAD in, AUX in */ 1419 /* Select MIC, Line in, TAD in, AUX in */
1469 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); 1420 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
1470 /* Default to CAPTURE_SOURCE to i2s in */ 1421 /* Default to CAPTURE_SOURCE to i2s in */
1471 chip->capture_source = 3; 1422 if (!resume)
1423 chip->capture_source = 3;
1472 } else if (chip->details->ac97 == 1) { 1424 } else if (chip->details->ac97 == 1) {
1473 /* Default to AC97 in */ 1425 /* Default to AC97 in */
1474 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x444400e4); 1426 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x444400e4);
1475 /* Default to CAPTURE_SOURCE to AC97 in */ 1427 /* Default to CAPTURE_SOURCE to AC97 in */
1476 chip->capture_source = 4; 1428 if (!resume)
1429 chip->capture_source = 4;
1477 } else { 1430 } else {
1478 /* Select MIC, Line in, TAD in, AUX in */ 1431 /* Select MIC, Line in, TAD in, AUX in */
1479 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); 1432 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
1480 /* Default to Set CAPTURE_SOURCE to i2s in */ 1433 /* Default to Set CAPTURE_SOURCE to i2s in */
1481 chip->capture_source = 3; 1434 if (!resume)
1435 chip->capture_source = 3;
1482 } 1436 }
1483 1437
1484 if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */ 1438 if (chip->details->gpio_type == 2) {
1485 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ 1439 /* The SB0438 use GPIO differently. */
1440 /* FIXME: Still need to find out what the other GPIO bits do.
1441 * E.g. For digital spdif out.
1442 */
1486 outl(0x0, chip->port+GPIO); 1443 outl(0x0, chip->port+GPIO);
1487 //outl(0x00f0e000, chip->port+GPIO); /* Analog */ 1444 /* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
1488 outl(0x005f5301, chip->port+GPIO); /* Analog */ 1445 outl(0x005f5301, chip->port+GPIO); /* Analog */
1489 } else if (chip->details->gpio_type == 1) { /* The SB0410 and SB0413 use GPIO differently. */ 1446 } else if (chip->details->gpio_type == 1) {
1490 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ 1447 /* The SB0410 and SB0413 use GPIO differently. */
1448 /* FIXME: Still need to find out what the other GPIO bits do.
1449 * E.g. For digital spdif out.
1450 */
1491 outl(0x0, chip->port+GPIO); 1451 outl(0x0, chip->port+GPIO);
1492 //outl(0x00f0e000, chip->port+GPIO); /* Analog */ 1452 /* outl(0x00f0e000, chip->port+GPIO); */ /* Analog */
1493 outl(0x005f5301, chip->port+GPIO); /* Analog */ 1453 outl(0x005f5301, chip->port+GPIO); /* Analog */
1494 } else { 1454 } else {
1495 outl(0x0, chip->port+GPIO); 1455 outl(0x0, chip->port+GPIO);
1496 outl(0x005f03a3, chip->port+GPIO); /* Analog */ 1456 outl(0x005f03a3, chip->port+GPIO); /* Analog */
1497 //outl(0x005f02a2, chip->port+GPIO); /* SPDIF */ 1457 /* outl(0x005f02a2, chip->port+GPIO); */ /* SPDIF */
1498 } 1458 }
1499 snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */ 1459 snd_ca0106_intr_enable(chip, 0x105); /* Win2000 uses 0x1e0 */
1500 1460
1501 //outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); 1461 /* outl(HCFG_LOCKSOUNDCACHE|HCFG_AUDIOENABLE, chip->port+HCFG); */
1502 //outl(0x00001409, chip->port+HCFG); /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */ 1462 /* 0x1000 causes AC3 to fails. Maybe it effects 24 bit output. */
1503 //outl(0x00000009, chip->port+HCFG); 1463 /* outl(0x00001409, chip->port+HCFG); */
1504 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG); /* AC97 2.0, Enable outputs. */ 1464 /* outl(0x00000009, chip->port+HCFG); */
1465 /* AC97 2.0, Enable outputs. */
1466 outl(HCFG_AC97 | HCFG_AUDIOENABLE, chip->port+HCFG);
1505 1467
1506 if (chip->details->i2c_adc == 1) { /* The SB0410 and SB0413 use I2C to control ADC. */ 1468 if (chip->details->i2c_adc == 1) {
1469 /* The SB0410 and SB0413 use I2C to control ADC. */
1507 int size, n; 1470 int size, n;
1508 1471
1509 size = ARRAY_SIZE(i2c_adc_init); 1472 size = ARRAY_SIZE(i2c_adc_init);
1510 //snd_printk("I2C:array size=0x%x\n", size); 1473 /* snd_printk("I2C:array size=0x%x\n", size); */
1511 for (n=0; n < size; n++) { 1474 for (n = 0; n < size; n++)
1512 snd_ca0106_i2c_write(chip, i2c_adc_init[n][0], i2c_adc_init[n][1]); 1475 snd_ca0106_i2c_write(chip, i2c_adc_init[n][0],
1513 } 1476 i2c_adc_init[n][1]);
1514 for (n=0; n < 4; n++) { 1477 for (n = 0; n < 4; n++) {
1515 chip->i2c_capture_volume[n][0]= 0xcf; 1478 chip->i2c_capture_volume[n][0] = 0xcf;
1516 chip->i2c_capture_volume[n][1]= 0xcf; 1479 chip->i2c_capture_volume[n][1] = 0xcf;
1517 } 1480 }
1518 chip->i2c_capture_source=2; /* Line in */ 1481 chip->i2c_capture_source = 2; /* Line in */
1519 //snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); /* Enable Line-in capture. MIC in currently untested. */ 1482 /* Enable Line-in capture. MIC in currently untested. */
1483 /* snd_ca0106_i2c_write(chip, ADC_MUX, ADC_MUX_LINEIN); */
1520 } 1484 }
1521 if (chip->details->spi_dac == 1) { /* The SB0570 use SPI to control DAC. */ 1485
1486 if (chip->details->spi_dac == 1) {
1487 /* The SB0570 use SPI to control DAC. */
1522 int size, n; 1488 int size, n;
1523 1489
1524 size = ARRAY_SIZE(spi_dac_init); 1490 size = ARRAY_SIZE(spi_dac_init);
@@ -1530,9 +1496,112 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1530 chip->spi_dac_reg[reg] = spi_dac_init[n]; 1496 chip->spi_dac_reg[reg] = spi_dac_init[n];
1531 } 1497 }
1532 } 1498 }
1499}
1533 1500
1534 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, 1501static void ca0106_stop_chip(struct snd_ca0106 *chip)
1535 chip, &ops)) < 0) { 1502{
1503 /* disable interrupts */
1504 snd_ca0106_ptr_write(chip, BASIC_INTERRUPT, 0, 0);
1505 outl(0, chip->port + INTE);
1506 snd_ca0106_ptr_write(chip, EXTENDED_INT_MASK, 0, 0);
1507 udelay(1000);
1508 /* disable audio */
1509 /* outl(HCFG_LOCKSOUNDCACHE, chip->port + HCFG); */
1510 outl(0, chip->port + HCFG);
1511 /* FIXME: We need to stop and DMA transfers here.
1512 * But as I am not sure how yet, we cannot from the dma pages.
1513 * So we can fix: snd-malloc: Memory leak? pages not freed = 8
1514 */
1515}
1516
1517static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1518 struct pci_dev *pci,
1519 struct snd_ca0106 **rchip)
1520{
1521 struct snd_ca0106 *chip;
1522 struct snd_ca0106_details *c;
1523 int err;
1524 static struct snd_device_ops ops = {
1525 .dev_free = snd_ca0106_dev_free,
1526 };
1527
1528 *rchip = NULL;
1529
1530 err = pci_enable_device(pci);
1531 if (err < 0)
1532 return err;
1533 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0 ||
1534 pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK) < 0) {
1535 printk(KERN_ERR "error to set 32bit mask DMA\n");
1536 pci_disable_device(pci);
1537 return -ENXIO;
1538 }
1539
1540 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1541 if (chip == NULL) {
1542 pci_disable_device(pci);
1543 return -ENOMEM;
1544 }
1545
1546 chip->card = card;
1547 chip->pci = pci;
1548 chip->irq = -1;
1549
1550 spin_lock_init(&chip->emu_lock);
1551
1552 chip->port = pci_resource_start(pci, 0);
1553 chip->res_port = request_region(chip->port, 0x20, "snd_ca0106");
1554 if (!chip->res_port) {
1555 snd_ca0106_free(chip);
1556 printk(KERN_ERR "cannot allocate the port\n");
1557 return -EBUSY;
1558 }
1559
1560 if (request_irq(pci->irq, snd_ca0106_interrupt,
1561 IRQF_SHARED, "snd_ca0106", chip)) {
1562 snd_ca0106_free(chip);
1563 printk(KERN_ERR "cannot grab irq\n");
1564 return -EBUSY;
1565 }
1566 chip->irq = pci->irq;
1567
1568 /* This stores the periods table. */
1569 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
1570 1024, &chip->buffer) < 0) {
1571 snd_ca0106_free(chip);
1572 return -ENOMEM;
1573 }
1574
1575 pci_set_master(pci);
1576 /* read serial */
1577 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->serial);
1578 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->model);
1579 printk(KERN_INFO "snd-ca0106: Model %04x Rev %08x Serial %08x\n",
1580 chip->model, pci->revision, chip->serial);
1581 strcpy(card->driver, "CA0106");
1582 strcpy(card->shortname, "CA0106");
1583
1584 for (c = ca0106_chip_details; c->serial; c++) {
1585 if (subsystem[dev]) {
1586 if (c->serial == subsystem[dev])
1587 break;
1588 } else if (c->serial == chip->serial)
1589 break;
1590 }
1591 chip->details = c;
1592 if (subsystem[dev]) {
1593 printk(KERN_INFO "snd-ca0106: Sound card name=%s, "
1594 "subsystem=0x%x. Forced to subsystem=0x%x\n",
1595 c->name, chip->serial, subsystem[dev]);
1596 }
1597
1598 sprintf(card->longname, "%s at 0x%lx irq %i",
1599 c->name, chip->port, chip->irq);
1600
1601 ca0106_init_chip(chip, 0);
1602
1603 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
1604 if (err < 0) {
1536 snd_ca0106_free(chip); 1605 snd_ca0106_free(chip);
1537 return err; 1606 return err;
1538 } 1607 }
@@ -1629,7 +1698,7 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1629 static int dev; 1698 static int dev;
1630 struct snd_card *card; 1699 struct snd_card *card;
1631 struct snd_ca0106 *chip; 1700 struct snd_ca0106 *chip;
1632 int err; 1701 int i, err;
1633 1702
1634 if (dev >= SNDRV_CARDS) 1703 if (dev >= SNDRV_CARDS)
1635 return -ENODEV; 1704 return -ENODEV;
@@ -1642,44 +1711,31 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1642 if (card == NULL) 1711 if (card == NULL)
1643 return -ENOMEM; 1712 return -ENOMEM;
1644 1713
1645 if ((err = snd_ca0106_create(dev, card, pci, &chip)) < 0) { 1714 err = snd_ca0106_create(dev, card, pci, &chip);
1646 snd_card_free(card); 1715 if (err < 0)
1647 return err; 1716 goto error;
1648 } 1717 card->private_data = chip;
1649 1718
1650 if ((err = snd_ca0106_pcm(chip, 0, NULL)) < 0) { 1719 for (i = 0; i < 4; i++) {
1651 snd_card_free(card); 1720 err = snd_ca0106_pcm(chip, i);
1652 return err; 1721 if (err < 0)
1653 } 1722 goto error;
1654 if ((err = snd_ca0106_pcm(chip, 1, NULL)) < 0) {
1655 snd_card_free(card);
1656 return err;
1657 }
1658 if ((err = snd_ca0106_pcm(chip, 2, NULL)) < 0) {
1659 snd_card_free(card);
1660 return err;
1661 }
1662 if ((err = snd_ca0106_pcm(chip, 3, NULL)) < 0) {
1663 snd_card_free(card);
1664 return err;
1665 }
1666 if (chip->details->ac97 == 1) { /* The SB0410 and SB0413 do not have an AC97 chip. */
1667 if ((err = snd_ca0106_ac97(chip)) < 0) {
1668 snd_card_free(card);
1669 return err;
1670 }
1671 } 1723 }
1672 if ((err = snd_ca0106_mixer(chip)) < 0) { 1724
1673 snd_card_free(card); 1725 if (chip->details->ac97 == 1) {
1674 return err; 1726 /* The SB0410 and SB0413 do not have an AC97 chip. */
1727 err = snd_ca0106_ac97(chip);
1728 if (err < 0)
1729 goto error;
1675 } 1730 }
1731 err = snd_ca0106_mixer(chip);
1732 if (err < 0)
1733 goto error;
1676 1734
1677 snd_printdd("ca0106: probe for MIDI channel A ..."); 1735 snd_printdd("ca0106: probe for MIDI channel A ...");
1678 if ((err = snd_ca0106_midi(chip,CA0106_MIDI_CHAN_A)) < 0) { 1736 err = snd_ca0106_midi(chip, CA0106_MIDI_CHAN_A);
1679 snd_card_free(card); 1737 if (err < 0)
1680 snd_printdd(" failed, err=0x%x\n",err); 1738 goto error;
1681 return err;
1682 }
1683 snd_printdd(" done.\n"); 1739 snd_printdd(" done.\n");
1684 1740
1685#ifdef CONFIG_PROC_FS 1741#ifdef CONFIG_PROC_FS
@@ -1688,14 +1744,17 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1688 1744
1689 snd_card_set_dev(card, &pci->dev); 1745 snd_card_set_dev(card, &pci->dev);
1690 1746
1691 if ((err = snd_card_register(card)) < 0) { 1747 err = snd_card_register(card);
1692 snd_card_free(card); 1748 if (err < 0)
1693 return err; 1749 goto error;
1694 }
1695 1750
1696 pci_set_drvdata(pci, card); 1751 pci_set_drvdata(pci, card);
1697 dev++; 1752 dev++;
1698 return 0; 1753 return 0;
1754
1755 error:
1756 snd_card_free(card);
1757 return err;
1699} 1758}
1700 1759
1701static void __devexit snd_ca0106_remove(struct pci_dev *pci) 1760static void __devexit snd_ca0106_remove(struct pci_dev *pci)
@@ -1704,6 +1763,59 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci)
1704 pci_set_drvdata(pci, NULL); 1763 pci_set_drvdata(pci, NULL);
1705} 1764}
1706 1765
1766#ifdef CONFIG_PM
1767static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state)
1768{
1769 struct snd_card *card = pci_get_drvdata(pci);
1770 struct snd_ca0106 *chip = card->private_data;
1771 int i;
1772
1773 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1774 for (i = 0; i < 4; i++)
1775 snd_pcm_suspend_all(chip->pcm[i]);
1776 if (chip->details->ac97)
1777 snd_ac97_suspend(chip->ac97);
1778 snd_ca0106_mixer_suspend(chip);
1779
1780 ca0106_stop_chip(chip);
1781
1782 pci_disable_device(pci);
1783 pci_save_state(pci);
1784 pci_set_power_state(pci, pci_choose_state(pci, state));
1785 return 0;
1786}
1787
1788static int snd_ca0106_resume(struct pci_dev *pci)
1789{
1790 struct snd_card *card = pci_get_drvdata(pci);
1791 struct snd_ca0106 *chip = card->private_data;
1792 int i;
1793
1794 pci_set_power_state(pci, PCI_D0);
1795 pci_restore_state(pci);
1796
1797 if (pci_enable_device(pci) < 0) {
1798 snd_card_disconnect(card);
1799 return -EIO;
1800 }
1801
1802 pci_set_master(pci);
1803
1804 ca0106_init_chip(chip, 1);
1805
1806 if (chip->details->ac97)
1807 snd_ac97_resume(chip->ac97);
1808 snd_ca0106_mixer_resume(chip);
1809 if (chip->details->spi_dac) {
1810 for (i = 0; i < ARRAY_SIZE(chip->spi_dac_reg); i++)
1811 snd_ca0106_spi_write(chip, chip->spi_dac_reg[i]);
1812 }
1813
1814 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1815 return 0;
1816}
1817#endif
1818
1707// PCI IDs 1819// PCI IDs
1708static struct pci_device_id snd_ca0106_ids[] = { 1820static struct pci_device_id snd_ca0106_ids[] = {
1709 { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */ 1821 { 0x1102, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* Audigy LS or Live 24bit */
@@ -1717,6 +1829,10 @@ static struct pci_driver driver = {
1717 .id_table = snd_ca0106_ids, 1829 .id_table = snd_ca0106_ids,
1718 .probe = snd_ca0106_probe, 1830 .probe = snd_ca0106_probe,
1719 .remove = __devexit_p(snd_ca0106_remove), 1831 .remove = __devexit_p(snd_ca0106_remove),
1832#ifdef CONFIG_PM
1833 .suspend = snd_ca0106_suspend,
1834 .resume = snd_ca0106_resume,
1835#endif
1720}; 1836};
1721 1837
1722// initialization of the module 1838// initialization of the module
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 3025ed1b6e1e..ad2888705d2a 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -75,6 +75,84 @@
75 75
76#include "ca0106.h" 76#include "ca0106.h"
77 77
78static void ca0106_spdif_enable(struct snd_ca0106 *emu)
79{
80 unsigned int val;
81
82 if (emu->spdif_enable) {
83 /* Digital */
84 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
85 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
86 val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000;
87 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
88 val = inl(emu->port + GPIO) & ~0x101;
89 outl(val, emu->port + GPIO);
90
91 } else {
92 /* Analog */
93 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
94 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
95 val = snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000;
96 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0, val);
97 val = inl(emu->port + GPIO) | 0x101;
98 outl(val, emu->port + GPIO);
99 }
100}
101
102static void ca0106_set_capture_source(struct snd_ca0106 *emu)
103{
104 unsigned int val = emu->capture_source;
105 unsigned int source, mask;
106 source = (val << 28) | (val << 24) | (val << 20) | (val << 16);
107 mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
108 snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
109}
110
111static void ca0106_set_i2c_capture_source(struct snd_ca0106 *emu,
112 unsigned int val, int force)
113{
114 unsigned int ngain, ogain;
115 u32 source;
116
117 snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
118 ngain = emu->i2c_capture_volume[val][0]; /* Left */
119 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
120 if (force || ngain != ogain)
121 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ngain & 0xff);
122 ngain = emu->i2c_capture_volume[val][1]; /* Right */
123 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
124 if (force || ngain != ogain)
125 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ngain & 0xff);
126 source = 1 << val;
127 snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
128 emu->i2c_capture_source = val;
129}
130
131static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
132{
133 u32 tmp;
134
135 if (emu->capture_mic_line_in) {
136 /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
137 tmp = inl(emu->port+GPIO) & ~0x400;
138 tmp = tmp | 0x400;
139 outl(tmp, emu->port+GPIO);
140 /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
141 } else {
142 /* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */ /* Mute input */
143 tmp = inl(emu->port+GPIO) & ~0x400;
144 outl(tmp, emu->port+GPIO);
145 /* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
146 }
147}
148
149static void ca0106_set_spdif_bits(struct snd_ca0106 *emu, int idx)
150{
151 snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, emu->spdif_str_bits[idx]);
152}
153
154/*
155 */
78static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); 156static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
79static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); 157static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
80 158
@@ -95,30 +173,12 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
95 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 173 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
96 unsigned int val; 174 unsigned int val;
97 int change = 0; 175 int change = 0;
98 u32 mask;
99 176
100 val = !!ucontrol->value.integer.value[0]; 177 val = !!ucontrol->value.integer.value[0];
101 change = (emu->spdif_enable != val); 178 change = (emu->spdif_enable != val);
102 if (change) { 179 if (change) {
103 emu->spdif_enable = val; 180 emu->spdif_enable = val;
104 if (val) { 181 ca0106_spdif_enable(emu);
105 /* Digital */
106 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
107 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x0b000000);
108 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
109 snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) & ~0x1000);
110 mask = inl(emu->port + GPIO) & ~0x101;
111 outl(mask, emu->port + GPIO);
112
113 } else {
114 /* Analog */
115 snd_ca0106_ptr_write(emu, SPDIF_SELECT1, 0, 0xf);
116 snd_ca0106_ptr_write(emu, SPDIF_SELECT2, 0, 0x000f0000);
117 snd_ca0106_ptr_write(emu, CAPTURE_CONTROL, 0,
118 snd_ca0106_ptr_read(emu, CAPTURE_CONTROL, 0) | 0x1000);
119 mask = inl(emu->port + GPIO) | 0x101;
120 outl(mask, emu->port + GPIO);
121 }
122 } 182 }
123 return change; 183 return change;
124} 184}
@@ -154,8 +214,6 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
154 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 214 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
155 unsigned int val; 215 unsigned int val;
156 int change = 0; 216 int change = 0;
157 u32 mask;
158 u32 source;
159 217
160 val = ucontrol->value.enumerated.item[0] ; 218 val = ucontrol->value.enumerated.item[0] ;
161 if (val >= 6) 219 if (val >= 6)
@@ -163,9 +221,7 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
163 change = (emu->capture_source != val); 221 change = (emu->capture_source != val);
164 if (change) { 222 if (change) {
165 emu->capture_source = val; 223 emu->capture_source = val;
166 source = (val << 28) | (val << 24) | (val << 20) | (val << 16); 224 ca0106_set_capture_source(emu);
167 mask = snd_ca0106_ptr_read(emu, CAPTURE_SOURCE, 0) & 0xffff;
168 snd_ca0106_ptr_write(emu, CAPTURE_SOURCE, 0, source | mask);
169 } 225 }
170 return change; 226 return change;
171} 227}
@@ -200,9 +256,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
200{ 256{
201 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 257 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
202 unsigned int source_id; 258 unsigned int source_id;
203 unsigned int ngain, ogain;
204 int change = 0; 259 int change = 0;
205 u32 source;
206 /* If the capture source has changed, 260 /* If the capture source has changed,
207 * update the capture volume from the cached value 261 * update the capture volume from the cached value
208 * for the particular source. 262 * for the particular source.
@@ -212,18 +266,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
212 return -EINVAL; 266 return -EINVAL;
213 change = (emu->i2c_capture_source != source_id); 267 change = (emu->i2c_capture_source != source_id);
214 if (change) { 268 if (change) {
215 snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */ 269 ca0106_set_i2c_capture_source(emu, source_id, 0);
216 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
217 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
218 if (ngain != ogain)
219 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
220 ngain = emu->i2c_capture_volume[source_id][1]; /* Left */
221 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Left */
222 if (ngain != ogain)
223 snd_ca0106_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
224 source = 1 << source_id;
225 snd_ca0106_i2c_write(emu, ADC_MUX, source); /* Set source */
226 emu->i2c_capture_source = source_id;
227 } 270 }
228 return change; 271 return change;
229} 272}
@@ -271,7 +314,6 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
271 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 314 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
272 unsigned int val; 315 unsigned int val;
273 int change = 0; 316 int change = 0;
274 u32 tmp;
275 317
276 val = ucontrol->value.enumerated.item[0] ; 318 val = ucontrol->value.enumerated.item[0] ;
277 if (val > 1) 319 if (val > 1)
@@ -279,18 +321,7 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
279 change = (emu->capture_mic_line_in != val); 321 change = (emu->capture_mic_line_in != val);
280 if (change) { 322 if (change) {
281 emu->capture_mic_line_in = val; 323 emu->capture_mic_line_in = val;
282 if (val) { 324 ca0106_set_capture_mic_line_in(emu);
283 //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
284 tmp = inl(emu->port+GPIO) & ~0x400;
285 tmp = tmp | 0x400;
286 outl(tmp, emu->port+GPIO);
287 //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
288 } else {
289 //snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
290 tmp = inl(emu->port+GPIO) & ~0x400;
291 outl(tmp, emu->port+GPIO);
292 //snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
293 }
294 } 325 }
295 return change; 326 return change;
296} 327}
@@ -322,16 +353,33 @@ static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
322 return 0; 353 return 0;
323} 354}
324 355
325static int snd_ca0106_spdif_get(struct snd_kcontrol *kcontrol, 356static void decode_spdif_bits(unsigned char *status, unsigned int bits)
357{
358 status[0] = (bits >> 0) & 0xff;
359 status[1] = (bits >> 8) & 0xff;
360 status[2] = (bits >> 16) & 0xff;
361 status[3] = (bits >> 24) & 0xff;
362}
363
364static int snd_ca0106_spdif_get_default(struct snd_kcontrol *kcontrol,
326 struct snd_ctl_elem_value *ucontrol) 365 struct snd_ctl_elem_value *ucontrol)
327{ 366{
328 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 367 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
329 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 368 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
330 369
331 ucontrol->value.iec958.status[0] = (emu->spdif_bits[idx] >> 0) & 0xff; 370 decode_spdif_bits(ucontrol->value.iec958.status,
332 ucontrol->value.iec958.status[1] = (emu->spdif_bits[idx] >> 8) & 0xff; 371 emu->spdif_bits[idx]);
333 ucontrol->value.iec958.status[2] = (emu->spdif_bits[idx] >> 16) & 0xff; 372 return 0;
334 ucontrol->value.iec958.status[3] = (emu->spdif_bits[idx] >> 24) & 0xff; 373}
374
375static int snd_ca0106_spdif_get_stream(struct snd_kcontrol *kcontrol,
376 struct snd_ctl_elem_value *ucontrol)
377{
378 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
379 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
380
381 decode_spdif_bits(ucontrol->value.iec958.status,
382 emu->spdif_str_bits[idx]);
335 return 0; 383 return 0;
336} 384}
337 385
@@ -345,24 +393,48 @@ static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
345 return 0; 393 return 0;
346} 394}
347 395
348static int snd_ca0106_spdif_put(struct snd_kcontrol *kcontrol, 396static unsigned int encode_spdif_bits(unsigned char *status)
397{
398 return ((unsigned int)status[0] << 0) |
399 ((unsigned int)status[1] << 8) |
400 ((unsigned int)status[2] << 16) |
401 ((unsigned int)status[3] << 24);
402}
403
404static int snd_ca0106_spdif_put_default(struct snd_kcontrol *kcontrol,
349 struct snd_ctl_elem_value *ucontrol) 405 struct snd_ctl_elem_value *ucontrol)
350{ 406{
351 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol); 407 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
352 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 408 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
353 int change;
354 unsigned int val; 409 unsigned int val;
355 410
356 val = (ucontrol->value.iec958.status[0] << 0) | 411 val = encode_spdif_bits(ucontrol->value.iec958.status);
357 (ucontrol->value.iec958.status[1] << 8) | 412 if (val != emu->spdif_bits[idx]) {
358 (ucontrol->value.iec958.status[2] << 16) |
359 (ucontrol->value.iec958.status[3] << 24);
360 change = val != emu->spdif_bits[idx];
361 if (change) {
362 snd_ca0106_ptr_write(emu, SPCS0 + idx, 0, val);
363 emu->spdif_bits[idx] = val; 413 emu->spdif_bits[idx] = val;
414 /* FIXME: this isn't safe, but needed to keep the compatibility
415 * with older alsa-lib config
416 */
417 emu->spdif_str_bits[idx] = val;
418 ca0106_set_spdif_bits(emu, idx);
419 return 1;
364 } 420 }
365 return change; 421 return 0;
422}
423
424static int snd_ca0106_spdif_put_stream(struct snd_kcontrol *kcontrol,
425 struct snd_ctl_elem_value *ucontrol)
426{
427 struct snd_ca0106 *emu = snd_kcontrol_chip(kcontrol);
428 unsigned int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
429 unsigned int val;
430
431 val = encode_spdif_bits(ucontrol->value.iec958.status);
432 if (val != emu->spdif_str_bits[idx]) {
433 emu->spdif_str_bits[idx] = val;
434 ca0106_set_spdif_bits(emu, idx);
435 return 1;
436 }
437 return 0;
366} 438}
367 439
368static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol, 440static int snd_ca0106_volume_info(struct snd_kcontrol *kcontrol,
@@ -573,8 +645,16 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
573 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 645 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
574 .count = 4, 646 .count = 4,
575 .info = snd_ca0106_spdif_info, 647 .info = snd_ca0106_spdif_info,
576 .get = snd_ca0106_spdif_get, 648 .get = snd_ca0106_spdif_get_default,
577 .put = snd_ca0106_spdif_put 649 .put = snd_ca0106_spdif_put_default
650 },
651 {
652 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
653 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM),
654 .count = 4,
655 .info = snd_ca0106_spdif_info,
656 .get = snd_ca0106_spdif_get_stream,
657 .put = snd_ca0106_spdif_put_stream
578 }, 658 },
579}; 659};
580 660
@@ -773,3 +853,50 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
773 return 0; 853 return 0;
774} 854}
775 855
856#ifdef CONFIG_PM
857struct ca0106_vol_tbl {
858 unsigned int channel_id;
859 unsigned int reg;
860};
861
862static struct ca0106_vol_tbl saved_volumes[NUM_SAVED_VOLUMES] = {
863 { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2 },
864 { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME2 },
865 { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME2 },
866 { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME2 },
867 { CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME1 },
868 { CONTROL_REAR_CHANNEL, PLAYBACK_VOLUME1 },
869 { CONTROL_CENTER_LFE_CHANNEL, PLAYBACK_VOLUME1 },
870 { CONTROL_UNKNOWN_CHANNEL, PLAYBACK_VOLUME1 },
871 { 1, CAPTURE_CONTROL },
872};
873
874void snd_ca0106_mixer_suspend(struct snd_ca0106 *chip)
875{
876 int i;
877
878 /* save volumes */
879 for (i = 0; i < NUM_SAVED_VOLUMES; i++)
880 chip->saved_vol[i] =
881 snd_ca0106_ptr_read(chip, saved_volumes[i].reg,
882 saved_volumes[i].channel_id);
883}
884
885void snd_ca0106_mixer_resume(struct snd_ca0106 *chip)
886{
887 int i;
888
889 for (i = 0; i < NUM_SAVED_VOLUMES; i++)
890 snd_ca0106_ptr_write(chip, saved_volumes[i].reg,
891 saved_volumes[i].channel_id,
892 chip->saved_vol[i]);
893
894 ca0106_spdif_enable(chip);
895 ca0106_set_capture_source(chip);
896 ca0106_set_i2c_capture_source(chip, chip->i2c_capture_source, 1);
897 for (i = 0; i < 4; i++)
898 ca0106_set_spdif_bits(chip, i);
899 if (chip->details->i2c_adc)
900 ca0106_set_capture_mic_line_in(chip);
901}
902#endif /* CONFIG_PM */
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index fb6dc3980257..8ab07aa63652 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -3640,7 +3640,10 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3640{ 3640{
3641 struct snd_card *card = pci_get_drvdata(pci); 3641 struct snd_card *card = pci_get_drvdata(pci);
3642 struct snd_cs46xx *chip = card->private_data; 3642 struct snd_cs46xx *chip = card->private_data;
3643 int i, amp_saved; 3643 int amp_saved;
3644#ifdef CONFIG_SND_CS46XX_NEW_DSP
3645 int i;
3646#endif
3644 3647
3645 pci_set_power_state(pci, PCI_D0); 3648 pci_set_power_state(pci, PCI_D0);
3646 pci_restore_state(pci); 3649 pci_restore_state(pci);
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile
index bb3d57e6a3cb..fda7a94c992f 100644
--- a/sound/pci/cs5535audio/Makefile
+++ b/sound/pci/cs5535audio/Makefile
@@ -4,6 +4,9 @@
4 4
5snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o 5snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o
6snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o 6snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o
7ifdef CONFIG_MGEODE_LX
8snd-cs5535audio-$(CONFIG_OLPC) += cs5535audio_olpc.o
9endif
7 10
8# Toplevel Module Dependency 11# Toplevel Module Dependency
9obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o 12obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 1d8b16052535..826e6dec2e97 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -159,10 +159,14 @@ static int __devinit snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
159 return err; 159 return err;
160 160
161 memset(&ac97, 0, sizeof(ac97)); 161 memset(&ac97, 0, sizeof(ac97));
162 ac97.scaps = AC97_SCAP_AUDIO|AC97_SCAP_SKIP_MODEM; 162 ac97.scaps = AC97_SCAP_AUDIO | AC97_SCAP_SKIP_MODEM
163 | AC97_SCAP_POWER_SAVE;
163 ac97.private_data = cs5535au; 164 ac97.private_data = cs5535au;
164 ac97.pci = cs5535au->pci; 165 ac97.pci = cs5535au->pci;
165 166
167 /* set any OLPC-specific scaps */
168 olpc_prequirks(card, &ac97);
169
166 if ((err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97)) < 0) { 170 if ((err = snd_ac97_mixer(pbus, &ac97, &cs5535au->ac97)) < 0) {
167 snd_printk(KERN_ERR "mixer failed\n"); 171 snd_printk(KERN_ERR "mixer failed\n");
168 return err; 172 return err;
@@ -170,6 +174,12 @@ static int __devinit snd_cs5535audio_mixer(struct cs5535audio *cs5535au)
170 174
171 snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk); 175 snd_ac97_tune_hardware(cs5535au->ac97, ac97_quirks, ac97_quirk);
172 176
177 err = olpc_quirks(card, cs5535au->ac97);
178 if (err < 0) {
179 snd_printk(KERN_ERR "olpc quirks failed\n");
180 return err;
181 }
182
173 return 0; 183 return 0;
174} 184}
175 185
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 66bae7664193..7a298ac662e3 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -78,6 +78,7 @@ struct cs5535audio_dma {
78 unsigned int buf_addr, buf_bytes; 78 unsigned int buf_addr, buf_bytes;
79 unsigned int period_bytes, periods; 79 unsigned int period_bytes, periods;
80 u32 saved_prd; 80 u32 saved_prd;
81 int pcm_open_flag;
81}; 82};
82 83
83struct cs5535audio { 84struct cs5535audio {
@@ -93,8 +94,46 @@ struct cs5535audio {
93 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS]; 94 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
94}; 95};
95 96
97#ifdef CONFIG_PM
96int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state); 98int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
97int snd_cs5535audio_resume(struct pci_dev *pci); 99int snd_cs5535audio_resume(struct pci_dev *pci);
100#endif
101
102#if defined(CONFIG_OLPC) && defined(CONFIG_MGEODE_LX)
103void __devinit olpc_prequirks(struct snd_card *card,
104 struct snd_ac97_template *ac97);
105int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97);
106void olpc_analog_input(struct snd_ac97 *ac97, int on);
107void olpc_mic_bias(struct snd_ac97 *ac97, int on);
108
109static inline void olpc_capture_open(struct snd_ac97 *ac97)
110{
111 /* default to Analog Input off */
112 olpc_analog_input(ac97, 0);
113 /* enable MIC Bias for recording */
114 olpc_mic_bias(ac97, 1);
115}
116
117static inline void olpc_capture_close(struct snd_ac97 *ac97)
118{
119 /* disable Analog Input */
120 olpc_analog_input(ac97, 0);
121 /* disable the MIC Bias (so the recording LED turns off) */
122 olpc_mic_bias(ac97, 0);
123}
124#else
125static inline void olpc_prequirks(struct snd_card *card,
126 struct snd_ac97_template *ac97) { }
127static inline int olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
128{
129 return 0;
130}
131static inline void olpc_analog_input(struct snd_ac97 *ac97, int on) { }
132static inline void olpc_mic_bias(struct snd_ac97 *ac97, int on) { }
133static inline void olpc_capture_open(struct snd_ac97 *ac97) { }
134static inline void olpc_capture_close(struct snd_ac97 *ac97) { }
135#endif
136
98int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio); 137int __devinit snd_cs5535audio_pcm(struct cs5535audio *cs5535audio);
99 138
100#endif /* __SOUND_CS5535AUDIO_H */ 139#endif /* __SOUND_CS5535AUDIO_H */
diff --git a/sound/pci/cs5535audio/cs5535audio_olpc.c b/sound/pci/cs5535audio/cs5535audio_olpc.c
new file mode 100644
index 000000000000..5c6814335cd7
--- /dev/null
+++ b/sound/pci/cs5535audio/cs5535audio_olpc.c
@@ -0,0 +1,179 @@
1/*
2 * OLPC XO-1 additional sound features
3 *
4 * Copyright © 2006 Jaya Kumar <jayakumar.lkml@gmail.com>
5 * Copyright © 2007-2008 Andres Salomon <dilinger@debian.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 */
12#include <sound/core.h>
13#include <sound/info.h>
14#include <sound/control.h>
15#include <sound/ac97_codec.h>
16
17#include <asm/olpc.h>
18#include "cs5535audio.h"
19
20/*
21 * OLPC has an additional feature on top of the regular AD1888 codec features.
22 * It has an Analog Input mode that is switched into (after disabling the
23 * High Pass Filter) via GPIO. It is supported on B2 and later models.
24 */
25void olpc_analog_input(struct snd_ac97 *ac97, int on)
26{
27 int err;
28
29 if (!machine_is_olpc())
30 return;
31
32 /* update the High Pass Filter (via AC97_AD_TEST2) */
33 err = snd_ac97_update_bits(ac97, AC97_AD_TEST2,
34 1 << AC97_AD_HPFD_SHIFT, on << AC97_AD_HPFD_SHIFT);
35 if (err < 0) {
36 snd_printk(KERN_ERR "setting High Pass Filter - %d\n", err);
37 return;
38 }
39
40 /* set Analog Input through GPIO */
41 if (on)
42 geode_gpio_set(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
43 else
44 geode_gpio_clear(OLPC_GPIO_MIC_AC, GPIO_OUTPUT_VAL);
45}
46
47/*
48 * OLPC XO-1's V_REFOUT is a mic bias enable.
49 */
50void olpc_mic_bias(struct snd_ac97 *ac97, int on)
51{
52 int err;
53
54 if (!machine_is_olpc())
55 return;
56
57 on = on ? 0 : 1;
58 err = snd_ac97_update_bits(ac97, AC97_AD_MISC,
59 1 << AC97_AD_VREFD_SHIFT, on << AC97_AD_VREFD_SHIFT);
60 if (err < 0)
61 snd_printk(KERN_ERR "setting MIC Bias - %d\n", err);
62}
63
64static int olpc_dc_info(struct snd_kcontrol *kctl,
65 struct snd_ctl_elem_info *uinfo)
66{
67 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
68 uinfo->count = 1;
69 uinfo->value.integer.min = 0;
70 uinfo->value.integer.max = 1;
71 return 0;
72}
73
74static int olpc_dc_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
75{
76 v->value.integer.value[0] = geode_gpio_isset(OLPC_GPIO_MIC_AC,
77 GPIO_OUTPUT_VAL);
78 return 0;
79}
80
81static int olpc_dc_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
82{
83 struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
84
85 olpc_analog_input(cs5535au->ac97, v->value.integer.value[0]);
86 return 1;
87}
88
89static int olpc_mic_info(struct snd_kcontrol *kctl,
90 struct snd_ctl_elem_info *uinfo)
91{
92 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
93 uinfo->count = 1;
94 uinfo->value.integer.min = 0;
95 uinfo->value.integer.max = 1;
96 return 0;
97}
98
99static int olpc_mic_get(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
100{
101 struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
102 struct snd_ac97 *ac97 = cs5535au->ac97;
103 int i;
104
105 i = (snd_ac97_read(ac97, AC97_AD_MISC) >> AC97_AD_VREFD_SHIFT) & 0x1;
106 v->value.integer.value[0] = i ? 0 : 1;
107 return 0;
108}
109
110static int olpc_mic_put(struct snd_kcontrol *kctl, struct snd_ctl_elem_value *v)
111{
112 struct cs5535audio *cs5535au = snd_kcontrol_chip(kctl);
113
114 olpc_mic_bias(cs5535au->ac97, v->value.integer.value[0]);
115 return 1;
116}
117
118static struct snd_kcontrol_new olpc_cs5535audio_ctls[] __devinitdata = {
119{
120 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
121 .name = "DC Mode Enable",
122 .info = olpc_dc_info,
123 .get = olpc_dc_get,
124 .put = olpc_dc_put,
125 .private_value = 0,
126},
127{
128 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
129 .name = "MIC Bias Enable",
130 .info = olpc_mic_info,
131 .get = olpc_mic_get,
132 .put = olpc_mic_put,
133 .private_value = 0,
134},
135};
136
137void __devinit olpc_prequirks(struct snd_card *card,
138 struct snd_ac97_template *ac97)
139{
140 if (!machine_is_olpc())
141 return;
142
143 /* invert EAPD if on an OLPC B3 or higher */
144 if (olpc_board_at_least(olpc_board_pre(0xb3)))
145 ac97->scaps |= AC97_SCAP_INV_EAPD;
146}
147
148int __devinit olpc_quirks(struct snd_card *card, struct snd_ac97 *ac97)
149{
150 struct snd_ctl_elem_id elem;
151 int i, err;
152
153 if (!machine_is_olpc())
154 return 0;
155
156 /* drop the original AD1888 HPF control */
157 memset(&elem, 0, sizeof(elem));
158 elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
159 strncpy(elem.name, "High Pass Filter Enable", sizeof(elem.name));
160 snd_ctl_remove_id(card, &elem);
161
162 /* drop the original V_REFOUT control */
163 memset(&elem, 0, sizeof(elem));
164 elem.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
165 strncpy(elem.name, "V_REFOUT Enable", sizeof(elem.name));
166 snd_ctl_remove_id(card, &elem);
167
168 /* add the OLPC-specific controls */
169 for (i = 0; i < ARRAY_SIZE(olpc_cs5535audio_ctls); i++) {
170 err = snd_ctl_add(card, snd_ctl_new1(&olpc_cs5535audio_ctls[i],
171 ac97->private_data));
172 if (err < 0)
173 return err;
174 }
175
176 /* turn off the mic by default */
177 olpc_mic_bias(ac97, 0);
178 return 0;
179}
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c
index cdcda87116c3..0f48a871f17b 100644
--- a/sound/pci/cs5535audio/cs5535audio_pcm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pcm.c
@@ -260,6 +260,9 @@ static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream,
260 err = cs5535audio_build_dma_packets(cs5535au, dma, substream, 260 err = cs5535audio_build_dma_packets(cs5535au, dma, substream,
261 params_periods(hw_params), 261 params_periods(hw_params),
262 params_period_bytes(hw_params)); 262 params_period_bytes(hw_params));
263 if (!err)
264 dma->pcm_open_flag = 1;
265
263 return err; 266 return err;
264} 267}
265 268
@@ -268,6 +271,15 @@ static int snd_cs5535audio_hw_free(struct snd_pcm_substream *substream)
268 struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream); 271 struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
269 struct cs5535audio_dma *dma = substream->runtime->private_data; 272 struct cs5535audio_dma *dma = substream->runtime->private_data;
270 273
274 if (dma->pcm_open_flag) {
275 if (substream == cs5535au->playback_substream)
276 snd_ac97_update_power(cs5535au->ac97,
277 AC97_PCM_FRONT_DAC_RATE, 0);
278 else
279 snd_ac97_update_power(cs5535au->ac97,
280 AC97_PCM_LR_ADC_RATE, 0);
281 dma->pcm_open_flag = 0;
282 }
271 cs5535audio_clear_dma_packets(cs5535au, dma, substream); 283 cs5535audio_clear_dma_packets(cs5535au, dma, substream);
272 return snd_pcm_lib_free_pages(substream); 284 return snd_pcm_lib_free_pages(substream);
273} 285}
@@ -351,11 +363,14 @@ static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream)
351 if ((err = snd_pcm_hw_constraint_integer(runtime, 363 if ((err = snd_pcm_hw_constraint_integer(runtime,
352 SNDRV_PCM_HW_PARAM_PERIODS)) < 0) 364 SNDRV_PCM_HW_PARAM_PERIODS)) < 0)
353 return err; 365 return err;
366 olpc_capture_open(cs5535au->ac97);
354 return 0; 367 return 0;
355} 368}
356 369
357static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream) 370static int snd_cs5535audio_capture_close(struct snd_pcm_substream *substream)
358{ 371{
372 struct cs5535audio *cs5535au = snd_pcm_substream_chip(substream);
373 olpc_capture_close(cs5535au->ac97);
359 return 0; 374 return 0;
360} 375}
361 376
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index de5ee8f097f6..7958006a1d66 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -69,7 +69,7 @@ MODULE_FIRMWARE(EMU1010_NOTEBOOK_FILENAME);
69 * EMU10K1 init / done 69 * EMU10K1 init / done
70 *************************************************************************/ 70 *************************************************************************/
71 71
72void snd_emu10k1_voice_init(struct snd_emu10k1 * emu, int ch) 72void snd_emu10k1_voice_init(struct snd_emu10k1 *emu, int ch)
73{ 73{
74 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0); 74 snd_emu10k1_ptr_write(emu, DCYSUSV, ch, 0);
75 snd_emu10k1_ptr_write(emu, IP, ch, 0); 75 snd_emu10k1_ptr_write(emu, IP, ch, 0);
@@ -151,9 +151,9 @@ static unsigned int i2c_adc_init[][2] = {
151 { 0x12, 0x32 }, /* ALC Control 3 */ 151 { 0x12, 0x32 }, /* ALC Control 3 */
152 { 0x13, 0x00 }, /* Noise gate control */ 152 { 0x13, 0x00 }, /* Noise gate control */
153 { 0x14, 0xa6 }, /* Limiter control */ 153 { 0x14, 0xa6 }, /* Limiter control */
154 { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for Audigy 2 ZS Notebook */ 154 { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for A2ZS Notebook */
155}; 155};
156 156
157static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) 157static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
158{ 158{
159 unsigned int silent_page; 159 unsigned int silent_page;
@@ -161,8 +161,8 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
161 u32 tmp; 161 u32 tmp;
162 162
163 /* disable audio and lock cache */ 163 /* disable audio and lock cache */
164 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, 164 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK |
165 emu->port + HCFG); 165 HCFG_MUTEBUTTONENABLE, emu->port + HCFG);
166 166
167 /* reset recording buffers */ 167 /* reset recording buffers */
168 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE); 168 snd_emu10k1_ptr_write(emu, MICBS, 0, ADCBS_BUFSIZE_NONE);
@@ -179,7 +179,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
179 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0); 179 snd_emu10k1_ptr_write(emu, SOLEL, 0, 0);
180 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0); 180 snd_emu10k1_ptr_write(emu, SOLEH, 0, 0);
181 181
182 if (emu->audigy){ 182 if (emu->audigy) {
183 /* set SPDIF bypass mode */ 183 /* set SPDIF bypass mode */
184 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT); 184 snd_emu10k1_ptr_write(emu, SPBYPASS, 0, SPBYPASS_FORMAT);
185 /* enable rear left + rear right AC97 slots */ 185 /* enable rear left + rear right AC97 slots */
@@ -197,12 +197,12 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
197 197
198 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ 198 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
199 /* Hacks for Alice3 to work independent of haP16V driver */ 199 /* Hacks for Alice3 to work independent of haP16V driver */
200 //Setup SRCMulti_I2S SamplingRate 200 /* Setup SRCMulti_I2S SamplingRate */
201 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); 201 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
202 tmp &= 0xfffff1ff; 202 tmp &= 0xfffff1ff;
203 tmp |= (0x2<<9); 203 tmp |= (0x2<<9);
204 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp); 204 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, 0, tmp);
205 205
206 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */ 206 /* Setup SRCSel (Enable Spdif,I2S SRCMulti) */
207 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14); 207 snd_emu10k1_ptr20_write(emu, SRCSel, 0, 0x14);
208 /* Setup SRCMulti Input Audio Enable */ 208 /* Setup SRCMulti Input Audio Enable */
@@ -217,7 +217,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
217 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */ 217 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
218 /* Hacks for Alice3 to work independent of haP16V driver */ 218 /* Hacks for Alice3 to work independent of haP16V driver */
219 snd_printk(KERN_INFO "Audigy2 value: Special config.\n"); 219 snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
220 //Setup SRCMulti_I2S SamplingRate 220 /* Setup SRCMulti_I2S SamplingRate */
221 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); 221 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
222 tmp &= 0xfffff1ff; 222 tmp &= 0xfffff1ff;
223 tmp |= (0x2<<9); 223 tmp |= (0x2<<9);
@@ -270,13 +270,13 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
270 size = ARRAY_SIZE(i2c_adc_init); 270 size = ARRAY_SIZE(i2c_adc_init);
271 for (n = 0; n < size; n++) 271 for (n = 0; n < size; n++)
272 snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]); 272 snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]);
273 for (n=0; n < 4; n++) { 273 for (n = 0; n < 4; n++) {
274 emu->i2c_capture_volume[n][0]= 0xcf; 274 emu->i2c_capture_volume[n][0] = 0xcf;
275 emu->i2c_capture_volume[n][1]= 0xcf; 275 emu->i2c_capture_volume[n][1] = 0xcf;
276 } 276 }
277 } 277 }
278 278
279 279
280 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr); 280 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
281 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */ 281 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
282 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */ 282 snd_emu10k1_ptr_write(emu, TCBS, 0, 4); /* taken from original driver */
@@ -313,7 +313,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
313 (emu->model == 0x21 && emu->revision < 6)) 313 (emu->model == 0x21 && emu->revision < 6))
314 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG); 314 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE, emu->port + HCFG);
315 else 315 else
316 // With on-chip joystick 316 /* With on-chip joystick */
317 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); 317 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
318 318
319 if (enable_ir) { /* enable IR for SB Live */ 319 if (enable_ir) { /* enable IR for SB Live */
@@ -335,9 +335,9 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
335 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG); 335 outl(reg | HCFG_GPOUT1 | HCFG_GPOUT2, emu->port + HCFG);
336 udelay(100); 336 udelay(100);
337 outl(reg, emu->port + HCFG); 337 outl(reg, emu->port + HCFG);
338 } 338 }
339 } 339 }
340 340
341 if (emu->card_capabilities->emu_model) { 341 if (emu->card_capabilities->emu_model) {
342 ; /* Disable all access to A_IOCFG for the emu1010 */ 342 ; /* Disable all access to A_IOCFG for the emu1010 */
343 } else if (emu->card_capabilities->i2c_adc) { 343 } else if (emu->card_capabilities->i2c_adc) {
@@ -364,7 +364,7 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
364 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */ 364 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
365 } else if (emu->audigy) { 365 } else if (emu->audigy) {
366 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); 366 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
367 367
368 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ 368 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
369 /* Unmute Analog now. Set GPO6 to 1 for Apollo. 369 /* Unmute Analog now. Set GPO6 to 1 for Apollo.
370 * This has to be done after init ALice3 I2SOut beyond 48KHz. 370 * This has to be done after init ALice3 I2SOut beyond 48KHz.
@@ -378,12 +378,12 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
378 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG); 378 outl(inl(emu->port + A_IOCFG) | 0x0080, emu->port + A_IOCFG);
379 } 379 }
380 } 380 }
381 381
382#if 0 382#if 0
383 { 383 {
384 unsigned int tmp; 384 unsigned int tmp;
385 /* FIXME: the following routine disables LiveDrive-II !! */ 385 /* FIXME: the following routine disables LiveDrive-II !! */
386 // TOSLink detection 386 /* TOSLink detection */
387 emu->tos_link = 0; 387 emu->tos_link = 0;
388 tmp = inl(emu->port + HCFG); 388 tmp = inl(emu->port + HCFG);
389 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) { 389 if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
@@ -400,7 +400,7 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
400 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE); 400 snd_emu10k1_intr_enable(emu, INTE_PCIERRORENABLE);
401} 401}
402 402
403int snd_emu10k1_done(struct snd_emu10k1 * emu) 403int snd_emu10k1_done(struct snd_emu10k1 *emu)
404{ 404{
405 int ch; 405 int ch;
406 406
@@ -495,7 +495,7 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
495 495
496#define EC_LAST_PROMFILE_ADDR 0x2f 496#define EC_LAST_PROMFILE_ADDR 0x2f
497 497
498#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The 498#define EC_SERIALNUM_ADDR 0x30 /* First word of serial number. The
499 * can be up to 30 characters in length 499 * can be up to 30 characters in length
500 * and is stored as a NULL-terminated 500 * and is stored as a NULL-terminated
501 * ASCII string. Any unused bytes must be 501 * ASCII string. Any unused bytes must be
@@ -503,8 +503,8 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
503#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */ 503#define EC_CHECKSUM_ADDR 0x3f /* Location at which checksum is stored */
504 504
505 505
506/* Most of this stuff is pretty self-evident. According to the hardware 506/* Most of this stuff is pretty self-evident. According to the hardware
507 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC 507 * dudes, we need to leave the ADCCAL bit low in order to avoid a DC
508 * offset problem. Weird. 508 * offset problem. Weird.
509 */ 509 */
510#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \ 510#define EC_RAW_RUN_MODE (EC_DACMUTEN | EC_ADCRSTN | EC_TRIM_MUTEN | \
@@ -523,7 +523,7 @@ int snd_emu10k1_done(struct snd_emu10k1 * emu)
523 * register. 523 * register.
524 */ 524 */
525 525
526static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value) 526static void snd_emu10k1_ecard_write(struct snd_emu10k1 *emu, unsigned int value)
527{ 527{
528 unsigned short count; 528 unsigned short count;
529 unsigned int data; 529 unsigned int data;
@@ -561,7 +561,7 @@ static void snd_emu10k1_ecard_write(struct snd_emu10k1 * emu, unsigned int value
561 * channel. 561 * channel.
562 */ 562 */
563 563
564static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu, 564static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 *emu,
565 unsigned short gain) 565 unsigned short gain)
566{ 566{
567 unsigned int bit; 567 unsigned int bit;
@@ -574,7 +574,7 @@ static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
574 574
575 for (bit = (1 << 15); bit; bit >>= 1) { 575 for (bit = (1 << 15); bit; bit >>= 1) {
576 unsigned int value; 576 unsigned int value;
577 577
578 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA); 578 value = emu->ecard_ctrl & ~(EC_TRIM_CSN | EC_TRIM_SDATA);
579 579
580 if (gain & bit) 580 if (gain & bit)
@@ -589,7 +589,7 @@ static void snd_emu10k1_ecard_setadcgain(struct snd_emu10k1 * emu,
589 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl); 589 snd_emu10k1_ecard_write(emu, emu->ecard_ctrl);
590} 590}
591 591
592static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu) 592static int snd_emu10k1_ecard_init(struct snd_emu10k1 *emu)
593{ 593{
594 unsigned int hc_value; 594 unsigned int hc_value;
595 595
@@ -598,7 +598,7 @@ static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
598 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) | 598 EC_SPDIF0_SELECT(EC_DEFAULT_SPDIF0_SEL) |
599 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL); 599 EC_SPDIF1_SELECT(EC_DEFAULT_SPDIF1_SEL);
600 600
601 /* Step 0: Set the codec type in the hardware control register 601 /* Step 0: Set the codec type in the hardware control register
602 * and enable audio output */ 602 * and enable audio output */
603 hc_value = inl(emu->port + HCFG); 603 hc_value = inl(emu->port + HCFG);
604 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG); 604 outl(hc_value | HCFG_AUDIOENABLE | HCFG_CODECFORMAT_I2S, emu->port + HCFG);
@@ -629,7 +629,7 @@ static int snd_emu10k1_ecard_init(struct snd_emu10k1 * emu)
629 return 0; 629 return 0;
630} 630}
631 631
632static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu) 632static int snd_emu10k1_cardbus_init(struct snd_emu10k1 *emu)
633{ 633{
634 unsigned long special_port; 634 unsigned long special_port;
635 unsigned int value; 635 unsigned int value;
@@ -656,7 +656,7 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
656 return 0; 656 return 0;
657} 657}
658 658
659static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * filename) 659static int snd_emu1010_load_firmware(struct snd_emu10k1 *emu, const char *filename)
660{ 660{
661 int err; 661 int err;
662 int n, i; 662 int n, i;
@@ -666,11 +666,12 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
666 unsigned long flags; 666 unsigned long flags;
667 const struct firmware *fw_entry; 667 const struct firmware *fw_entry;
668 668
669 if ((err = request_firmware(&fw_entry, filename, &emu->pci->dev)) != 0) { 669 err = request_firmware(&fw_entry, filename, &emu->pci->dev);
670 snd_printk(KERN_ERR "firmware: %s not found. Err=%d\n",filename, err); 670 if (err != 0) {
671 snd_printk(KERN_ERR "firmware: %s not found. Err = %d\n", filename, err);
671 return err; 672 return err;
672 } 673 }
673 snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size); 674 snd_printk(KERN_INFO "firmware size = 0x%zx\n", fw_entry->size);
674 675
675 /* The FPGA is a Xilinx Spartan IIE XC2S50E */ 676 /* The FPGA is a Xilinx Spartan IIE XC2S50E */
676 /* GPIO7 -> FPGA PGMN 677 /* GPIO7 -> FPGA PGMN
@@ -685,13 +686,13 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
685 outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */ 686 outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */
686 write_post = inl(emu->port + A_IOCFG); 687 write_post = inl(emu->port + A_IOCFG);
687 udelay(100); /* Allow FPGA memory to clean */ 688 udelay(100); /* Allow FPGA memory to clean */
688 for(n = 0; n < fw_entry->size; n++) { 689 for (n = 0; n < fw_entry->size; n++) {
689 value=fw_entry->data[n]; 690 value = fw_entry->data[n];
690 for(i = 0; i < 8; i++) { 691 for (i = 0; i < 8; i++) {
691 reg = 0x80; 692 reg = 0x80;
692 if (value & 0x1) 693 if (value & 0x1)
693 reg = reg | 0x20; 694 reg = reg | 0x20;
694 value = value >> 1; 695 value = value >> 1;
695 outl(reg, emu->port + A_IOCFG); 696 outl(reg, emu->port + A_IOCFG);
696 write_post = inl(emu->port + A_IOCFG); 697 write_post = inl(emu->port + A_IOCFG);
697 outl(reg | 0x40, emu->port + A_IOCFG); 698 outl(reg | 0x40, emu->port + A_IOCFG);
@@ -703,14 +704,14 @@ static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * file
703 write_post = inl(emu->port + A_IOCFG); 704 write_post = inl(emu->port + A_IOCFG);
704 spin_unlock_irqrestore(&emu->emu_lock, flags); 705 spin_unlock_irqrestore(&emu->emu_lock, flags);
705 706
706 release_firmware(fw_entry); 707 release_firmware(fw_entry);
707 return 0; 708 return 0;
708} 709}
709 710
710static int emu1010_firmware_thread(void *data) 711static int emu1010_firmware_thread(void *data)
711{ 712{
712 struct snd_emu10k1 * emu = data; 713 struct snd_emu10k1 *emu = data;
713 int tmp,tmp2; 714 int tmp, tmp2;
714 int reg; 715 int reg;
715 int err; 716 int err;
716 717
@@ -719,50 +720,50 @@ static int emu1010_firmware_thread(void *data)
719 msleep_interruptible(1000); 720 msleep_interruptible(1000);
720 if (kthread_should_stop()) 721 if (kthread_should_stop())
721 break; 722 break;
722 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */ 723 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp); /* IRQ Status */
723 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); /* OPTIONS: Which cards are attached to the EMU */ 724 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg); /* OPTIONS: Which cards are attached to the EMU */
724 if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) { 725 if (reg & EMU_HANA_OPTION_DOCK_OFFLINE) {
725 /* Audio Dock attached */ 726 /* Audio Dock attached */
726 /* Return to Audio Dock programming mode */ 727 /* Return to Audio Dock programming mode */
727 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); 728 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
728 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); 729 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK);
729 if (emu->card_capabilities->emu_model == 730 if (emu->card_capabilities->emu_model ==
730 EMU_MODEL_EMU1010) { 731 EMU_MODEL_EMU1010) {
731 if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { 732 err = snd_emu1010_load_firmware(emu, DOCK_FILENAME);
733 if (err != 0)
732 continue; 734 continue;
733 }
734 } else if (emu->card_capabilities->emu_model == 735 } else if (emu->card_capabilities->emu_model ==
735 EMU_MODEL_EMU1010B) { 736 EMU_MODEL_EMU1010B) {
736 if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { 737 err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
738 if (err != 0)
737 continue; 739 continue;
738 }
739 } else if (emu->card_capabilities->emu_model == 740 } else if (emu->card_capabilities->emu_model ==
740 EMU_MODEL_EMU1616) { 741 EMU_MODEL_EMU1616) {
741 if ((err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME)) != 0) { 742 err = snd_emu1010_load_firmware(emu, MICRO_DOCK_FILENAME);
743 if (err != 0)
742 continue; 744 continue;
743 }
744 } 745 }
745 746
746 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); 747 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0);
747 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg ); 748 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg);
748 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg); 749 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS = 0x%x\n", reg);
749 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ 750 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
750 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 751 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
751 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg); 752 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID = 0x%x\n", reg);
752 if ((reg & 0x1f) != 0x15) { 753 if ((reg & 0x1f) != 0x15) {
753 /* FPGA failed to be programmed */ 754 /* FPGA failed to be programmed */
754 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg); 755 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg = 0x%x\n", reg);
755 continue; 756 continue;
756 } 757 }
757 snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n"); 758 snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
758 snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp ); 759 snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp);
759 snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 ); 760 snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2);
760 snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2); 761 snd_printk("Audio Dock ver:%d.%d\n", tmp, tmp2);
761 /* Sync clocking between 1010 and Dock */ 762 /* Sync clocking between 1010 and Dock */
762 /* Allow DLL to settle */ 763 /* Allow DLL to settle */
763 msleep(10); 764 msleep(10);
764 /* Unmute all. Default is muted after a firmware load */ 765 /* Unmute all. Default is muted after a firmware load */
765 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE ); 766 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE);
766 } 767 }
767 } 768 }
768 snd_printk(KERN_INFO "emu1010: firmware thread stopping\n"); 769 snd_printk(KERN_INFO "emu1010: firmware thread stopping\n");
@@ -800,10 +801,10 @@ static int emu1010_firmware_thread(void *data)
800 * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops 801 * 16 x 16-bit playback - snd_emu10k1_fx8010_playback_ops
801 * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops 802 * 16 x 32-bit capture - snd_emu10k1_capture_efx_ops
802 */ 803 */
803static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) 804static int snd_emu10k1_emu1010_init(struct snd_emu10k1 *emu)
804{ 805{
805 unsigned int i; 806 unsigned int i;
806 int tmp,tmp2; 807 int tmp, tmp2;
807 int reg; 808 int reg;
808 int err; 809 int err;
809 const char *filename = NULL; 810 const char *filename = NULL;
@@ -818,7 +819,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
818 * Lock Tank Memory Cache, 819 * Lock Tank Memory Cache,
819 * Mute all codecs. 820 * Mute all codecs.
820 */ 821 */
821 outl(0x0005a004, emu->port + HCFG); 822 outl(0x0005a004, emu->port + HCFG);
822 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, 823 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
823 * Mute all codecs. 824 * Mute all codecs.
824 */ 825 */
@@ -829,25 +830,25 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
829 outl(0x0005a000, emu->port + HCFG); 830 outl(0x0005a000, emu->port + HCFG);
830 831
831 /* Disable 48Volt power to Audio Dock */ 832 /* Disable 48Volt power to Audio Dock */
832 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); 833 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
833 834
834 /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */ 835 /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
835 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 836 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
836 snd_printdd("reg1=0x%x\n",reg); 837 snd_printdd("reg1 = 0x%x\n", reg);
837 if ((reg & 0x3f) == 0x15) { 838 if ((reg & 0x3f) == 0x15) {
838 /* FPGA netlist already present so clear it */ 839 /* FPGA netlist already present so clear it */
839 /* Return to programming mode */ 840 /* Return to programming mode */
840 841
841 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02 ); 842 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02);
842 } 843 }
843 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 844 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
844 snd_printdd("reg2=0x%x\n",reg); 845 snd_printdd("reg2 = 0x%x\n", reg);
845 if ((reg & 0x3f) == 0x15) { 846 if ((reg & 0x3f) == 0x15) {
846 /* FPGA failed to return to programming mode */ 847 /* FPGA failed to return to programming mode */
847 snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n"); 848 snd_printk(KERN_INFO "emu1010: FPGA failed to return to programming mode\n");
848 return -ENODEV; 849 return -ENODEV;
849 } 850 }
850 snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); 851 snd_printk(KERN_INFO "emu1010: EMU_HANA_ID = 0x%x\n", reg);
851 switch (emu->card_capabilities->emu_model) { 852 switch (emu->card_capabilities->emu_model) {
852 case EMU_MODEL_EMU1010: 853 case EMU_MODEL_EMU1010:
853 filename = HANA_FILENAME; 854 filename = HANA_FILENAME;
@@ -876,25 +877,25 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
876 } 877 }
877 878
878 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ 879 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
879 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg ); 880 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg);
880 if ((reg & 0x3f) != 0x15) { 881 if ((reg & 0x3f) != 0x15) {
881 /* FPGA failed to be programmed */ 882 /* FPGA failed to be programmed */
882 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg); 883 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg = 0x%x\n", reg);
883 return -ENODEV; 884 return -ENODEV;
884 } 885 }
885 886
886 snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n"); 887 snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n");
887 snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp ); 888 snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp);
888 snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2 ); 889 snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2);
889 snd_printk("Hana ver:%d.%d\n",tmp ,tmp2); 890 snd_printk("emu1010: Hana version: %d.%d\n", tmp, tmp2);
890 /* Enable 48Volt power to Audio Dock */ 891 /* Enable 48Volt power to Audio Dock */
891 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON ); 892 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON);
892 893
893 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); 894 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
894 snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); 895 snd_printk(KERN_INFO "emu1010: Card options = 0x%x\n", reg);
895 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); 896 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
896 snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); 897 snd_printk(KERN_INFO "emu1010: Card options = 0x%x\n", reg);
897 snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp ); 898 snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp);
898 /* Optical -> ADAT I/O */ 899 /* Optical -> ADAT I/O */
899 /* 0 : SPDIF 900 /* 0 : SPDIF
900 * 1 : ADAT 901 * 1 : ADAT
@@ -904,41 +905,42 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
904 tmp = 0; 905 tmp = 0;
905 tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) | 906 tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
906 (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0); 907 (emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
907 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp ); 908 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
908 snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp ); 909 snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp);
909 /* Set no attenuation on Audio Dock pads. */ 910 /* Set no attenuation on Audio Dock pads. */
910 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00 ); 911 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00);
911 emu->emu1010.adc_pads = 0x00; 912 emu->emu1010.adc_pads = 0x00;
912 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp ); 913 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
913 /* Unmute Audio dock DACs, Headphone source DAC-4. */ 914 /* Unmute Audio dock DACs, Headphone source DAC-4. */
914 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 ); 915 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
915 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 ); 916 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);
916 snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp ); 917 snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp);
917 /* DAC PADs. */ 918 /* DAC PADs. */
918 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f ); 919 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f);
919 emu->emu1010.dac_pads = 0x0f; 920 emu->emu1010.dac_pads = 0x0f;
920 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp ); 921 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp);
921 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 ); 922 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30);
922 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); 923 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp);
923 /* SPDIF Format. Set Consumer mode, 24bit, copy enable */ 924 /* SPDIF Format. Set Consumer mode, 24bit, copy enable */
924 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); 925 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10);
925 /* MIDI routing */ 926 /* MIDI routing */
926 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); 927 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19);
927 /* Unknown. */ 928 /* Unknown. */
928 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); 929 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c);
929 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); // IRQ Enable: All on */ 930 /* IRQ Enable: Alll on */
931 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); */
930 /* IRQ Enable: All off */ 932 /* IRQ Enable: All off */
931 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00 ); 933 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00);
932 934
933 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); 935 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg);
934 snd_printk(KERN_INFO "emu1010: Card options3=0x%x\n",reg); 936 snd_printk(KERN_INFO "emu1010: Card options3 = 0x%x\n", reg);
935 /* Default WCLK set to 48kHz. */ 937 /* Default WCLK set to 48kHz. */
936 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00 ); 938 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00);
937 /* Word Clock source, Internal 48kHz x1 */ 939 /* Word Clock source, Internal 48kHz x1 */
938 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); 940 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
939 //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); 941 /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
940 /* Audio Dock LEDs. */ 942 /* Audio Dock LEDs. */
941 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 ); 943 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);
942 944
943#if 0 945#if 0
944 /* For 96kHz */ 946 /* For 96kHz */
@@ -992,7 +994,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
992 * Defaults only, users will set their own values anyways, let's 994 * Defaults only, users will set their own values anyways, let's
993 * just copy/paste. 995 * just copy/paste.
994 */ 996 */
995 997
996 snd_emu1010_fpga_link_dst_src_write(emu, 998 snd_emu1010_fpga_link_dst_src_write(emu,
997 EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1); 999 EMU_DST_ALICE2_EMU32_8, EMU_SRC_DOCK_MIC_A1);
998 snd_emu1010_fpga_link_dst_src_write(emu, 1000 snd_emu1010_fpga_link_dst_src_write(emu,
@@ -1037,19 +1039,19 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
1037 snd_emu1010_fpga_link_dst_src_write(emu, 1039 snd_emu1010_fpga_link_dst_src_write(emu,
1038 EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2); 1040 EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2);
1039#endif 1041#endif
1040 for (i = 0;i < 0x20; i++ ) { 1042 for (i = 0; i < 0x20; i++) {
1041 /* AudioDock Elink <- Silence */ 1043 /* AudioDock Elink <- Silence */
1042 snd_emu1010_fpga_link_dst_src_write(emu, 0x0100+i, EMU_SRC_SILENCE); 1044 snd_emu1010_fpga_link_dst_src_write(emu, 0x0100 + i, EMU_SRC_SILENCE);
1043 } 1045 }
1044 for (i = 0;i < 4; i++) { 1046 for (i = 0; i < 4; i++) {
1045 /* Hana SPDIF Out <- Silence */ 1047 /* Hana SPDIF Out <- Silence */
1046 snd_emu1010_fpga_link_dst_src_write(emu, 0x0200+i, EMU_SRC_SILENCE); 1048 snd_emu1010_fpga_link_dst_src_write(emu, 0x0200 + i, EMU_SRC_SILENCE);
1047 } 1049 }
1048 for (i = 0;i < 7; i++) { 1050 for (i = 0; i < 7; i++) {
1049 /* Hamoa DAC <- Silence */ 1051 /* Hamoa DAC <- Silence */
1050 snd_emu1010_fpga_link_dst_src_write(emu, 0x0300+i, EMU_SRC_SILENCE); 1052 snd_emu1010_fpga_link_dst_src_write(emu, 0x0300 + i, EMU_SRC_SILENCE);
1051 } 1053 }
1052 for (i = 0;i < 7; i++) { 1054 for (i = 0; i < 7; i++) {
1053 /* Hana ADAT Out <- Silence */ 1055 /* Hana ADAT Out <- Silence */
1054 snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE); 1056 snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE);
1055 } 1057 }
@@ -1065,30 +1067,30 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
1065 EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1); 1067 EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1);
1066 snd_emu1010_fpga_link_dst_src_write(emu, 1068 snd_emu1010_fpga_link_dst_src_write(emu,
1067 EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1); 1069 EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1);
1068 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01 ); // Unmute all 1070 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01); /* Unmute all */
1071
1072 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
1069 1073
1070 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp );
1071
1072 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, 1074 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
1073 * Lock Sound Memory Cache, Lock Tank Memory Cache, 1075 * Lock Sound Memory Cache, Lock Tank Memory Cache,
1074 * Mute all codecs. 1076 * Mute all codecs.
1075 */ 1077 */
1076 outl(0x0000a000, emu->port + HCFG); 1078 outl(0x0000a000, emu->port + HCFG);
1077 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave, 1079 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
1078 * Lock Sound Memory Cache, Lock Tank Memory Cache, 1080 * Lock Sound Memory Cache, Lock Tank Memory Cache,
1079 * Un-Mute all codecs. 1081 * Un-Mute all codecs.
1080 */ 1082 */
1081 outl(0x0000a001, emu->port + HCFG); 1083 outl(0x0000a001, emu->port + HCFG);
1082 1084
1083 /* Initial boot complete. Now patches */ 1085 /* Initial boot complete. Now patches */
1084 1086
1085 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp ); 1087 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp);
1086 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); /* MIDI Route */ 1088 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
1087 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); /* Unknown */ 1089 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */
1088 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); /* MIDI Route */ 1090 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19); /* MIDI Route */
1089 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); /* Unknown */ 1091 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c); /* Unknown */
1090 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp ); 1092 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp);
1091 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */ 1093 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10); /* SPDIF Format spdif (or 0x11 for aes/ebu) */
1092 1094
1093 /* Start Micro/Audio Dock firmware loader thread */ 1095 /* Start Micro/Audio Dock firmware loader thread */
1094 if (!emu->emu1010.firmware_thread) { 1096 if (!emu->emu1010.firmware_thread) {
@@ -1218,20 +1220,20 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
1218 emu->emu1010.output_source[23] = 28; 1220 emu->emu1010.output_source[23] = 28;
1219 } 1221 }
1220 /* TEMP: Select SPDIF in/out */ 1222 /* TEMP: Select SPDIF in/out */
1221 //snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */ 1223 /* snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); */ /* Output spdif */
1222 1224
1223 /* TEMP: Select 48kHz SPDIF out */ 1225 /* TEMP: Select 48kHz SPDIF out */
1224 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */ 1226 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */
1225 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */ 1227 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */
1226 /* Word Clock source, Internal 48kHz x1 */ 1228 /* Word Clock source, Internal 48kHz x1 */
1227 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K ); 1229 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K);
1228 //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X ); 1230 /* snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X); */
1229 emu->emu1010.internal_clock = 1; /* 48000 */ 1231 emu->emu1010.internal_clock = 1; /* 48000 */
1230 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);/* Set LEDs on Audio Dock */ 1232 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12); /* Set LEDs on Audio Dock */
1231 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */ 1233 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */
1232 //snd_emu1010_fpga_write(emu, 0x7, 0x0); /* Mute all */ 1234 /* snd_emu1010_fpga_write(emu, 0x7, 0x0); */ /* Mute all */
1233 //snd_emu1010_fpga_write(emu, 0x7, 0x1); /* Unmute all */ 1235 /* snd_emu1010_fpga_write(emu, 0x7, 0x1); */ /* Unmute all */
1234 //snd_emu1010_fpga_write(emu, 0xe, 0x12); /* Set LEDs on Audio Dock */ 1236 /* snd_emu1010_fpga_write(emu, 0xe, 0x12); */ /* Set LEDs on Audio Dock */
1235 1237
1236 return 0; 1238 return 0;
1237} 1239}
@@ -1247,13 +1249,13 @@ static void free_pm_buffer(struct snd_emu10k1 *emu);
1247static int snd_emu10k1_free(struct snd_emu10k1 *emu) 1249static int snd_emu10k1_free(struct snd_emu10k1 *emu)
1248{ 1250{
1249 if (emu->port) { /* avoid access to already used hardware */ 1251 if (emu->port) { /* avoid access to already used hardware */
1250 snd_emu10k1_fx8010_tram_setup(emu, 0); 1252 snd_emu10k1_fx8010_tram_setup(emu, 0);
1251 snd_emu10k1_done(emu); 1253 snd_emu10k1_done(emu);
1252 snd_emu10k1_free_efx(emu); 1254 snd_emu10k1_free_efx(emu);
1253 } 1255 }
1254 if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) { 1256 if (emu->card_capabilities->emu_model == EMU_MODEL_EMU1010) {
1255 /* Disable 48Volt power to Audio Dock */ 1257 /* Disable 48Volt power to Audio Dock */
1256 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 ); 1258 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0);
1257 } 1259 }
1258 if (emu->emu1010.firmware_thread) 1260 if (emu->emu1010.firmware_thread)
1259 kthread_stop(emu->emu1010.firmware_thread); 1261 kthread_stop(emu->emu1010.firmware_thread);
@@ -1278,7 +1280,7 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
1278#endif 1280#endif
1279 if (emu->port) 1281 if (emu->port)
1280 pci_release_regions(emu->pci); 1282 pci_release_regions(emu->pci);
1281 if (emu->card_capabilities->ca0151_chip) /* P16V */ 1283 if (emu->card_capabilities->ca0151_chip) /* P16V */
1282 snd_p16v_free(emu); 1284 snd_p16v_free(emu);
1283 pci_disable_device(emu->pci); 1285 pci_disable_device(emu->pci);
1284 kfree(emu); 1286 kfree(emu);
@@ -1292,21 +1294,6 @@ static int snd_emu10k1_dev_free(struct snd_device *device)
1292} 1294}
1293 1295
1294static struct snd_emu_chip_details emu_chip_details[] = { 1296static struct snd_emu_chip_details emu_chip_details[] = {
1295 /* Audigy 2 Value AC3 out does not work yet. Need to find out how to turn off interpolators.*/
1296 /* Tested by James@superbug.co.uk 3rd July 2005 */
1297 /* DSP: CA0108-IAT
1298 * DAC: CS4382-KQ
1299 * ADC: Philips 1361T
1300 * AC97: STAC9750
1301 * CA0151: None
1302 */
1303 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
1304 .driver = "Audigy2", .name = "Audigy 2 Value [SB0400]",
1305 .id = "Audigy2",
1306 .emu10k2_chip = 1,
1307 .ca0108_chip = 1,
1308 .spk71 = 1,
1309 .ac97_chip = 1} ,
1310 /* Audigy4 (Not PRO) SB0610 */ 1297 /* Audigy4 (Not PRO) SB0610 */
1311 /* Tested by James@superbug.co.uk 4th April 2006 */ 1298 /* Tested by James@superbug.co.uk 4th April 2006 */
1312 /* A_IOCFG bits 1299 /* A_IOCFG bits
@@ -1346,20 +1333,37 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1346 * CA0151: None 1333 * CA0151: None
1347 */ 1334 */
1348 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102, 1335 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10211102,
1349 .driver = "Audigy2", .name = "Audigy 4 [SB0610]", 1336 .driver = "Audigy2", .name = "SB Audigy 4 [SB0610]",
1350 .id = "Audigy2", 1337 .id = "Audigy2",
1351 .emu10k2_chip = 1, 1338 .emu10k2_chip = 1,
1352 .ca0108_chip = 1, 1339 .ca0108_chip = 1,
1353 .spk71 = 1, 1340 .spk71 = 1,
1354 .adc_1361t = 1, /* 24 bit capture instead of 16bit */ 1341 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
1355 .ac97_chip = 1} , 1342 .ac97_chip = 1} ,
1343 /* Audigy 2 Value AC3 out does not work yet.
1344 * Need to find out how to turn off interpolators.
1345 */
1346 /* Tested by James@superbug.co.uk 3rd July 2005 */
1347 /* DSP: CA0108-IAT
1348 * DAC: CS4382-KQ
1349 * ADC: Philips 1361T
1350 * AC97: STAC9750
1351 * CA0151: None
1352 */
1353 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x10011102,
1354 .driver = "Audigy2", .name = "SB Audigy 2 Value [SB0400]",
1355 .id = "Audigy2",
1356 .emu10k2_chip = 1,
1357 .ca0108_chip = 1,
1358 .spk71 = 1,
1359 .ac97_chip = 1} ,
1356 /* Audigy 2 ZS Notebook Cardbus card.*/ 1360 /* Audigy 2 ZS Notebook Cardbus card.*/
1357 /* Tested by James@superbug.co.uk 6th November 2006 */ 1361 /* Tested by James@superbug.co.uk 6th November 2006 */
1358 /* Audio output 7.1/Headphones working. 1362 /* Audio output 7.1/Headphones working.
1359 * Digital output working. (AC3 not checked, only PCM) 1363 * Digital output working. (AC3 not checked, only PCM)
1360 * Audio Mic/Line inputs working. 1364 * Audio Mic/Line inputs working.
1361 * Digital input not tested. 1365 * Digital input not tested.
1362 */ 1366 */
1363 /* DSP: Tina2 1367 /* DSP: Tina2
1364 * DAC: Wolfson WM8768/WM8568 1368 * DAC: Wolfson WM8768/WM8568
1365 * ADC: Wolfson WM8775 1369 * ADC: Wolfson WM8775
@@ -1386,7 +1390,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1386 * 1390 *
1387 */ 1391 */
1388 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102, 1392 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
1389 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]", 1393 .driver = "Audigy2", .name = "SB Audigy 2 ZS Notebook [SB0530]",
1390 .id = "Audigy2", 1394 .id = "Audigy2",
1391 .emu10k2_chip = 1, 1395 .emu10k2_chip = 1,
1392 .ca0108_chip = 1, 1396 .ca0108_chip = 1,
@@ -1396,7 +1400,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1396 .spk71 = 1} , 1400 .spk71 = 1} ,
1397 /* Tested by James@superbug.co.uk 4th Nov 2007. */ 1401 /* Tested by James@superbug.co.uk 4th Nov 2007. */
1398 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102, 1402 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102,
1399 .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", 1403 .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]",
1400 .id = "EMU1010", 1404 .id = "EMU1010",
1401 .emu10k2_chip = 1, 1405 .emu10k2_chip = 1,
1402 .ca0108_chip = 1, 1406 .ca0108_chip = 1,
@@ -1404,47 +1408,49 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1404 .spk71 = 1 , 1408 .spk71 = 1 ,
1405 .emu_model = EMU_MODEL_EMU1616}, 1409 .emu_model = EMU_MODEL_EMU1616},
1406 /* Tested by James@superbug.co.uk 4th Nov 2007. */ 1410 /* Tested by James@superbug.co.uk 4th Nov 2007. */
1411 /* This is MAEM8960, 0202 is MAEM 8980 */
1407 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102, 1412 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40041102,
1408 .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM????]", 1413 .driver = "Audigy2", .name = "E-mu 1010b PCI [MAEM8960]",
1409 .id = "EMU1010", 1414 .id = "EMU1010",
1410 .emu10k2_chip = 1, 1415 .emu10k2_chip = 1,
1411 .ca0108_chip = 1, 1416 .ca0108_chip = 1,
1412 .spk71 = 1, 1417 .spk71 = 1,
1413 .emu_model = EMU_MODEL_EMU1010B}, 1418 .emu_model = EMU_MODEL_EMU1010B}, /* EMU 1010 new revision */
1414 /* Tested by James@superbug.co.uk 8th July 2005. */ 1419 /* Tested by James@superbug.co.uk 8th July 2005. */
1420 /* This is MAEM8810, 0202 is MAEM8820 */
1415 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, 1421 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
1416 .driver = "Audigy2", .name = "E-mu 1010 [4001]", 1422 .driver = "Audigy2", .name = "E-mu 1010 [MAEM8810]",
1417 .id = "EMU1010", 1423 .id = "EMU1010",
1418 .emu10k2_chip = 1, 1424 .emu10k2_chip = 1,
1419 .ca0102_chip = 1, 1425 .ca0102_chip = 1,
1420 .spk71 = 1, 1426 .spk71 = 1,
1421 .emu_model = EMU_MODEL_EMU1010}, /* Emu 1010 */ 1427 .emu_model = EMU_MODEL_EMU1010}, /* EMU 1010 old revision */
1422 /* EMU0404b */ 1428 /* EMU0404b */
1423 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102, 1429 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x40021102,
1424 .driver = "Audigy2", .name = "E-mu 0404b [4002]", 1430 .driver = "Audigy2", .name = "E-mu 0404b PCI [MAEM8852]",
1425 .id = "EMU0404", 1431 .id = "EMU0404",
1426 .emu10k2_chip = 1, 1432 .emu10k2_chip = 1,
1427 .ca0108_chip = 1, 1433 .ca0108_chip = 1,
1428 .spk71 = 1, 1434 .spk71 = 1,
1429 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */ 1435 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 new revision */
1430 /* Tested by James@superbug.co.uk 20-3-2007. */ 1436 /* Tested by James@superbug.co.uk 20-3-2007. */
1431 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102, 1437 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40021102,
1432 .driver = "Audigy2", .name = "E-mu 0404 [4002]", 1438 .driver = "Audigy2", .name = "E-mu 0404 [MAEM8850]",
1433 .id = "EMU0404", 1439 .id = "EMU0404",
1434 .emu10k2_chip = 1, 1440 .emu10k2_chip = 1,
1435 .ca0102_chip = 1, 1441 .ca0102_chip = 1,
1436 .spk71 = 1, 1442 .spk71 = 1,
1437 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */ 1443 .emu_model = EMU_MODEL_EMU0404}, /* EMU 0404 */
1438 /* Audigy4 (Not PRO) SB0610 */ 1444 /* Note that all E-mu cards require kernel 2.6 or newer. */
1439 {.vendor = 0x1102, .device = 0x0008, 1445 {.vendor = 0x1102, .device = 0x0008,
1440 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 1446 .driver = "Audigy2", .name = "SB Audigy 2 Value [Unknown]",
1441 .id = "Audigy2", 1447 .id = "Audigy2",
1442 .emu10k2_chip = 1, 1448 .emu10k2_chip = 1,
1443 .ca0108_chip = 1, 1449 .ca0108_chip = 1,
1444 .ac97_chip = 1} , 1450 .ac97_chip = 1} ,
1445 /* Tested by James@superbug.co.uk 3rd July 2005 */ 1451 /* Tested by James@superbug.co.uk 3rd July 2005 */
1446 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, 1452 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
1447 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", 1453 .driver = "Audigy2", .name = "SB Audigy 4 PRO [SB0380]",
1448 .id = "Audigy2", 1454 .id = "Audigy2",
1449 .emu10k2_chip = 1, 1455 .emu10k2_chip = 1,
1450 .ca0102_chip = 1, 1456 .ca0102_chip = 1,
@@ -1457,7 +1463,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1457 * Just like 0x20021102 1463 * Just like 0x20021102
1458 */ 1464 */
1459 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102, 1465 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20061102,
1460 .driver = "Audigy2", .name = "Audigy 2 [SB0350b]", 1466 .driver = "Audigy2", .name = "SB Audigy 2 [SB0350b]",
1461 .id = "Audigy2", 1467 .id = "Audigy2",
1462 .emu10k2_chip = 1, 1468 .emu10k2_chip = 1,
1463 .ca0102_chip = 1, 1469 .ca0102_chip = 1,
@@ -1467,7 +1473,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1467 .invert_shared_spdif = 1, /* digital/analog switch swapped */ 1473 .invert_shared_spdif = 1, /* digital/analog switch swapped */
1468 .ac97_chip = 1} , 1474 .ac97_chip = 1} ,
1469 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102, 1475 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20021102,
1470 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0350]", 1476 .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0350]",
1471 .id = "Audigy2", 1477 .id = "Audigy2",
1472 .emu10k2_chip = 1, 1478 .emu10k2_chip = 1,
1473 .ca0102_chip = 1, 1479 .ca0102_chip = 1,
@@ -1477,7 +1483,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1477 .invert_shared_spdif = 1, /* digital/analog switch swapped */ 1483 .invert_shared_spdif = 1, /* digital/analog switch swapped */
1478 .ac97_chip = 1} , 1484 .ac97_chip = 1} ,
1479 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102, 1485 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20011102,
1480 .driver = "Audigy2", .name = "Audigy 2 ZS [2001]", 1486 .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0360]",
1481 .id = "Audigy2", 1487 .id = "Audigy2",
1482 .emu10k2_chip = 1, 1488 .emu10k2_chip = 1,
1483 .ca0102_chip = 1, 1489 .ca0102_chip = 1,
@@ -1495,7 +1501,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1495 * CA0151: Yes 1501 * CA0151: Yes
1496 */ 1502 */
1497 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102, 1503 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10071102,
1498 .driver = "Audigy2", .name = "Audigy 2 [SB0240]", 1504 .driver = "Audigy2", .name = "SB Audigy 2 [SB0240]",
1499 .id = "Audigy2", 1505 .id = "Audigy2",
1500 .emu10k2_chip = 1, 1506 .emu10k2_chip = 1,
1501 .ca0102_chip = 1, 1507 .ca0102_chip = 1,
@@ -1505,7 +1511,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1505 .adc_1361t = 1, /* 24 bit capture instead of 16bit */ 1511 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
1506 .ac97_chip = 1} , 1512 .ac97_chip = 1} ,
1507 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102, 1513 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10051102,
1508 .driver = "Audigy2", .name = "Audigy 2 EX [1005]", 1514 .driver = "Audigy2", .name = "SB Audigy 2 Platinum EX [SB0280]",
1509 .id = "Audigy2", 1515 .id = "Audigy2",
1510 .emu10k2_chip = 1, 1516 .emu10k2_chip = 1,
1511 .ca0102_chip = 1, 1517 .ca0102_chip = 1,
@@ -1515,7 +1521,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1515 /* Dell OEM/Creative Labs Audigy 2 ZS */ 1521 /* Dell OEM/Creative Labs Audigy 2 ZS */
1516 /* See ALSA bug#1365 */ 1522 /* See ALSA bug#1365 */
1517 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10031102, 1523 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10031102,
1518 .driver = "Audigy2", .name = "Audigy 2 ZS [SB0353]", 1524 .driver = "Audigy2", .name = "SB Audigy 2 ZS [SB0353]",
1519 .id = "Audigy2", 1525 .id = "Audigy2",
1520 .emu10k2_chip = 1, 1526 .emu10k2_chip = 1,
1521 .ca0102_chip = 1, 1527 .ca0102_chip = 1,
@@ -1524,7 +1530,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1524 .spdif_bug = 1, 1530 .spdif_bug = 1,
1525 .ac97_chip = 1} , 1531 .ac97_chip = 1} ,
1526 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102, 1532 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x10021102,
1527 .driver = "Audigy2", .name = "Audigy 2 Platinum [SB0240P]", 1533 .driver = "Audigy2", .name = "SB Audigy 2 Platinum [SB0240P]",
1528 .id = "Audigy2", 1534 .id = "Audigy2",
1529 .emu10k2_chip = 1, 1535 .emu10k2_chip = 1,
1530 .ca0102_chip = 1, 1536 .ca0102_chip = 1,
@@ -1535,7 +1541,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1535 .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */ 1541 .adc_1361t = 1, /* 24 bit capture instead of 16bit. Fixes ALSA bug#324 */
1536 .ac97_chip = 1} , 1542 .ac97_chip = 1} ,
1537 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04, 1543 {.vendor = 0x1102, .device = 0x0004, .revision = 0x04,
1538 .driver = "Audigy2", .name = "Audigy 2 [Unknown]", 1544 .driver = "Audigy2", .name = "SB Audigy 2 [Unknown]",
1539 .id = "Audigy2", 1545 .id = "Audigy2",
1540 .emu10k2_chip = 1, 1546 .emu10k2_chip = 1,
1541 .ca0102_chip = 1, 1547 .ca0102_chip = 1,
@@ -1543,78 +1549,79 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1543 .spdif_bug = 1, 1549 .spdif_bug = 1,
1544 .ac97_chip = 1} , 1550 .ac97_chip = 1} ,
1545 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102, 1551 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00531102,
1546 .driver = "Audigy", .name = "Audigy 1 [SB0090]", 1552 .driver = "Audigy", .name = "SB Audigy 1 [SB0092]",
1547 .id = "Audigy", 1553 .id = "Audigy",
1548 .emu10k2_chip = 1, 1554 .emu10k2_chip = 1,
1549 .ca0102_chip = 1, 1555 .ca0102_chip = 1,
1550 .ac97_chip = 1} , 1556 .ac97_chip = 1} ,
1551 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102, 1557 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00521102,
1552 .driver = "Audigy", .name = "Audigy 1 ES [SB0160]", 1558 .driver = "Audigy", .name = "SB Audigy 1 ES [SB0160]",
1553 .id = "Audigy", 1559 .id = "Audigy",
1554 .emu10k2_chip = 1, 1560 .emu10k2_chip = 1,
1555 .ca0102_chip = 1, 1561 .ca0102_chip = 1,
1556 .spdif_bug = 1, 1562 .spdif_bug = 1,
1557 .ac97_chip = 1} , 1563 .ac97_chip = 1} ,
1558 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102, 1564 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x00511102,
1559 .driver = "Audigy", .name = "Audigy 1 [SB0090]", 1565 .driver = "Audigy", .name = "SB Audigy 1 [SB0090]",
1560 .id = "Audigy", 1566 .id = "Audigy",
1561 .emu10k2_chip = 1, 1567 .emu10k2_chip = 1,
1562 .ca0102_chip = 1, 1568 .ca0102_chip = 1,
1563 .ac97_chip = 1} , 1569 .ac97_chip = 1} ,
1564 {.vendor = 0x1102, .device = 0x0004, 1570 {.vendor = 0x1102, .device = 0x0004,
1565 .driver = "Audigy", .name = "Audigy 1 [Unknown]", 1571 .driver = "Audigy", .name = "Audigy 1 [Unknown]",
1566 .id = "Audigy", 1572 .id = "Audigy",
1567 .emu10k2_chip = 1, 1573 .emu10k2_chip = 1,
1568 .ca0102_chip = 1, 1574 .ca0102_chip = 1,
1569 .ac97_chip = 1} , 1575 .ac97_chip = 1} ,
1570 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806B1102, 1576 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
1571 .driver = "EMU10K1", .name = "SBLive! [SB0105]", 1577 .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0220]",
1578 .id = "Live",
1579 .emu10k1_chip = 1,
1580 .ac97_chip = 1,
1581 .sblive51 = 1} ,
1582 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806b1102,
1583 .driver = "EMU10K1", .name = "SB Live! [SB0105]",
1572 .id = "Live", 1584 .id = "Live",
1573 .emu10k1_chip = 1, 1585 .emu10k1_chip = 1,
1574 .ac97_chip = 1, 1586 .ac97_chip = 1,
1575 .sblive51 = 1} , 1587 .sblive51 = 1} ,
1576 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806A1102, 1588 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x806a1102,
1577 .driver = "EMU10K1", .name = "SBLive! Value [SB0103]", 1589 .driver = "EMU10K1", .name = "SB Live! Value [SB0103]",
1578 .id = "Live", 1590 .id = "Live",
1579 .emu10k1_chip = 1, 1591 .emu10k1_chip = 1,
1580 .ac97_chip = 1, 1592 .ac97_chip = 1,
1581 .sblive51 = 1} , 1593 .sblive51 = 1} ,
1582 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102, 1594 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80691102,
1583 .driver = "EMU10K1", .name = "SBLive! Value [SB0101]", 1595 .driver = "EMU10K1", .name = "SB Live! Value [SB0101]",
1584 .id = "Live", 1596 .id = "Live",
1585 .emu10k1_chip = 1, 1597 .emu10k1_chip = 1,
1586 .ac97_chip = 1, 1598 .ac97_chip = 1,
1587 .sblive51 = 1} , 1599 .sblive51 = 1} ,
1588 /* Tested by ALSA bug#1680 26th December 2005 */ 1600 /* Tested by ALSA bug#1680 26th December 2005 */
1589 /* note: It really has SB0220 written on the card. */ 1601 /* note: It really has SB0220 written on the card, */
1602 /* but it's SB0228 according to kx.inf */
1590 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80661102, 1603 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80661102,
1591 .driver = "EMU10K1", .name = "SB Live 5.1 Dell OEM [SB0220]", 1604 .driver = "EMU10K1", .name = "SB Live! 5.1 Dell OEM [SB0228]",
1592 .id = "Live", 1605 .id = "Live",
1593 .emu10k1_chip = 1, 1606 .emu10k1_chip = 1,
1594 .ac97_chip = 1, 1607 .ac97_chip = 1,
1595 .sblive51 = 1} , 1608 .sblive51 = 1} ,
1596 /* Tested by Thomas Zehetbauer 27th Aug 2005 */ 1609 /* Tested by Thomas Zehetbauer 27th Aug 2005 */
1597 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102, 1610 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80651102,
1598 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]", 1611 .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0220]",
1599 .id = "Live",
1600 .emu10k1_chip = 1,
1601 .ac97_chip = 1,
1602 .sblive51 = 1} ,
1603 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x100a1102,
1604 .driver = "EMU10K1", .name = "SB Live 5.1 [SB0220]",
1605 .id = "Live", 1612 .id = "Live",
1606 .emu10k1_chip = 1, 1613 .emu10k1_chip = 1,
1607 .ac97_chip = 1, 1614 .ac97_chip = 1,
1608 .sblive51 = 1} , 1615 .sblive51 = 1} ,
1609 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102, 1616 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80641102,
1610 .driver = "EMU10K1", .name = "SB Live 5.1", 1617 .driver = "EMU10K1", .name = "SB Live! 5.1",
1611 .id = "Live", 1618 .id = "Live",
1612 .emu10k1_chip = 1, 1619 .emu10k1_chip = 1,
1613 .ac97_chip = 1, 1620 .ac97_chip = 1,
1614 .sblive51 = 1} , 1621 .sblive51 = 1} ,
1615 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */ 1622 /* Tested by alsa bugtrack user "hus" bug #1297 12th Aug 2005 */
1616 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102, 1623 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80611102,
1617 .driver = "EMU10K1", .name = "SBLive 5.1 [SB0060]", 1624 .driver = "EMU10K1", .name = "SB Live! 5.1 [SB0060]",
1618 .id = "Live", 1625 .id = "Live",
1619 .emu10k1_chip = 1, 1626 .emu10k1_chip = 1,
1620 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum 1627 .ac97_chip = 2, /* ac97 is optional; both SBLive 5.1 and platinum
@@ -1622,78 +1629,78 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1622 */ 1629 */
1623 .sblive51 = 1} , 1630 .sblive51 = 1} ,
1624 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102, 1631 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80511102,
1625 .driver = "EMU10K1", .name = "SBLive! Value [CT4850]", 1632 .driver = "EMU10K1", .name = "SB Live! Value [CT4850]",
1626 .id = "Live", 1633 .id = "Live",
1627 .emu10k1_chip = 1, 1634 .emu10k1_chip = 1,
1628 .ac97_chip = 1, 1635 .ac97_chip = 1,
1629 .sblive51 = 1} , 1636 .sblive51 = 1} ,
1630 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102, 1637 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80401102,
1631 .driver = "EMU10K1", .name = "SBLive! Platinum [CT4760P]", 1638 .driver = "EMU10K1", .name = "SB Live! Platinum [CT4760P]",
1632 .id = "Live", 1639 .id = "Live",
1633 .emu10k1_chip = 1, 1640 .emu10k1_chip = 1,
1634 .ac97_chip = 1} , 1641 .ac97_chip = 1} ,
1635 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102, 1642 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80321102,
1636 .driver = "EMU10K1", .name = "SBLive! Value [CT4871]", 1643 .driver = "EMU10K1", .name = "SB Live! Value [CT4871]",
1637 .id = "Live", 1644 .id = "Live",
1638 .emu10k1_chip = 1, 1645 .emu10k1_chip = 1,
1639 .ac97_chip = 1, 1646 .ac97_chip = 1,
1640 .sblive51 = 1} , 1647 .sblive51 = 1} ,
1641 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102, 1648 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80311102,
1642 .driver = "EMU10K1", .name = "SBLive! Value [CT4831]", 1649 .driver = "EMU10K1", .name = "SB Live! Value [CT4831]",
1643 .id = "Live", 1650 .id = "Live",
1644 .emu10k1_chip = 1, 1651 .emu10k1_chip = 1,
1645 .ac97_chip = 1, 1652 .ac97_chip = 1,
1646 .sblive51 = 1} , 1653 .sblive51 = 1} ,
1647 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102, 1654 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80281102,
1648 .driver = "EMU10K1", .name = "SBLive! Value [CT4870]", 1655 .driver = "EMU10K1", .name = "SB Live! Value [CT4870]",
1649 .id = "Live", 1656 .id = "Live",
1650 .emu10k1_chip = 1, 1657 .emu10k1_chip = 1,
1651 .ac97_chip = 1, 1658 .ac97_chip = 1,
1652 .sblive51 = 1} , 1659 .sblive51 = 1} ,
1653 /* Tested by James@superbug.co.uk 3rd July 2005 */ 1660 /* Tested by James@superbug.co.uk 3rd July 2005 */
1654 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102, 1661 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80271102,
1655 .driver = "EMU10K1", .name = "SBLive! Value [CT4832]", 1662 .driver = "EMU10K1", .name = "SB Live! Value [CT4832]",
1656 .id = "Live", 1663 .id = "Live",
1657 .emu10k1_chip = 1, 1664 .emu10k1_chip = 1,
1658 .ac97_chip = 1, 1665 .ac97_chip = 1,
1659 .sblive51 = 1} , 1666 .sblive51 = 1} ,
1660 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102, 1667 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80261102,
1661 .driver = "EMU10K1", .name = "SBLive! Value [CT4830]", 1668 .driver = "EMU10K1", .name = "SB Live! Value [CT4830]",
1662 .id = "Live", 1669 .id = "Live",
1663 .emu10k1_chip = 1, 1670 .emu10k1_chip = 1,
1664 .ac97_chip = 1, 1671 .ac97_chip = 1,
1665 .sblive51 = 1} , 1672 .sblive51 = 1} ,
1666 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102, 1673 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80231102,
1667 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]", 1674 .driver = "EMU10K1", .name = "SB PCI512 [CT4790]",
1668 .id = "Live", 1675 .id = "Live",
1669 .emu10k1_chip = 1, 1676 .emu10k1_chip = 1,
1670 .ac97_chip = 1, 1677 .ac97_chip = 1,
1671 .sblive51 = 1} , 1678 .sblive51 = 1} ,
1672 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102, 1679 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x80221102,
1673 .driver = "EMU10K1", .name = "SBLive! Value [CT4780]", 1680 .driver = "EMU10K1", .name = "SB Live! Value [CT4780]",
1674 .id = "Live", 1681 .id = "Live",
1675 .emu10k1_chip = 1, 1682 .emu10k1_chip = 1,
1676 .ac97_chip = 1, 1683 .ac97_chip = 1,
1677 .sblive51 = 1} , 1684 .sblive51 = 1} ,
1678 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102, 1685 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x40011102,
1679 .driver = "EMU10K1", .name = "E-mu APS [4001]", 1686 .driver = "EMU10K1", .name = "E-mu APS [PC545]",
1680 .id = "APS", 1687 .id = "APS",
1681 .emu10k1_chip = 1, 1688 .emu10k1_chip = 1,
1682 .ecard = 1} , 1689 .ecard = 1} ,
1683 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102, 1690 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00211102,
1684 .driver = "EMU10K1", .name = "SBLive! [CT4620]", 1691 .driver = "EMU10K1", .name = "SB Live! [CT4620]",
1685 .id = "Live", 1692 .id = "Live",
1686 .emu10k1_chip = 1, 1693 .emu10k1_chip = 1,
1687 .ac97_chip = 1, 1694 .ac97_chip = 1,
1688 .sblive51 = 1} , 1695 .sblive51 = 1} ,
1689 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102, 1696 {.vendor = 0x1102, .device = 0x0002, .subsystem = 0x00201102,
1690 .driver = "EMU10K1", .name = "SBLive! Value [CT4670]", 1697 .driver = "EMU10K1", .name = "SB Live! Value [CT4670]",
1691 .id = "Live", 1698 .id = "Live",
1692 .emu10k1_chip = 1, 1699 .emu10k1_chip = 1,
1693 .ac97_chip = 1, 1700 .ac97_chip = 1,
1694 .sblive51 = 1} , 1701 .sblive51 = 1} ,
1695 {.vendor = 0x1102, .device = 0x0002, 1702 {.vendor = 0x1102, .device = 0x0002,
1696 .driver = "EMU10K1", .name = "SB Live [Unknown]", 1703 .driver = "EMU10K1", .name = "SB Live! [Unknown]",
1697 .id = "Live", 1704 .id = "Live",
1698 .emu10k1_chip = 1, 1705 .emu10k1_chip = 1,
1699 .ac97_chip = 1, 1706 .ac97_chip = 1,
@@ -1702,13 +1709,13 @@ static struct snd_emu_chip_details emu_chip_details[] = {
1702}; 1709};
1703 1710
1704int __devinit snd_emu10k1_create(struct snd_card *card, 1711int __devinit snd_emu10k1_create(struct snd_card *card,
1705 struct pci_dev * pci, 1712 struct pci_dev *pci,
1706 unsigned short extin_mask, 1713 unsigned short extin_mask,
1707 unsigned short extout_mask, 1714 unsigned short extout_mask,
1708 long max_cache_bytes, 1715 long max_cache_bytes,
1709 int enable_ir, 1716 int enable_ir,
1710 uint subsystem, 1717 uint subsystem,
1711 struct snd_emu10k1 ** remu) 1718 struct snd_emu10k1 **remu)
1712{ 1719{
1713 struct snd_emu10k1 *emu; 1720 struct snd_emu10k1 *emu;
1714 int idx, err; 1721 int idx, err;
@@ -1718,11 +1725,12 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1718 static struct snd_device_ops ops = { 1725 static struct snd_device_ops ops = {
1719 .dev_free = snd_emu10k1_dev_free, 1726 .dev_free = snd_emu10k1_dev_free,
1720 }; 1727 };
1721 1728
1722 *remu = NULL; 1729 *remu = NULL;
1723 1730
1724 /* enable PCI device */ 1731 /* enable PCI device */
1725 if ((err = pci_enable_device(pci)) < 0) 1732 err = pci_enable_device(pci);
1733 if (err < 0)
1726 return err; 1734 return err;
1727 1735
1728 emu = kzalloc(sizeof(*emu), GFP_KERNEL); 1736 emu = kzalloc(sizeof(*emu), GFP_KERNEL);
@@ -1749,16 +1757,17 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1749 emu->revision = pci->revision; 1757 emu->revision = pci->revision;
1750 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial); 1758 pci_read_config_dword(pci, PCI_SUBSYSTEM_VENDOR_ID, &emu->serial);
1751 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model); 1759 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &emu->model);
1752 snd_printdd("vendor=0x%x, device=0x%x, subsystem_vendor_id=0x%x, subsystem_id=0x%x\n",pci->vendor, pci->device, emu->serial, emu->model); 1760 snd_printdd("vendor = 0x%x, device = 0x%x, subsystem_vendor_id = 0x%x, subsystem_id = 0x%x\n", pci->vendor, pci->device, emu->serial, emu->model);
1753 1761
1754 for (c = emu_chip_details; c->vendor; c++) { 1762 for (c = emu_chip_details; c->vendor; c++) {
1755 if (c->vendor == pci->vendor && c->device == pci->device) { 1763 if (c->vendor == pci->vendor && c->device == pci->device) {
1756 if (subsystem) { 1764 if (subsystem) {
1757 if (c->subsystem && (c->subsystem == subsystem) ) { 1765 if (c->subsystem && (c->subsystem == subsystem))
1758 break; 1766 break;
1759 } else continue; 1767 else
1768 continue;
1760 } else { 1769 } else {
1761 if (c->subsystem && (c->subsystem != emu->serial) ) 1770 if (c->subsystem && (c->subsystem != emu->serial))
1762 continue; 1771 continue;
1763 if (c->revision && c->revision != emu->revision) 1772 if (c->revision && c->revision != emu->revision)
1764 continue; 1773 continue;
@@ -1774,14 +1783,18 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1774 } 1783 }
1775 emu->card_capabilities = c; 1784 emu->card_capabilities = c;
1776 if (c->subsystem && !subsystem) 1785 if (c->subsystem && !subsystem)
1777 snd_printdd("Sound card name=%s\n", c->name); 1786 snd_printdd("Sound card name = %s\n", c->name);
1778 else if (subsystem) 1787 else if (subsystem)
1779 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x. Forced to subsytem=0x%x\n", 1788 snd_printdd("Sound card name = %s, "
1780 c->name, pci->vendor, pci->device, emu->serial, c->subsystem); 1789 "vendor = 0x%x, device = 0x%x, subsystem = 0x%x. "
1781 else 1790 "Forced to subsytem = 0x%x\n", c->name,
1782 snd_printdd("Sound card name=%s, vendor=0x%x, device=0x%x, subsystem=0x%x.\n", 1791 pci->vendor, pci->device, emu->serial, c->subsystem);
1783 c->name, pci->vendor, pci->device, emu->serial); 1792 else
1784 1793 snd_printdd("Sound card name = %s, "
1794 "vendor = 0x%x, device = 0x%x, subsystem = 0x%x.\n",
1795 c->name, pci->vendor, pci->device,
1796 emu->serial);
1797
1785 if (!*card->id && c->id) { 1798 if (!*card->id && c->id) {
1786 int i, n = 0; 1799 int i, n = 0;
1787 strlcpy(card->id, c->id, sizeof(card->id)); 1800 strlcpy(card->id, c->id, sizeof(card->id));
@@ -1815,7 +1828,8 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1815 else 1828 else
1816 emu->gpr_base = FXGPREGBASE; 1829 emu->gpr_base = FXGPREGBASE;
1817 1830
1818 if ((err = pci_request_regions(pci, "EMU10K1")) < 0) { 1831 err = pci_request_regions(pci, "EMU10K1");
1832 if (err < 0) {
1819 kfree(emu); 1833 kfree(emu);
1820 pci_disable_device(pci); 1834 pci_disable_device(pci);
1821 return err; 1835 return err;
@@ -1862,21 +1876,25 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1862 emu->enable_ir = enable_ir; 1876 emu->enable_ir = enable_ir;
1863 1877
1864 if (emu->card_capabilities->ca_cardbus_chip) { 1878 if (emu->card_capabilities->ca_cardbus_chip) {
1865 if ((err = snd_emu10k1_cardbus_init(emu)) < 0) 1879 err = snd_emu10k1_cardbus_init(emu);
1880 if (err < 0)
1866 goto error; 1881 goto error;
1867 } 1882 }
1868 if (emu->card_capabilities->ecard) { 1883 if (emu->card_capabilities->ecard) {
1869 if ((err = snd_emu10k1_ecard_init(emu)) < 0) 1884 err = snd_emu10k1_ecard_init(emu);
1885 if (err < 0)
1870 goto error; 1886 goto error;
1871 } else if (emu->card_capabilities->emu_model) { 1887 } else if (emu->card_capabilities->emu_model) {
1872 if ((err = snd_emu10k1_emu1010_init(emu)) < 0) { 1888 err = snd_emu10k1_emu1010_init(emu);
1873 snd_emu10k1_free(emu); 1889 if (err < 0) {
1874 return err; 1890 snd_emu10k1_free(emu);
1875 } 1891 return err;
1892 }
1876 } else { 1893 } else {
1877 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version 1894 /* 5.1: Enable the additional AC97 Slots. If the emu10k1 version
1878 does not support this, it shouldn't do any harm */ 1895 does not support this, it shouldn't do any harm */
1879 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); 1896 snd_emu10k1_ptr_write(emu, AC97SLOT, 0,
1897 AC97SLOT_CNTR|AC97SLOT_LFE);
1880 } 1898 }
1881 1899
1882 /* initialize TRAM setup */ 1900 /* initialize TRAM setup */
@@ -1916,7 +1934,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1916 snd_emu10k1_synth_alloc(emu, 4096); 1934 snd_emu10k1_synth_alloc(emu, 4096);
1917 if (emu->reserved_page) 1935 if (emu->reserved_page)
1918 emu->reserved_page->map_locked = 1; 1936 emu->reserved_page->map_locked = 1;
1919 1937
1920 /* Clear silent pages and set up pointers */ 1938 /* Clear silent pages and set up pointers */
1921 memset(emu->silent_page.area, 0, PAGE_SIZE); 1939 memset(emu->silent_page.area, 0, PAGE_SIZE);
1922 silent_page = emu->silent_page.addr << 1; 1940 silent_page = emu->silent_page.addr << 1;
@@ -1929,19 +1947,23 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1929 emu->voices[idx].number = idx; 1947 emu->voices[idx].number = idx;
1930 } 1948 }
1931 1949
1932 if ((err = snd_emu10k1_init(emu, enable_ir, 0)) < 0) 1950 err = snd_emu10k1_init(emu, enable_ir, 0);
1951 if (err < 0)
1933 goto error; 1952 goto error;
1934#ifdef CONFIG_PM 1953#ifdef CONFIG_PM
1935 if ((err = alloc_pm_buffer(emu)) < 0) 1954 err = alloc_pm_buffer(emu);
1955 if (err < 0)
1936 goto error; 1956 goto error;
1937#endif 1957#endif
1938 1958
1939 /* Initialize the effect engine */ 1959 /* Initialize the effect engine */
1940 if ((err = snd_emu10k1_init_efx(emu)) < 0) 1960 err = snd_emu10k1_init_efx(emu);
1961 if (err < 0)
1941 goto error; 1962 goto error;
1942 snd_emu10k1_audio_enable(emu); 1963 snd_emu10k1_audio_enable(emu);
1943 1964
1944 if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops)) < 0) 1965 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, emu, &ops);
1966 if (err < 0)
1945 goto error; 1967 goto error;
1946 1968
1947#ifdef CONFIG_PROC_FS 1969#ifdef CONFIG_PROC_FS
@@ -1981,7 +2003,7 @@ static int __devinit alloc_pm_buffer(struct snd_emu10k1 *emu)
1981 if (emu->audigy) 2003 if (emu->audigy)
1982 size += ARRAY_SIZE(saved_regs_audigy); 2004 size += ARRAY_SIZE(saved_regs_audigy);
1983 emu->saved_ptr = vmalloc(4 * NUM_G * size); 2005 emu->saved_ptr = vmalloc(4 * NUM_G * size);
1984 if (! emu->saved_ptr) 2006 if (!emu->saved_ptr)
1985 return -ENOMEM; 2007 return -ENOMEM;
1986 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0) 2008 if (snd_emu10k1_efx_alloc_pm_buffer(emu) < 0)
1987 return -ENOMEM; 2009 return -ENOMEM;
@@ -2026,7 +2048,7 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
2026 if (emu->card_capabilities->ecard) 2048 if (emu->card_capabilities->ecard)
2027 snd_emu10k1_ecard_init(emu); 2049 snd_emu10k1_ecard_init(emu);
2028 else if (emu->card_capabilities->emu_model) 2050 else if (emu->card_capabilities->emu_model)
2029 snd_emu10k1_emu1010_init(emu); 2051 snd_emu10k1_emu1010_init(emu);
2030 else 2052 else
2031 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); 2053 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
2032 snd_emu10k1_init(emu, emu->enable_ir, 1); 2054 snd_emu10k1_init(emu, emu->enable_ir, 1);
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index f34bbfb705f5..b0fb6c917c38 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -1639,6 +1639,45 @@ static struct snd_kcontrol_new snd_audigy_shared_spdif __devinitdata =
1639 .put = snd_emu10k1_shared_spdif_put 1639 .put = snd_emu10k1_shared_spdif_put
1640}; 1640};
1641 1641
1642/* workaround for too low volume on Audigy due to 16bit/24bit conversion */
1643
1644#define snd_audigy_capture_boost_info snd_ctl_boolean_mono_info
1645
1646static int snd_audigy_capture_boost_get(struct snd_kcontrol *kcontrol,
1647 struct snd_ctl_elem_value *ucontrol)
1648{
1649 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1650 unsigned int val;
1651
1652 /* FIXME: better to use a cached version */
1653 val = snd_ac97_read(emu->ac97, AC97_REC_GAIN);
1654 ucontrol->value.integer.value[0] = !!val;
1655 return 0;
1656}
1657
1658static int snd_audigy_capture_boost_put(struct snd_kcontrol *kcontrol,
1659 struct snd_ctl_elem_value *ucontrol)
1660{
1661 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
1662 unsigned int val;
1663
1664 if (ucontrol->value.integer.value[0])
1665 val = 0x0f0f;
1666 else
1667 val = 0;
1668 return snd_ac97_update(emu->ac97, AC97_REC_GAIN, val);
1669}
1670
1671static struct snd_kcontrol_new snd_audigy_capture_boost __devinitdata =
1672{
1673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1674 .name = "Analog Capture Boost",
1675 .info = snd_audigy_capture_boost_info,
1676 .get = snd_audigy_capture_boost_get,
1677 .put = snd_audigy_capture_boost_put
1678};
1679
1680
1642/* 1681/*
1643 */ 1682 */
1644static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97) 1683static void snd_emu10k1_mixer_free_ac97(struct snd_ac97 *ac97)
@@ -2087,5 +2126,12 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
2087 } 2126 }
2088 } 2127 }
2089 2128
2129 if (emu->card_capabilities->ac97_chip && emu->audigy) {
2130 err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_capture_boost,
2131 emu));
2132 if (err < 0)
2133 return err;
2134 }
2135
2090 return 0; 2136 return 0;
2091} 2137}
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 20ee7599600b..e9c3794bbcb8 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -1953,7 +1953,7 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
1953 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4); 1953 outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
1954 1954
1955 if (event & ESM_HWVOL_IRQ) 1955 if (event & ESM_HWVOL_IRQ)
1956 tasklet_hi_schedule(&chip->hwvol_tq); /* we'll do this later */ 1956 tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
1957 1957
1958 /* else ack 'em all, i imagine */ 1958 /* else ack 'em all, i imagine */
1959 outb(0xFF, chip->io_port + 0x1A); 1959 outb(0xFF, chip->io_port + 0x1A);
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
new file mode 100644
index 000000000000..eb2a19b894a0
--- /dev/null
+++ b/sound/pci/hda/Kconfig
@@ -0,0 +1,188 @@
1menuconfig SND_HDA_INTEL
2 tristate "Intel HD Audio"
3 select SND_PCM
4 select SND_VMASTER
5 select SND_JACK if INPUT=y || INPUT=SND
6 help
7 Say Y here to include support for Intel "High Definition
8 Audio" (Azalia) and its compatible devices.
9
10 This option enables the HD-audio controller. Don't forget
11 to choose the appropriate codec options below.
12
13 To compile this driver as a module, choose M here: the module
14 will be called snd-hda-intel.
15
16if SND_HDA_INTEL
17
18config SND_HDA_HWDEP
19 bool "Build hwdep interface for HD-audio driver"
20 select SND_HWDEP
21 help
22 Say Y here to build a hwdep interface for HD-audio driver.
23 This interface can be used for out-of-band communication
24 with codecs for debugging purposes.
25
26config SND_HDA_RECONFIG
27 bool "Allow dynamic codec reconfiguration (EXPERIMENTAL)"
28 depends on SND_HDA_HWDEP && EXPERIMENTAL
29 help
30 Say Y here to enable the HD-audio codec re-configuration feature.
31 This adds the sysfs interfaces to allow user to clear the whole
32 codec configuration, change the codec setup, add extra verbs,
33 and re-configure the codec dynamically.
34
35config SND_HDA_INPUT_BEEP
36 bool "Support digital beep via input layer"
37 depends on INPUT=y || INPUT=SND_HDA_INTEL
38 help
39 Say Y here to build a digital beep interface for HD-audio
40 driver. This interface is used to generate digital beeps.
41
42config SND_HDA_CODEC_REALTEK
43 bool "Build Realtek HD-audio codec support"
44 default y
45 help
46 Say Y here to include Realtek HD-audio codec support in
47 snd-hda-intel driver, such as ALC880.
48
49 When the HD-audio driver is built as a module, the codec
50 support code is also built as another module,
51 snd-hda-codec-realtek.
52 This module is automatically loaded at probing.
53
54config SND_HDA_CODEC_ANALOG
55 bool "Build Analog Device HD-audio codec support"
56 default y
57 help
58 Say Y here to include Analog Device HD-audio codec support in
59 snd-hda-intel driver, such as AD1986A.
60
61 When the HD-audio driver is built as a module, the codec
62 support code is also built as another module,
63 snd-hda-codec-analog.
64 This module is automatically loaded at probing.
65
66config SND_HDA_CODEC_SIGMATEL
67 bool "Build IDT/Sigmatel HD-audio codec support"
68 default y
69 help
70 Say Y here to include IDT (Sigmatel) HD-audio codec support in
71 snd-hda-intel driver, such as STAC9200.
72
73 When the HD-audio driver is built as a module, the codec
74 support code is also built as another module,
75 snd-hda-codec-idt.
76 This module is automatically loaded at probing.
77
78config SND_HDA_CODEC_VIA
79 bool "Build VIA HD-audio codec support"
80 default y
81 help
82 Say Y here to include VIA HD-audio codec support in
83 snd-hda-intel driver, such as VT1708.
84
85 When the HD-audio driver is built as a module, the codec
86 support code is also built as another module,
87 snd-hda-codec-via.
88 This module is automatically loaded at probing.
89
90config SND_HDA_CODEC_ATIHDMI
91 bool "Build ATI HDMI HD-audio codec support"
92 default y
93 help
94 Say Y here to include ATI HDMI HD-audio codec support in
95 snd-hda-intel driver, such as ATI RS600 HDMI.
96
97 When the HD-audio driver is built as a module, the codec
98 support code is also built as another module,
99 snd-hda-codec-atihdmi.
100 This module is automatically loaded at probing.
101
102config SND_HDA_CODEC_NVHDMI
103 bool "Build NVIDIA HDMI HD-audio codec support"
104 default y
105 help
106 Say Y here to include NVIDIA HDMI HD-audio codec support in
107 snd-hda-intel driver, such as NVIDIA MCP78 HDMI.
108
109 When the HD-audio driver is built as a module, the codec
110 support code is also built as another module,
111 snd-hda-codec-nvhdmi.
112 This module is automatically loaded at probing.
113
114config SND_HDA_CODEC_INTELHDMI
115 bool "Build INTEL HDMI HD-audio codec support"
116 default y
117 help
118 Say Y here to include INTEL HDMI HD-audio codec support in
119 snd-hda-intel driver, such as Eaglelake integrated HDMI.
120
121 When the HD-audio driver is built as a module, the codec
122 support code is also built as another module,
123 snd-hda-codec-intelhdmi.
124 This module is automatically loaded at probing.
125
126config SND_HDA_ELD
127 def_bool y
128 depends on SND_HDA_CODEC_INTELHDMI
129
130config SND_HDA_CODEC_CONEXANT
131 bool "Build Conexant HD-audio codec support"
132 default y
133 help
134 Say Y here to include Conexant HD-audio codec support in
135 snd-hda-intel driver, such as CX20549.
136
137 When the HD-audio driver is built as a module, the codec
138 support code is also built as another module,
139 snd-hda-codec-conexant.
140 This module is automatically loaded at probing.
141
142config SND_HDA_CODEC_CMEDIA
143 bool "Build C-Media HD-audio codec support"
144 default y
145 help
146 Say Y here to include C-Media HD-audio codec support in
147 snd-hda-intel driver, such as CMI9880.
148
149 When the HD-audio driver is built as a module, the codec
150 support code is also built as another module,
151 snd-hda-codec-cmedia.
152 This module is automatically loaded at probing.
153
154config SND_HDA_CODEC_SI3054
155 bool "Build Silicon Labs 3054 HD-modem codec support"
156 default y
157 help
158 Say Y here to include Silicon Labs 3054 HD-modem codec
159 (and compatibles) support in snd-hda-intel driver.
160
161 When the HD-audio driver is built as a module, the codec
162 support code is also built as another module,
163 snd-hda-codec-si3054.
164 This module is automatically loaded at probing.
165
166config SND_HDA_GENERIC
167 bool "Enable generic HD-audio codec parser"
168 default y
169 help
170 Say Y here to enable the generic HD-audio codec parser
171 in snd-hda-intel driver.
172
173config SND_HDA_POWER_SAVE
174 bool "Aggressive power-saving on HD-audio"
175 help
176 Say Y here to enable more aggressive power-saving mode on
177 HD-audio driver. The power-saving timeout can be configured
178 via power_save option or over sysfs on-the-fly.
179
180config SND_HDA_POWER_SAVE_DEFAULT
181 int "Default time-out for HD-audio power-save mode"
182 depends on SND_HDA_POWER_SAVE
183 default 0
184 help
185 The default time-out value in seconds for HD-audio automatic
186 power-save mode. 0 means to disable the power-save mode.
187
188endif
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index 1980c6d207e7..50f9d0967251 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,20 +1,59 @@
1snd-hda-intel-y := hda_intel.o 1snd-hda-intel-objs := hda_intel.o
2# since snd-hda-intel is the only driver using hda-codec,
3# merge it into a single module although it was originally
4# designed to be individual modules
5snd-hda-intel-y += hda_codec.o
6snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o
7snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-intel-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
9snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
10snd-hda-intel-$(CONFIG_SND_HDA_CODEC_REALTEK) += patch_realtek.o
11snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CMEDIA) += patch_cmedia.o
12snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ANALOG) += patch_analog.o
13snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SIGMATEL) += patch_sigmatel.o
14snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SI3054) += patch_si3054.o
15snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ATIHDMI) += patch_atihdmi.o
16snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CONEXANT) += patch_conexant.o
17snd-hda-intel-$(CONFIG_SND_HDA_CODEC_VIA) += patch_via.o
18snd-hda-intel-$(CONFIG_SND_HDA_CODEC_NVHDMI) += patch_nvhdmi.o
19 2
3snd-hda-codec-y := hda_codec.o
4snd-hda-codec-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o
5snd-hda-codec-$(CONFIG_PROC_FS) += hda_proc.o
6# snd-hda-codec-$(CONFIG_SND_HDA_ELD) += hda_eld.o
7snd-hda-codec-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o
8snd-hda-codec-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o
9
10snd-hda-codec-realtek-objs := patch_realtek.o
11snd-hda-codec-cmedia-objs := patch_cmedia.o
12snd-hda-codec-analog-objs := patch_analog.o
13snd-hda-codec-idt-objs := patch_sigmatel.o
14snd-hda-codec-si3054-objs := patch_si3054.o
15snd-hda-codec-atihdmi-objs := patch_atihdmi.o
16snd-hda-codec-conexant-objs := patch_conexant.o
17snd-hda-codec-via-objs := patch_via.o
18snd-hda-codec-nvhdmi-objs := patch_nvhdmi.o
19snd-hda-codec-intelhdmi-objs := patch_intelhdmi.o hda_eld.o
20
21# common driver
22obj-$(CONFIG_SND_HDA_INTEL) := snd-hda-codec.o
23
24# codec drivers (note: CONFIG_SND_HDA_CODEC_XXX are booleans)
25ifdef CONFIG_SND_HDA_CODEC_REALTEK
26obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-realtek.o
27endif
28ifdef CONFIG_SND_HDA_CODEC_CMEDIA
29obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-cmedia.o
30endif
31ifdef CONFIG_SND_HDA_CODEC_ANALOG
32obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-analog.o
33endif
34ifdef CONFIG_SND_HDA_CODEC_SIGMATEL
35obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-idt.o
36endif
37ifdef CONFIG_SND_HDA_CODEC_SI3054
38obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-si3054.o
39endif
40ifdef CONFIG_SND_HDA_CODEC_ATIHDMI
41obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-atihdmi.o
42endif
43ifdef CONFIG_SND_HDA_CODEC_CONEXANT
44obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-conexant.o
45endif
46ifdef CONFIG_SND_HDA_CODEC_VIA
47obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-via.o
48endif
49ifdef CONFIG_SND_HDA_CODEC_NVHDMI
50obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-nvhdmi.o
51endif
52ifdef CONFIG_SND_HDA_CODEC_INTELHDMI
53obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-codec-intelhdmi.o
54endif
55
56# this must be the last entry after codec drivers;
57# otherwise the codec patches won't be hooked before the PCI probe
58# when built in kernel
20obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o 59obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 3ecd7e797dee..e00421c0d8ba 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -128,6 +128,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
128 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); 128 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
129 return 0; 129 return 0;
130} 130}
131EXPORT_SYMBOL_HDA(snd_hda_attach_beep_device);
131 132
132void snd_hda_detach_beep_device(struct hda_codec *codec) 133void snd_hda_detach_beep_device(struct hda_codec *codec)
133{ 134{
@@ -140,3 +141,4 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
140 kfree(beep); 141 kfree(beep);
141 } 142 }
142} 143}
144EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index eb9164176dab..e16cf63821ae 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -31,15 +31,6 @@
31#include <sound/initval.h> 31#include <sound/initval.h>
32#include "hda_local.h" 32#include "hda_local.h"
33#include <sound/hda_hwdep.h> 33#include <sound/hda_hwdep.h>
34#include "hda_patch.h" /* codec presets */
35
36#ifdef CONFIG_SND_HDA_POWER_SAVE
37/* define this option here to hide as static */
38static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
39module_param(power_save, int, 0644);
40MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
41 "(in second, 0 = disable).");
42#endif
43 34
44/* 35/*
45 * vendor / preset table 36 * vendor / preset table
@@ -55,6 +46,7 @@ static struct hda_vendor_id hda_vendor_ids[] = {
55 { 0x1002, "ATI" }, 46 { 0x1002, "ATI" },
56 { 0x1057, "Motorola" }, 47 { 0x1057, "Motorola" },
57 { 0x1095, "Silicon Image" }, 48 { 0x1095, "Silicon Image" },
49 { 0x10de, "Nvidia" },
58 { 0x10ec, "Realtek" }, 50 { 0x10ec, "Realtek" },
59 { 0x1106, "VIA" }, 51 { 0x1106, "VIA" },
60 { 0x111d, "IDT" }, 52 { 0x111d, "IDT" },
@@ -66,40 +58,31 @@ static struct hda_vendor_id hda_vendor_ids[] = {
66 { 0x1854, "LG" }, 58 { 0x1854, "LG" },
67 { 0x1aec, "Wolfson Microelectronics" }, 59 { 0x1aec, "Wolfson Microelectronics" },
68 { 0x434d, "C-Media" }, 60 { 0x434d, "C-Media" },
61 { 0x8086, "Intel" },
69 { 0x8384, "SigmaTel" }, 62 { 0x8384, "SigmaTel" },
70 {} /* terminator */ 63 {} /* terminator */
71}; 64};
72 65
73static const struct hda_codec_preset *hda_preset_tables[] = { 66static DEFINE_MUTEX(preset_mutex);
74#ifdef CONFIG_SND_HDA_CODEC_REALTEK 67static LIST_HEAD(hda_preset_tables);
75 snd_hda_preset_realtek, 68
76#endif 69int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset)
77#ifdef CONFIG_SND_HDA_CODEC_CMEDIA 70{
78 snd_hda_preset_cmedia, 71 mutex_lock(&preset_mutex);
79#endif 72 list_add_tail(&preset->list, &hda_preset_tables);
80#ifdef CONFIG_SND_HDA_CODEC_ANALOG 73 mutex_unlock(&preset_mutex);
81 snd_hda_preset_analog, 74 return 0;
82#endif 75}
83#ifdef CONFIG_SND_HDA_CODEC_SIGMATEL 76EXPORT_SYMBOL_HDA(snd_hda_add_codec_preset);
84 snd_hda_preset_sigmatel, 77
85#endif 78int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset)
86#ifdef CONFIG_SND_HDA_CODEC_SI3054 79{
87 snd_hda_preset_si3054, 80 mutex_lock(&preset_mutex);
88#endif 81 list_del(&preset->list);
89#ifdef CONFIG_SND_HDA_CODEC_ATIHDMI 82 mutex_unlock(&preset_mutex);
90 snd_hda_preset_atihdmi, 83 return 0;
91#endif 84}
92#ifdef CONFIG_SND_HDA_CODEC_CONEXANT 85EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
93 snd_hda_preset_conexant,
94#endif
95#ifdef CONFIG_SND_HDA_CODEC_VIA
96 snd_hda_preset_via,
97#endif
98#ifdef CONFIG_SND_HDA_CODEC_NVHDMI
99 snd_hda_preset_nvhdmi,
100#endif
101 NULL
102};
103 86
104#ifdef CONFIG_SND_HDA_POWER_SAVE 87#ifdef CONFIG_SND_HDA_POWER_SAVE
105static void hda_power_work(struct work_struct *work); 88static void hda_power_work(struct work_struct *work);
@@ -108,6 +91,72 @@ static void hda_keep_power_on(struct hda_codec *codec);
108static inline void hda_keep_power_on(struct hda_codec *codec) {} 91static inline void hda_keep_power_on(struct hda_codec *codec) {}
109#endif 92#endif
110 93
94const char *snd_hda_get_jack_location(u32 cfg)
95{
96 static char *bases[7] = {
97 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
98 };
99 static unsigned char specials_idx[] = {
100 0x07, 0x08,
101 0x17, 0x18, 0x19,
102 0x37, 0x38
103 };
104 static char *specials[] = {
105 "Rear Panel", "Drive Bar",
106 "Riser", "HDMI", "ATAPI",
107 "Mobile-In", "Mobile-Out"
108 };
109 int i;
110 cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
111 if ((cfg & 0x0f) < 7)
112 return bases[cfg & 0x0f];
113 for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
114 if (cfg == specials_idx[i])
115 return specials[i];
116 }
117 return "UNKNOWN";
118}
119EXPORT_SYMBOL_HDA(snd_hda_get_jack_location);
120
121const char *snd_hda_get_jack_connectivity(u32 cfg)
122{
123 static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
124
125 return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
126}
127EXPORT_SYMBOL_HDA(snd_hda_get_jack_connectivity);
128
129const char *snd_hda_get_jack_type(u32 cfg)
130{
131 static char *jack_types[16] = {
132 "Line Out", "Speaker", "HP Out", "CD",
133 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
134 "Line In", "Aux", "Mic", "Telephony",
135 "SPDIF In", "Digitial In", "Reserved", "Other"
136 };
137
138 return jack_types[(cfg & AC_DEFCFG_DEVICE)
139 >> AC_DEFCFG_DEVICE_SHIFT];
140}
141EXPORT_SYMBOL_HDA(snd_hda_get_jack_type);
142
143/*
144 * Compose a 32bit command word to be sent to the HD-audio controller
145 */
146static inline unsigned int
147make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
148 unsigned int verb, unsigned int parm)
149{
150 u32 val;
151
152 val = (u32)(codec->addr & 0x0f) << 28;
153 val |= (u32)direct << 27;
154 val |= (u32)nid << 20;
155 val |= verb << 8;
156 val |= parm;
157 return val;
158}
159
111/** 160/**
112 * snd_hda_codec_read - send a command and get the response 161 * snd_hda_codec_read - send a command and get the response
113 * @codec: the HDA codec 162 * @codec: the HDA codec
@@ -124,17 +173,21 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
124 int direct, 173 int direct,
125 unsigned int verb, unsigned int parm) 174 unsigned int verb, unsigned int parm)
126{ 175{
176 struct hda_bus *bus = codec->bus;
127 unsigned int res; 177 unsigned int res;
178
179 res = make_codec_cmd(codec, nid, direct, verb, parm);
128 snd_hda_power_up(codec); 180 snd_hda_power_up(codec);
129 mutex_lock(&codec->bus->cmd_mutex); 181 mutex_lock(&bus->cmd_mutex);
130 if (!codec->bus->ops.command(codec, nid, direct, verb, parm)) 182 if (!bus->ops.command(bus, res))
131 res = codec->bus->ops.get_response(codec); 183 res = bus->ops.get_response(bus);
132 else 184 else
133 res = (unsigned int)-1; 185 res = (unsigned int)-1;
134 mutex_unlock(&codec->bus->cmd_mutex); 186 mutex_unlock(&bus->cmd_mutex);
135 snd_hda_power_down(codec); 187 snd_hda_power_down(codec);
136 return res; 188 return res;
137} 189}
190EXPORT_SYMBOL_HDA(snd_hda_codec_read);
138 191
139/** 192/**
140 * snd_hda_codec_write - send a single command without waiting for response 193 * snd_hda_codec_write - send a single command without waiting for response
@@ -151,14 +204,19 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
151int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, 204int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
152 unsigned int verb, unsigned int parm) 205 unsigned int verb, unsigned int parm)
153{ 206{
207 struct hda_bus *bus = codec->bus;
208 unsigned int res;
154 int err; 209 int err;
210
211 res = make_codec_cmd(codec, nid, direct, verb, parm);
155 snd_hda_power_up(codec); 212 snd_hda_power_up(codec);
156 mutex_lock(&codec->bus->cmd_mutex); 213 mutex_lock(&bus->cmd_mutex);
157 err = codec->bus->ops.command(codec, nid, direct, verb, parm); 214 err = bus->ops.command(bus, res);
158 mutex_unlock(&codec->bus->cmd_mutex); 215 mutex_unlock(&bus->cmd_mutex);
159 snd_hda_power_down(codec); 216 snd_hda_power_down(codec);
160 return err; 217 return err;
161} 218}
219EXPORT_SYMBOL_HDA(snd_hda_codec_write);
162 220
163/** 221/**
164 * snd_hda_sequence_write - sequence writes 222 * snd_hda_sequence_write - sequence writes
@@ -173,6 +231,7 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
173 for (; seq->nid; seq++) 231 for (; seq->nid; seq++)
174 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); 232 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
175} 233}
234EXPORT_SYMBOL_HDA(snd_hda_sequence_write);
176 235
177/** 236/**
178 * snd_hda_get_sub_nodes - get the range of sub nodes 237 * snd_hda_get_sub_nodes - get the range of sub nodes
@@ -194,6 +253,7 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
194 *start_id = (parm >> 16) & 0x7fff; 253 *start_id = (parm >> 16) & 0x7fff;
195 return (int)(parm & 0x7fff); 254 return (int)(parm & 0x7fff);
196} 255}
256EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
197 257
198/** 258/**
199 * snd_hda_get_connections - get connection list 259 * snd_hda_get_connections - get connection list
@@ -282,6 +342,7 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
282 } 342 }
283 return conns; 343 return conns;
284} 344}
345EXPORT_SYMBOL_HDA(snd_hda_get_connections);
285 346
286 347
287/** 348/**
@@ -316,6 +377,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
316 377
317 return 0; 378 return 0;
318} 379}
380EXPORT_SYMBOL_HDA(snd_hda_queue_unsol_event);
319 381
320/* 382/*
321 * process queued unsolicited events 383 * process queued unsolicited events
@@ -345,7 +407,7 @@ static void process_unsol_events(struct work_struct *work)
345/* 407/*
346 * initialize unsolicited queue 408 * initialize unsolicited queue
347 */ 409 */
348static int __devinit init_unsol_queue(struct hda_bus *bus) 410static int init_unsol_queue(struct hda_bus *bus)
349{ 411{
350 struct hda_bus_unsolicited *unsol; 412 struct hda_bus_unsolicited *unsol;
351 413
@@ -391,9 +453,24 @@ static int snd_hda_bus_free(struct hda_bus *bus)
391static int snd_hda_bus_dev_free(struct snd_device *device) 453static int snd_hda_bus_dev_free(struct snd_device *device)
392{ 454{
393 struct hda_bus *bus = device->device_data; 455 struct hda_bus *bus = device->device_data;
456 bus->shutdown = 1;
394 return snd_hda_bus_free(bus); 457 return snd_hda_bus_free(bus);
395} 458}
396 459
460#ifdef CONFIG_SND_HDA_HWDEP
461static int snd_hda_bus_dev_register(struct snd_device *device)
462{
463 struct hda_bus *bus = device->device_data;
464 struct hda_codec *codec;
465 list_for_each_entry(codec, &bus->codec_list, list) {
466 snd_hda_hwdep_add_sysfs(codec);
467 }
468 return 0;
469}
470#else
471#define snd_hda_bus_dev_register NULL
472#endif
473
397/** 474/**
398 * snd_hda_bus_new - create a HDA bus 475 * snd_hda_bus_new - create a HDA bus
399 * @card: the card entry 476 * @card: the card entry
@@ -402,13 +479,14 @@ static int snd_hda_bus_dev_free(struct snd_device *device)
402 * 479 *
403 * Returns 0 if successful, or a negative error code. 480 * Returns 0 if successful, or a negative error code.
404 */ 481 */
405int __devinit snd_hda_bus_new(struct snd_card *card, 482int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
406 const struct hda_bus_template *temp, 483 const struct hda_bus_template *temp,
407 struct hda_bus **busp) 484 struct hda_bus **busp)
408{ 485{
409 struct hda_bus *bus; 486 struct hda_bus *bus;
410 int err; 487 int err;
411 static struct snd_device_ops dev_ops = { 488 static struct snd_device_ops dev_ops = {
489 .dev_register = snd_hda_bus_dev_register,
412 .dev_free = snd_hda_bus_dev_free, 490 .dev_free = snd_hda_bus_dev_free,
413 }; 491 };
414 492
@@ -430,6 +508,7 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
430 bus->private_data = temp->private_data; 508 bus->private_data = temp->private_data;
431 bus->pci = temp->pci; 509 bus->pci = temp->pci;
432 bus->modelname = temp->modelname; 510 bus->modelname = temp->modelname;
511 bus->power_save = temp->power_save;
433 bus->ops = temp->ops; 512 bus->ops = temp->ops;
434 513
435 mutex_init(&bus->cmd_mutex); 514 mutex_init(&bus->cmd_mutex);
@@ -444,27 +523,42 @@ int __devinit snd_hda_bus_new(struct snd_card *card,
444 *busp = bus; 523 *busp = bus;
445 return 0; 524 return 0;
446} 525}
526EXPORT_SYMBOL_HDA(snd_hda_bus_new);
447 527
448#ifdef CONFIG_SND_HDA_GENERIC 528#ifdef CONFIG_SND_HDA_GENERIC
449#define is_generic_config(codec) \ 529#define is_generic_config(codec) \
450 (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic")) 530 (codec->modelname && !strcmp(codec->modelname, "generic"))
451#else 531#else
452#define is_generic_config(codec) 0 532#define is_generic_config(codec) 0
453#endif 533#endif
454 534
535#ifdef MODULE
536#define HDA_MODREQ_MAX_COUNT 2 /* two request_modules()'s */
537#else
538#define HDA_MODREQ_MAX_COUNT 0 /* all presets are statically linked */
539#endif
540
455/* 541/*
456 * find a matching codec preset 542 * find a matching codec preset
457 */ 543 */
458static const struct hda_codec_preset __devinit * 544static const struct hda_codec_preset *
459find_codec_preset(struct hda_codec *codec) 545find_codec_preset(struct hda_codec *codec)
460{ 546{
461 const struct hda_codec_preset **tbl, *preset; 547 struct hda_codec_preset_list *tbl;
548 const struct hda_codec_preset *preset;
549 int mod_requested = 0;
462 550
463 if (is_generic_config(codec)) 551 if (is_generic_config(codec))
464 return NULL; /* use the generic parser */ 552 return NULL; /* use the generic parser */
465 553
466 for (tbl = hda_preset_tables; *tbl; tbl++) { 554 again:
467 for (preset = *tbl; preset->id; preset++) { 555 mutex_lock(&preset_mutex);
556 list_for_each_entry(tbl, &hda_preset_tables, list) {
557 if (!try_module_get(tbl->owner)) {
558 snd_printk(KERN_ERR "hda_codec: cannot module_get\n");
559 continue;
560 }
561 for (preset = tbl->preset; preset->id; preset++) {
468 u32 mask = preset->mask; 562 u32 mask = preset->mask;
469 if (preset->afg && preset->afg != codec->afg) 563 if (preset->afg && preset->afg != codec->afg)
470 continue; 564 continue;
@@ -474,23 +568,40 @@ find_codec_preset(struct hda_codec *codec)
474 mask = ~0; 568 mask = ~0;
475 if (preset->id == (codec->vendor_id & mask) && 569 if (preset->id == (codec->vendor_id & mask) &&
476 (!preset->rev || 570 (!preset->rev ||
477 preset->rev == codec->revision_id)) 571 preset->rev == codec->revision_id)) {
572 mutex_unlock(&preset_mutex);
573 codec->owner = tbl->owner;
478 return preset; 574 return preset;
575 }
479 } 576 }
577 module_put(tbl->owner);
578 }
579 mutex_unlock(&preset_mutex);
580
581 if (mod_requested < HDA_MODREQ_MAX_COUNT) {
582 char name[32];
583 if (!mod_requested)
584 snprintf(name, sizeof(name), "snd-hda-codec-id:%08x",
585 codec->vendor_id);
586 else
587 snprintf(name, sizeof(name), "snd-hda-codec-id:%04x*",
588 (codec->vendor_id >> 16) & 0xffff);
589 request_module(name);
590 mod_requested++;
591 goto again;
480 } 592 }
481 return NULL; 593 return NULL;
482} 594}
483 595
484/* 596/*
485 * snd_hda_get_codec_name - store the codec name 597 * get_codec_name - store the codec name
486 */ 598 */
487void snd_hda_get_codec_name(struct hda_codec *codec, 599static int get_codec_name(struct hda_codec *codec)
488 char *name, int namelen)
489{ 600{
490 const struct hda_vendor_id *c; 601 const struct hda_vendor_id *c;
491 const char *vendor = NULL; 602 const char *vendor = NULL;
492 u16 vendor_id = codec->vendor_id >> 16; 603 u16 vendor_id = codec->vendor_id >> 16;
493 char tmp[16]; 604 char tmp[16], name[32];
494 605
495 for (c = hda_vendor_ids; c->id; c++) { 606 for (c = hda_vendor_ids; c->id; c++) {
496 if (c->id == vendor_id) { 607 if (c->id == vendor_id) {
@@ -503,16 +614,21 @@ void snd_hda_get_codec_name(struct hda_codec *codec,
503 vendor = tmp; 614 vendor = tmp;
504 } 615 }
505 if (codec->preset && codec->preset->name) 616 if (codec->preset && codec->preset->name)
506 snprintf(name, namelen, "%s %s", vendor, codec->preset->name); 617 snprintf(name, sizeof(name), "%s %s", vendor,
618 codec->preset->name);
507 else 619 else
508 snprintf(name, namelen, "%s ID %x", vendor, 620 snprintf(name, sizeof(name), "%s ID %x", vendor,
509 codec->vendor_id & 0xffff); 621 codec->vendor_id & 0xffff);
622 codec->name = kstrdup(name, GFP_KERNEL);
623 if (!codec->name)
624 return -ENOMEM;
625 return 0;
510} 626}
511 627
512/* 628/*
513 * look for an AFG and MFG nodes 629 * look for an AFG and MFG nodes
514 */ 630 */
515static void __devinit setup_fg_nodes(struct hda_codec *codec) 631static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec)
516{ 632{
517 int i, total_nodes; 633 int i, total_nodes;
518 hda_nid_t nid; 634 hda_nid_t nid;
@@ -571,11 +687,15 @@ static void snd_hda_codec_free(struct hda_codec *codec)
571 flush_scheduled_work(); 687 flush_scheduled_work();
572#endif 688#endif
573 list_del(&codec->list); 689 list_del(&codec->list);
690 snd_array_free(&codec->mixers);
574 codec->bus->caddr_tbl[codec->addr] = NULL; 691 codec->bus->caddr_tbl[codec->addr] = NULL;
575 if (codec->patch_ops.free) 692 if (codec->patch_ops.free)
576 codec->patch_ops.free(codec); 693 codec->patch_ops.free(codec);
694 module_put(codec->owner);
577 free_hda_cache(&codec->amp_cache); 695 free_hda_cache(&codec->amp_cache);
578 free_hda_cache(&codec->cmd_cache); 696 free_hda_cache(&codec->cmd_cache);
697 kfree(codec->name);
698 kfree(codec->modelname);
579 kfree(codec->wcaps); 699 kfree(codec->wcaps);
580 kfree(codec); 700 kfree(codec);
581} 701}
@@ -588,8 +708,8 @@ static void snd_hda_codec_free(struct hda_codec *codec)
588 * 708 *
589 * Returns 0 if successful, or a negative error code. 709 * Returns 0 if successful, or a negative error code.
590 */ 710 */
591int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 711int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
592 struct hda_codec **codecp) 712 int do_init, struct hda_codec **codecp)
593{ 713{
594 struct hda_codec *codec; 714 struct hda_codec *codec;
595 char component[31]; 715 char component[31];
@@ -617,6 +737,14 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
617 mutex_init(&codec->spdif_mutex); 737 mutex_init(&codec->spdif_mutex);
618 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info)); 738 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
619 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head)); 739 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
740 snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32);
741 if (codec->bus->modelname) {
742 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
743 if (!codec->modelname) {
744 snd_hda_codec_free(codec);
745 return -ENODEV;
746 }
747 }
620 748
621#ifdef CONFIG_SND_HDA_POWER_SAVE 749#ifdef CONFIG_SND_HDA_POWER_SAVE
622 INIT_DELAYED_WORK(&codec->power_work, hda_power_work); 750 INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
@@ -662,12 +790,44 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
662 snd_hda_codec_read(codec, nid, 0, 790 snd_hda_codec_read(codec, nid, 0,
663 AC_VERB_GET_SUBSYSTEM_ID, 0); 791 AC_VERB_GET_SUBSYSTEM_ID, 0);
664 } 792 }
793 if (bus->modelname)
794 codec->modelname = kstrdup(bus->modelname, GFP_KERNEL);
795
796 if (do_init) {
797 err = snd_hda_codec_configure(codec);
798 if (err < 0) {
799 snd_hda_codec_free(codec);
800 return err;
801 }
802 }
803 snd_hda_codec_proc_new(codec);
804
805 snd_hda_create_hwdep(codec);
806
807 sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id,
808 codec->subsystem_id, codec->revision_id);
809 snd_component_add(codec->bus->card, component);
810
811 if (codecp)
812 *codecp = codec;
813 return 0;
814}
815EXPORT_SYMBOL_HDA(snd_hda_codec_new);
816
817int snd_hda_codec_configure(struct hda_codec *codec)
818{
819 int err;
665 820
666 codec->preset = find_codec_preset(codec); 821 codec->preset = find_codec_preset(codec);
822 if (!codec->name) {
823 err = get_codec_name(codec);
824 if (err < 0)
825 return err;
826 }
667 /* audio codec should override the mixer name */ 827 /* audio codec should override the mixer name */
668 if (codec->afg || !*bus->card->mixername) 828 if (codec->afg || !*codec->bus->card->mixername)
669 snd_hda_get_codec_name(codec, bus->card->mixername, 829 strlcpy(codec->bus->card->mixername, codec->name,
670 sizeof(bus->card->mixername)); 830 sizeof(codec->bus->card->mixername));
671 831
672 if (is_generic_config(codec)) { 832 if (is_generic_config(codec)) {
673 err = snd_hda_parse_generic_codec(codec); 833 err = snd_hda_parse_generic_codec(codec);
@@ -684,25 +844,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
684 printk(KERN_ERR "hda-codec: No codec parser is available\n"); 844 printk(KERN_ERR "hda-codec: No codec parser is available\n");
685 845
686 patched: 846 patched:
687 if (err < 0) { 847 if (!err && codec->patch_ops.unsol_event)
688 snd_hda_codec_free(codec); 848 err = init_unsol_queue(codec->bus);
689 return err; 849 return err;
690 }
691
692 if (codec->patch_ops.unsol_event)
693 init_unsol_queue(bus);
694
695 snd_hda_codec_proc_new(codec);
696#ifdef CONFIG_SND_HDA_HWDEP
697 snd_hda_create_hwdep(codec);
698#endif
699
700 sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id, codec->subsystem_id, codec->revision_id);
701 snd_component_add(codec->bus->card, component);
702
703 if (codecp)
704 *codecp = codec;
705 return 0;
706} 850}
707 851
708/** 852/**
@@ -728,6 +872,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
728 msleep(1); 872 msleep(1);
729 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); 873 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
730} 874}
875EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
731 876
732void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) 877void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
733{ 878{
@@ -741,6 +886,7 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
741 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); 886 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
742#endif 887#endif
743} 888}
889EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
744 890
745/* 891/*
746 * amp access functions 892 * amp access functions
@@ -752,17 +898,17 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
752#define INFO_AMP_VOL(ch) (1 << (1 + (ch))) 898#define INFO_AMP_VOL(ch) (1 << (1 + (ch)))
753 899
754/* initialize the hash table */ 900/* initialize the hash table */
755static void __devinit init_hda_cache(struct hda_cache_rec *cache, 901static void /*__devinit*/ init_hda_cache(struct hda_cache_rec *cache,
756 unsigned int record_size) 902 unsigned int record_size)
757{ 903{
758 memset(cache, 0, sizeof(*cache)); 904 memset(cache, 0, sizeof(*cache));
759 memset(cache->hash, 0xff, sizeof(cache->hash)); 905 memset(cache->hash, 0xff, sizeof(cache->hash));
760 cache->record_size = record_size; 906 snd_array_init(&cache->buf, record_size, 64);
761} 907}
762 908
763static void free_hda_cache(struct hda_cache_rec *cache) 909static void free_hda_cache(struct hda_cache_rec *cache)
764{ 910{
765 kfree(cache->buffer); 911 snd_array_free(&cache->buf);
766} 912}
767 913
768/* query the hash. allocate an entry if not found. */ 914/* query the hash. allocate an entry if not found. */
@@ -774,35 +920,17 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
774 struct hda_cache_head *info; 920 struct hda_cache_head *info;
775 921
776 while (cur != 0xffff) { 922 while (cur != 0xffff) {
777 info = (struct hda_cache_head *)(cache->buffer + 923 info = snd_array_elem(&cache->buf, cur);
778 cur * cache->record_size);
779 if (info->key == key) 924 if (info->key == key)
780 return info; 925 return info;
781 cur = info->next; 926 cur = info->next;
782 } 927 }
783 928
784 /* add a new hash entry */ 929 /* add a new hash entry */
785 if (cache->num_entries >= cache->size) { 930 info = snd_array_new(&cache->buf);
786 /* reallocate the array */ 931 if (!info)
787 unsigned int new_size = cache->size + 64; 932 return NULL;
788 void *new_buffer; 933 cur = snd_array_index(&cache->buf, info);
789 new_buffer = kcalloc(new_size, cache->record_size, GFP_KERNEL);
790 if (!new_buffer) {
791 snd_printk(KERN_ERR "hda_codec: "
792 "can't malloc amp_info\n");
793 return NULL;
794 }
795 if (cache->buffer) {
796 memcpy(new_buffer, cache->buffer,
797 cache->size * cache->record_size);
798 kfree(cache->buffer);
799 }
800 cache->size = new_size;
801 cache->buffer = new_buffer;
802 }
803 cur = cache->num_entries++;
804 info = (struct hda_cache_head *)(cache->buffer +
805 cur * cache->record_size);
806 info->key = key; 934 info->key = key;
807 info->val = 0; 935 info->val = 0;
808 info->next = cache->hash[idx]; 936 info->next = cache->hash[idx];
@@ -840,6 +968,7 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
840 } 968 }
841 return info->amp_caps; 969 return info->amp_caps;
842} 970}
971EXPORT_SYMBOL_HDA(query_amp_caps);
843 972
844int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 973int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
845 unsigned int caps) 974 unsigned int caps)
@@ -853,6 +982,7 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
853 info->head.val |= INFO_AMP_CAPS; 982 info->head.val |= INFO_AMP_CAPS;
854 return 0; 983 return 0;
855} 984}
985EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps);
856 986
857/* 987/*
858 * read the current volume to info 988 * read the current volume to info
@@ -906,6 +1036,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
906 return 0; 1036 return 0;
907 return get_vol_mute(codec, info, nid, ch, direction, index); 1037 return get_vol_mute(codec, info, nid, ch, direction, index);
908} 1038}
1039EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read);
909 1040
910/* 1041/*
911 * update the AMP value, mask = bit mask to set, val = the value 1042 * update the AMP value, mask = bit mask to set, val = the value
@@ -925,6 +1056,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
925 put_vol_mute(codec, info, nid, ch, direction, idx, val); 1056 put_vol_mute(codec, info, nid, ch, direction, idx, val);
926 return 1; 1057 return 1;
927} 1058}
1059EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update);
928 1060
929/* 1061/*
930 * update the AMP stereo with the same mask and value 1062 * update the AMP stereo with the same mask and value
@@ -938,15 +1070,16 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
938 idx, mask, val); 1070 idx, mask, val);
939 return ret; 1071 return ret;
940} 1072}
1073EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);
941 1074
942#ifdef SND_HDA_NEEDS_RESUME 1075#ifdef SND_HDA_NEEDS_RESUME
943/* resume the all amp commands from the cache */ 1076/* resume the all amp commands from the cache */
944void snd_hda_codec_resume_amp(struct hda_codec *codec) 1077void snd_hda_codec_resume_amp(struct hda_codec *codec)
945{ 1078{
946 struct hda_amp_info *buffer = codec->amp_cache.buffer; 1079 struct hda_amp_info *buffer = codec->amp_cache.buf.list;
947 int i; 1080 int i;
948 1081
949 for (i = 0; i < codec->amp_cache.size; i++, buffer++) { 1082 for (i = 0; i < codec->amp_cache.buf.used; i++, buffer++) {
950 u32 key = buffer->head.key; 1083 u32 key = buffer->head.key;
951 hda_nid_t nid; 1084 hda_nid_t nid;
952 unsigned int idx, dir, ch; 1085 unsigned int idx, dir, ch;
@@ -963,6 +1096,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec)
963 } 1096 }
964 } 1097 }
965} 1098}
1099EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
966#endif /* SND_HDA_NEEDS_RESUME */ 1100#endif /* SND_HDA_NEEDS_RESUME */
967 1101
968/* volume */ 1102/* volume */
@@ -990,6 +1124,7 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
990 uinfo->value.integer.max = caps; 1124 uinfo->value.integer.max = caps;
991 return 0; 1125 return 0;
992} 1126}
1127EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info);
993 1128
994int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, 1129int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
995 struct snd_ctl_elem_value *ucontrol) 1130 struct snd_ctl_elem_value *ucontrol)
@@ -1009,6 +1144,7 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
1009 & HDA_AMP_VOLMASK; 1144 & HDA_AMP_VOLMASK;
1010 return 0; 1145 return 0;
1011} 1146}
1147EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_get);
1012 1148
1013int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, 1149int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
1014 struct snd_ctl_elem_value *ucontrol) 1150 struct snd_ctl_elem_value *ucontrol)
@@ -1033,6 +1169,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
1033 snd_hda_power_down(codec); 1169 snd_hda_power_down(codec);
1034 return change; 1170 return change;
1035} 1171}
1172EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_put);
1036 1173
1037int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, 1174int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1038 unsigned int size, unsigned int __user *_tlv) 1175 unsigned int size, unsigned int __user *_tlv)
@@ -1059,6 +1196,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1059 return -EFAULT; 1196 return -EFAULT;
1060 return 0; 1197 return 0;
1061} 1198}
1199EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_tlv);
1062 1200
1063/* 1201/*
1064 * set (static) TLV for virtual master volume; recalculated as max 0dB 1202 * set (static) TLV for virtual master volume; recalculated as max 0dB
@@ -1078,6 +1216,7 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
1078 tlv[2] = -nums * step; 1216 tlv[2] = -nums * step;
1079 tlv[3] = step; 1217 tlv[3] = step;
1080} 1218}
1219EXPORT_SYMBOL_HDA(snd_hda_set_vmaster_tlv);
1081 1220
1082/* find a mixer control element with the given name */ 1221/* find a mixer control element with the given name */
1083static struct snd_kcontrol * 1222static struct snd_kcontrol *
@@ -1097,6 +1236,69 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1097{ 1236{
1098 return _snd_hda_find_mixer_ctl(codec, name, 0); 1237 return _snd_hda_find_mixer_ctl(codec, name, 0);
1099} 1238}
1239EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1240
1241/* Add a control element and assign to the codec */
1242int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl)
1243{
1244 int err;
1245 struct snd_kcontrol **knewp;
1246
1247 err = snd_ctl_add(codec->bus->card, kctl);
1248 if (err < 0)
1249 return err;
1250 knewp = snd_array_new(&codec->mixers);
1251 if (!knewp)
1252 return -ENOMEM;
1253 *knewp = kctl;
1254 return 0;
1255}
1256EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
1257
1258#ifdef CONFIG_SND_HDA_RECONFIG
1259/* Clear all controls assigned to the given codec */
1260void snd_hda_ctls_clear(struct hda_codec *codec)
1261{
1262 int i;
1263 struct snd_kcontrol **kctls = codec->mixers.list;
1264 for (i = 0; i < codec->mixers.used; i++)
1265 snd_ctl_remove(codec->bus->card, kctls[i]);
1266 snd_array_free(&codec->mixers);
1267}
1268
1269void snd_hda_codec_reset(struct hda_codec *codec)
1270{
1271 int i;
1272
1273#ifdef CONFIG_SND_HDA_POWER_SAVE
1274 cancel_delayed_work(&codec->power_work);
1275 flush_scheduled_work();
1276#endif
1277 snd_hda_ctls_clear(codec);
1278 /* relase PCMs */
1279 for (i = 0; i < codec->num_pcms; i++) {
1280 if (codec->pcm_info[i].pcm) {
1281 snd_device_free(codec->bus->card,
1282 codec->pcm_info[i].pcm);
1283 clear_bit(codec->pcm_info[i].device,
1284 codec->bus->pcm_dev_bits);
1285 }
1286 }
1287 if (codec->patch_ops.free)
1288 codec->patch_ops.free(codec);
1289 codec->proc_widget_hook = NULL;
1290 codec->spec = NULL;
1291 free_hda_cache(&codec->amp_cache);
1292 free_hda_cache(&codec->cmd_cache);
1293 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
1294 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
1295 codec->num_pcms = 0;
1296 codec->pcm_info = NULL;
1297 codec->preset = NULL;
1298 module_put(codec->owner);
1299 codec->owner = NULL;
1300}
1301#endif /* CONFIG_SND_HDA_RECONFIG */
1100 1302
1101/* create a virtual master control and add slaves */ 1303/* create a virtual master control and add slaves */
1102int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 1304int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
@@ -1115,7 +1317,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1115 kctl = snd_ctl_make_virtual_master(name, tlv); 1317 kctl = snd_ctl_make_virtual_master(name, tlv);
1116 if (!kctl) 1318 if (!kctl)
1117 return -ENOMEM; 1319 return -ENOMEM;
1118 err = snd_ctl_add(codec->bus->card, kctl); 1320 err = snd_hda_ctl_add(codec, kctl);
1119 if (err < 0) 1321 if (err < 0)
1120 return err; 1322 return err;
1121 1323
@@ -1133,6 +1335,7 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1133 } 1335 }
1134 return 0; 1336 return 0;
1135} 1337}
1338EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);
1136 1339
1137/* switch */ 1340/* switch */
1138int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, 1341int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
@@ -1146,6 +1349,7 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
1146 uinfo->value.integer.max = 1; 1349 uinfo->value.integer.max = 1;
1147 return 0; 1350 return 0;
1148} 1351}
1352EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_info);
1149 1353
1150int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, 1354int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
1151 struct snd_ctl_elem_value *ucontrol) 1355 struct snd_ctl_elem_value *ucontrol)
@@ -1165,6 +1369,7 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
1165 HDA_AMP_MUTE) ? 0 : 1; 1369 HDA_AMP_MUTE) ? 0 : 1;
1166 return 0; 1370 return 0;
1167} 1371}
1372EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get);
1168 1373
1169int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, 1374int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
1170 struct snd_ctl_elem_value *ucontrol) 1375 struct snd_ctl_elem_value *ucontrol)
@@ -1195,6 +1400,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
1195 snd_hda_power_down(codec); 1400 snd_hda_power_down(codec);
1196 return change; 1401 return change;
1197} 1402}
1403EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);
1198 1404
1199/* 1405/*
1200 * bound volume controls 1406 * bound volume controls
@@ -1220,6 +1426,7 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
1220 mutex_unlock(&codec->spdif_mutex); 1426 mutex_unlock(&codec->spdif_mutex);
1221 return err; 1427 return err;
1222} 1428}
1429EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get);
1223 1430
1224int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, 1431int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1225 struct snd_ctl_elem_value *ucontrol) 1432 struct snd_ctl_elem_value *ucontrol)
@@ -1243,6 +1450,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
1243 mutex_unlock(&codec->spdif_mutex); 1450 mutex_unlock(&codec->spdif_mutex);
1244 return err < 0 ? err : change; 1451 return err < 0 ? err : change;
1245} 1452}
1453EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put);
1246 1454
1247/* 1455/*
1248 * generic bound volume/swtich controls 1456 * generic bound volume/swtich controls
@@ -1262,6 +1470,7 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
1262 mutex_unlock(&codec->spdif_mutex); 1470 mutex_unlock(&codec->spdif_mutex);
1263 return err; 1471 return err;
1264} 1472}
1473EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info);
1265 1474
1266int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, 1475int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
1267 struct snd_ctl_elem_value *ucontrol) 1476 struct snd_ctl_elem_value *ucontrol)
@@ -1278,6 +1487,7 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
1278 mutex_unlock(&codec->spdif_mutex); 1487 mutex_unlock(&codec->spdif_mutex);
1279 return err; 1488 return err;
1280} 1489}
1490EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get);
1281 1491
1282int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, 1492int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1283 struct snd_ctl_elem_value *ucontrol) 1493 struct snd_ctl_elem_value *ucontrol)
@@ -1300,6 +1510,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
1300 mutex_unlock(&codec->spdif_mutex); 1510 mutex_unlock(&codec->spdif_mutex);
1301 return err < 0 ? err : change; 1511 return err < 0 ? err : change;
1302} 1512}
1513EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put);
1303 1514
1304int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, 1515int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1305 unsigned int size, unsigned int __user *tlv) 1516 unsigned int size, unsigned int __user *tlv)
@@ -1316,6 +1527,7 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1316 mutex_unlock(&codec->spdif_mutex); 1527 mutex_unlock(&codec->spdif_mutex);
1317 return err; 1528 return err;
1318} 1529}
1530EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv);
1319 1531
1320struct hda_ctl_ops snd_hda_bind_vol = { 1532struct hda_ctl_ops snd_hda_bind_vol = {
1321 .info = snd_hda_mixer_amp_volume_info, 1533 .info = snd_hda_mixer_amp_volume_info,
@@ -1323,6 +1535,7 @@ struct hda_ctl_ops snd_hda_bind_vol = {
1323 .put = snd_hda_mixer_amp_volume_put, 1535 .put = snd_hda_mixer_amp_volume_put,
1324 .tlv = snd_hda_mixer_amp_tlv 1536 .tlv = snd_hda_mixer_amp_tlv
1325}; 1537};
1538EXPORT_SYMBOL_HDA(snd_hda_bind_vol);
1326 1539
1327struct hda_ctl_ops snd_hda_bind_sw = { 1540struct hda_ctl_ops snd_hda_bind_sw = {
1328 .info = snd_hda_mixer_amp_switch_info, 1541 .info = snd_hda_mixer_amp_switch_info,
@@ -1330,6 +1543,7 @@ struct hda_ctl_ops snd_hda_bind_sw = {
1330 .put = snd_hda_mixer_amp_switch_put, 1543 .put = snd_hda_mixer_amp_switch_put,
1331 .tlv = snd_hda_mixer_amp_tlv 1544 .tlv = snd_hda_mixer_amp_tlv
1332}; 1545};
1546EXPORT_SYMBOL_HDA(snd_hda_bind_sw);
1333 1547
1334/* 1548/*
1335 * SPDIF out controls 1549 * SPDIF out controls
@@ -1577,9 +1791,11 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
1577 } 1791 }
1578 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { 1792 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
1579 kctl = snd_ctl_new1(dig_mix, codec); 1793 kctl = snd_ctl_new1(dig_mix, codec);
1794 if (!kctl)
1795 return -ENOMEM;
1580 kctl->id.index = idx; 1796 kctl->id.index = idx;
1581 kctl->private_value = nid; 1797 kctl->private_value = nid;
1582 err = snd_ctl_add(codec->bus->card, kctl); 1798 err = snd_hda_ctl_add(codec, kctl);
1583 if (err < 0) 1799 if (err < 0)
1584 return err; 1800 return err;
1585 } 1801 }
@@ -1589,6 +1805,7 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
1589 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); 1805 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls);
1590 return 0; 1806 return 0;
1591} 1807}
1808EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls);
1592 1809
1593/* 1810/*
1594 * SPDIF sharing with analog output 1811 * SPDIF sharing with analog output
@@ -1623,9 +1840,10 @@ int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
1623 if (!mout->dig_out_nid) 1840 if (!mout->dig_out_nid)
1624 return 0; 1841 return 0;
1625 /* ATTENTION: here mout is passed as private_data, instead of codec */ 1842 /* ATTENTION: here mout is passed as private_data, instead of codec */
1626 return snd_ctl_add(codec->bus->card, 1843 return snd_hda_ctl_add(codec,
1627 snd_ctl_new1(&spdif_share_sw, mout)); 1844 snd_ctl_new1(&spdif_share_sw, mout));
1628} 1845}
1846EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw);
1629 1847
1630/* 1848/*
1631 * SPDIF input 1849 * SPDIF input
@@ -1725,7 +1943,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
1725 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { 1943 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
1726 kctl = snd_ctl_new1(dig_mix, codec); 1944 kctl = snd_ctl_new1(dig_mix, codec);
1727 kctl->private_value = nid; 1945 kctl->private_value = nid;
1728 err = snd_ctl_add(codec->bus->card, kctl); 1946 err = snd_hda_ctl_add(codec, kctl);
1729 if (err < 0) 1947 if (err < 0)
1730 return err; 1948 return err;
1731 } 1949 }
@@ -1735,6 +1953,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
1735 AC_DIG1_ENABLE; 1953 AC_DIG1_ENABLE;
1736 return 0; 1954 return 0;
1737} 1955}
1956EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
1738 1957
1739#ifdef SND_HDA_NEEDS_RESUME 1958#ifdef SND_HDA_NEEDS_RESUME
1740/* 1959/*
@@ -1761,10 +1980,14 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
1761int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, 1980int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
1762 int direct, unsigned int verb, unsigned int parm) 1981 int direct, unsigned int verb, unsigned int parm)
1763{ 1982{
1983 struct hda_bus *bus = codec->bus;
1984 unsigned int res;
1764 int err; 1985 int err;
1986
1987 res = make_codec_cmd(codec, nid, direct, verb, parm);
1765 snd_hda_power_up(codec); 1988 snd_hda_power_up(codec);
1766 mutex_lock(&codec->bus->cmd_mutex); 1989 mutex_lock(&bus->cmd_mutex);
1767 err = codec->bus->ops.command(codec, nid, direct, verb, parm); 1990 err = bus->ops.command(bus, res);
1768 if (!err) { 1991 if (!err) {
1769 struct hda_cache_head *c; 1992 struct hda_cache_head *c;
1770 u32 key = build_cmd_cache_key(nid, verb); 1993 u32 key = build_cmd_cache_key(nid, verb);
@@ -1772,18 +1995,19 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
1772 if (c) 1995 if (c)
1773 c->val = parm; 1996 c->val = parm;
1774 } 1997 }
1775 mutex_unlock(&codec->bus->cmd_mutex); 1998 mutex_unlock(&bus->cmd_mutex);
1776 snd_hda_power_down(codec); 1999 snd_hda_power_down(codec);
1777 return err; 2000 return err;
1778} 2001}
2002EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
1779 2003
1780/* resume the all commands from the cache */ 2004/* resume the all commands from the cache */
1781void snd_hda_codec_resume_cache(struct hda_codec *codec) 2005void snd_hda_codec_resume_cache(struct hda_codec *codec)
1782{ 2006{
1783 struct hda_cache_head *buffer = codec->cmd_cache.buffer; 2007 struct hda_cache_head *buffer = codec->cmd_cache.buf.list;
1784 int i; 2008 int i;
1785 2009
1786 for (i = 0; i < codec->cmd_cache.size; i++, buffer++) { 2010 for (i = 0; i < codec->cmd_cache.buf.used; i++, buffer++) {
1787 u32 key = buffer->key; 2011 u32 key = buffer->key;
1788 if (!key) 2012 if (!key)
1789 continue; 2013 continue;
@@ -1791,6 +2015,7 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec)
1791 get_cmd_cache_cmd(key), buffer->val); 2015 get_cmd_cache_cmd(key), buffer->val);
1792 } 2016 }
1793} 2017}
2018EXPORT_SYMBOL_HDA(snd_hda_codec_resume_cache);
1794 2019
1795/** 2020/**
1796 * snd_hda_sequence_write_cache - sequence writes with caching 2021 * snd_hda_sequence_write_cache - sequence writes with caching
@@ -1808,6 +2033,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec,
1808 snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb, 2033 snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
1809 seq->param); 2034 seq->param);
1810} 2035}
2036EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache);
1811#endif /* SND_HDA_NEEDS_RESUME */ 2037#endif /* SND_HDA_NEEDS_RESUME */
1812 2038
1813/* 2039/*
@@ -1868,6 +2094,17 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
1868 } 2094 }
1869} 2095}
1870 2096
2097#ifdef CONFIG_SND_HDA_HWDEP
2098/* execute additional init verbs */
2099static void hda_exec_init_verbs(struct hda_codec *codec)
2100{
2101 if (codec->init_verbs.list)
2102 snd_hda_sequence_write(codec, codec->init_verbs.list);
2103}
2104#else
2105static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
2106#endif
2107
1871#ifdef SND_HDA_NEEDS_RESUME 2108#ifdef SND_HDA_NEEDS_RESUME
1872/* 2109/*
1873 * call suspend and power-down; used both from PM and power-save 2110 * call suspend and power-down; used both from PM and power-save
@@ -1894,6 +2131,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
1894 hda_set_power_state(codec, 2131 hda_set_power_state(codec,
1895 codec->afg ? codec->afg : codec->mfg, 2132 codec->afg ? codec->afg : codec->mfg,
1896 AC_PWRST_D0); 2133 AC_PWRST_D0);
2134 hda_exec_init_verbs(codec);
1897 if (codec->patch_ops.resume) 2135 if (codec->patch_ops.resume)
1898 codec->patch_ops.resume(codec); 2136 codec->patch_ops.resume(codec);
1899 else { 2137 else {
@@ -1914,28 +2152,37 @@ static void hda_call_codec_resume(struct hda_codec *codec)
1914 * 2152 *
1915 * Returns 0 if successful, otherwise a negative error code. 2153 * Returns 0 if successful, otherwise a negative error code.
1916 */ 2154 */
1917int __devinit snd_hda_build_controls(struct hda_bus *bus) 2155int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
1918{ 2156{
1919 struct hda_codec *codec; 2157 struct hda_codec *codec;
1920 2158
1921 list_for_each_entry(codec, &bus->codec_list, list) { 2159 list_for_each_entry(codec, &bus->codec_list, list) {
1922 int err = 0; 2160 int err = snd_hda_codec_build_controls(codec);
1923 /* fake as if already powered-on */
1924 hda_keep_power_on(codec);
1925 /* then fire up */
1926 hda_set_power_state(codec,
1927 codec->afg ? codec->afg : codec->mfg,
1928 AC_PWRST_D0);
1929 /* continue to initialize... */
1930 if (codec->patch_ops.init)
1931 err = codec->patch_ops.init(codec);
1932 if (!err && codec->patch_ops.build_controls)
1933 err = codec->patch_ops.build_controls(codec);
1934 snd_hda_power_down(codec);
1935 if (err < 0) 2161 if (err < 0)
1936 return err; 2162 return err;
1937 } 2163 }
2164 return 0;
2165}
2166EXPORT_SYMBOL_HDA(snd_hda_build_controls);
1938 2167
2168int snd_hda_codec_build_controls(struct hda_codec *codec)
2169{
2170 int err = 0;
2171 /* fake as if already powered-on */
2172 hda_keep_power_on(codec);
2173 /* then fire up */
2174 hda_set_power_state(codec,
2175 codec->afg ? codec->afg : codec->mfg,
2176 AC_PWRST_D0);
2177 hda_exec_init_verbs(codec);
2178 /* continue to initialize... */
2179 if (codec->patch_ops.init)
2180 err = codec->patch_ops.init(codec);
2181 if (!err && codec->patch_ops.build_controls)
2182 err = codec->patch_ops.build_controls(codec);
2183 snd_hda_power_down(codec);
2184 if (err < 0)
2185 return err;
1939 return 0; 2186 return 0;
1940} 2187}
1941 2188
@@ -2028,6 +2275,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2028 2275
2029 return val; 2276 return val;
2030} 2277}
2278EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
2031 2279
2032/** 2280/**
2033 * snd_hda_query_supported_pcm - query the supported PCM rates and formats 2281 * snd_hda_query_supported_pcm - query the supported PCM rates and formats
@@ -2042,7 +2290,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
2042 * 2290 *
2043 * Returns 0 if successful, otherwise a negative error code. 2291 * Returns 0 if successful, otherwise a negative error code.
2044 */ 2292 */
2045int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 2293static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
2046 u32 *ratesp, u64 *formatsp, unsigned int *bpsp) 2294 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
2047{ 2295{
2048 int i; 2296 int i;
@@ -2207,6 +2455,7 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
2207 2455
2208 return 1; 2456 return 1;
2209} 2457}
2458EXPORT_SYMBOL_HDA(snd_hda_is_supported_format);
2210 2459
2211/* 2460/*
2212 * PCM stuff 2461 * PCM stuff
@@ -2236,8 +2485,8 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
2236 return 0; 2485 return 0;
2237} 2486}
2238 2487
2239static int __devinit set_pcm_default_values(struct hda_codec *codec, 2488static int set_pcm_default_values(struct hda_codec *codec,
2240 struct hda_pcm_stream *info) 2489 struct hda_pcm_stream *info)
2241{ 2490{
2242 /* query support PCM information from the given NID */ 2491 /* query support PCM information from the given NID */
2243 if (info->nid && (!info->rates || !info->formats)) { 2492 if (info->nid && (!info->rates || !info->formats)) {
@@ -2263,6 +2512,110 @@ static int __devinit set_pcm_default_values(struct hda_codec *codec,
2263 return 0; 2512 return 0;
2264} 2513}
2265 2514
2515/*
2516 * get the empty PCM device number to assign
2517 */
2518static int get_empty_pcm_device(struct hda_bus *bus, int type)
2519{
2520 static const char *dev_name[HDA_PCM_NTYPES] = {
2521 "Audio", "SPDIF", "HDMI", "Modem"
2522 };
2523 /* starting device index for each PCM type */
2524 static int dev_idx[HDA_PCM_NTYPES] = {
2525 [HDA_PCM_TYPE_AUDIO] = 0,
2526 [HDA_PCM_TYPE_SPDIF] = 1,
2527 [HDA_PCM_TYPE_HDMI] = 3,
2528 [HDA_PCM_TYPE_MODEM] = 6
2529 };
2530 /* normal audio device indices; not linear to keep compatibility */
2531 static int audio_idx[4] = { 0, 2, 4, 5 };
2532 int i, dev;
2533
2534 switch (type) {
2535 case HDA_PCM_TYPE_AUDIO:
2536 for (i = 0; i < ARRAY_SIZE(audio_idx); i++) {
2537 dev = audio_idx[i];
2538 if (!test_bit(dev, bus->pcm_dev_bits))
2539 break;
2540 }
2541 if (i >= ARRAY_SIZE(audio_idx)) {
2542 snd_printk(KERN_WARNING "Too many audio devices\n");
2543 return -EAGAIN;
2544 }
2545 break;
2546 case HDA_PCM_TYPE_SPDIF:
2547 case HDA_PCM_TYPE_HDMI:
2548 case HDA_PCM_TYPE_MODEM:
2549 dev = dev_idx[type];
2550 if (test_bit(dev, bus->pcm_dev_bits)) {
2551 snd_printk(KERN_WARNING "%s already defined\n",
2552 dev_name[type]);
2553 return -EAGAIN;
2554 }
2555 break;
2556 default:
2557 snd_printk(KERN_WARNING "Invalid PCM type %d\n", type);
2558 return -EINVAL;
2559 }
2560 set_bit(dev, bus->pcm_dev_bits);
2561 return dev;
2562}
2563
2564/*
2565 * attach a new PCM stream
2566 */
2567static int snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
2568{
2569 struct hda_bus *bus = codec->bus;
2570 struct hda_pcm_stream *info;
2571 int stream, err;
2572
2573 if (snd_BUG_ON(!pcm->name))
2574 return -EINVAL;
2575 for (stream = 0; stream < 2; stream++) {
2576 info = &pcm->stream[stream];
2577 if (info->substreams) {
2578 err = set_pcm_default_values(codec, info);
2579 if (err < 0)
2580 return err;
2581 }
2582 }
2583 return bus->ops.attach_pcm(bus, codec, pcm);
2584}
2585
2586/* assign all PCMs of the given codec */
2587int snd_hda_codec_build_pcms(struct hda_codec *codec)
2588{
2589 unsigned int pcm;
2590 int err;
2591
2592 if (!codec->num_pcms) {
2593 if (!codec->patch_ops.build_pcms)
2594 return 0;
2595 err = codec->patch_ops.build_pcms(codec);
2596 if (err < 0)
2597 return err;
2598 }
2599 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
2600 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
2601 int dev;
2602
2603 if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
2604 return 0; /* no substreams assigned */
2605
2606 if (!cpcm->pcm) {
2607 dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type);
2608 if (dev < 0)
2609 return 0;
2610 cpcm->device = dev;
2611 err = snd_hda_attach_pcm(codec, cpcm);
2612 if (err < 0)
2613 return err;
2614 }
2615 }
2616 return 0;
2617}
2618
2266/** 2619/**
2267 * snd_hda_build_pcms - build PCM information 2620 * snd_hda_build_pcms - build PCM information
2268 * @bus: the BUS 2621 * @bus: the BUS
@@ -2294,27 +2647,13 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus)
2294 struct hda_codec *codec; 2647 struct hda_codec *codec;
2295 2648
2296 list_for_each_entry(codec, &bus->codec_list, list) { 2649 list_for_each_entry(codec, &bus->codec_list, list) {
2297 unsigned int pcm, s; 2650 int err = snd_hda_codec_build_pcms(codec);
2298 int err;
2299 if (!codec->patch_ops.build_pcms)
2300 continue;
2301 err = codec->patch_ops.build_pcms(codec);
2302 if (err < 0) 2651 if (err < 0)
2303 return err; 2652 return err;
2304 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
2305 for (s = 0; s < 2; s++) {
2306 struct hda_pcm_stream *info;
2307 info = &codec->pcm_info[pcm].stream[s];
2308 if (!info->substreams)
2309 continue;
2310 err = set_pcm_default_values(codec, info);
2311 if (err < 0)
2312 return err;
2313 }
2314 }
2315 } 2653 }
2316 return 0; 2654 return 0;
2317} 2655}
2656EXPORT_SYMBOL_HDA(snd_hda_build_pcms);
2318 2657
2319/** 2658/**
2320 * snd_hda_check_board_config - compare the current codec with the config table 2659 * snd_hda_check_board_config - compare the current codec with the config table
@@ -2333,11 +2672,11 @@ int snd_hda_check_board_config(struct hda_codec *codec,
2333 int num_configs, const char **models, 2672 int num_configs, const char **models,
2334 const struct snd_pci_quirk *tbl) 2673 const struct snd_pci_quirk *tbl)
2335{ 2674{
2336 if (codec->bus->modelname && models) { 2675 if (codec->modelname && models) {
2337 int i; 2676 int i;
2338 for (i = 0; i < num_configs; i++) { 2677 for (i = 0; i < num_configs; i++) {
2339 if (models[i] && 2678 if (models[i] &&
2340 !strcmp(codec->bus->modelname, models[i])) { 2679 !strcmp(codec->modelname, models[i])) {
2341 snd_printd(KERN_INFO "hda_codec: model '%s' is " 2680 snd_printd(KERN_INFO "hda_codec: model '%s' is "
2342 "selected\n", models[i]); 2681 "selected\n", models[i]);
2343 return i; 2682 return i;
@@ -2370,6 +2709,7 @@ int snd_hda_check_board_config(struct hda_codec *codec,
2370 } 2709 }
2371 return -1; 2710 return -1;
2372} 2711}
2712EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
2373 2713
2374/** 2714/**
2375 * snd_hda_add_new_ctls - create controls from the array 2715 * snd_hda_add_new_ctls - create controls from the array
@@ -2390,7 +2730,7 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
2390 kctl = snd_ctl_new1(knew, codec); 2730 kctl = snd_ctl_new1(knew, codec);
2391 if (!kctl) 2731 if (!kctl)
2392 return -ENOMEM; 2732 return -ENOMEM;
2393 err = snd_ctl_add(codec->bus->card, kctl); 2733 err = snd_hda_ctl_add(codec, kctl);
2394 if (err < 0) { 2734 if (err < 0) {
2395 if (!codec->addr) 2735 if (!codec->addr)
2396 return err; 2736 return err;
@@ -2398,13 +2738,14 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
2398 if (!kctl) 2738 if (!kctl)
2399 return -ENOMEM; 2739 return -ENOMEM;
2400 kctl->id.device = codec->addr; 2740 kctl->id.device = codec->addr;
2401 err = snd_ctl_add(codec->bus->card, kctl); 2741 err = snd_hda_ctl_add(codec, kctl);
2402 if (err < 0) 2742 if (err < 0)
2403 return err; 2743 return err;
2404 } 2744 }
2405 } 2745 }
2406 return 0; 2746 return 0;
2407} 2747}
2748EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
2408 2749
2409#ifdef CONFIG_SND_HDA_POWER_SAVE 2750#ifdef CONFIG_SND_HDA_POWER_SAVE
2410static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, 2751static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
@@ -2414,6 +2755,7 @@ static void hda_power_work(struct work_struct *work)
2414{ 2755{
2415 struct hda_codec *codec = 2756 struct hda_codec *codec =
2416 container_of(work, struct hda_codec, power_work.work); 2757 container_of(work, struct hda_codec, power_work.work);
2758 struct hda_bus *bus = codec->bus;
2417 2759
2418 if (!codec->power_on || codec->power_count) { 2760 if (!codec->power_on || codec->power_count) {
2419 codec->power_transition = 0; 2761 codec->power_transition = 0;
@@ -2421,8 +2763,8 @@ static void hda_power_work(struct work_struct *work)
2421 } 2763 }
2422 2764
2423 hda_call_codec_suspend(codec); 2765 hda_call_codec_suspend(codec);
2424 if (codec->bus->ops.pm_notify) 2766 if (bus->ops.pm_notify)
2425 codec->bus->ops.pm_notify(codec); 2767 bus->ops.pm_notify(bus);
2426} 2768}
2427 2769
2428static void hda_keep_power_on(struct hda_codec *codec) 2770static void hda_keep_power_on(struct hda_codec *codec)
@@ -2433,29 +2775,39 @@ static void hda_keep_power_on(struct hda_codec *codec)
2433 2775
2434void snd_hda_power_up(struct hda_codec *codec) 2776void snd_hda_power_up(struct hda_codec *codec)
2435{ 2777{
2778 struct hda_bus *bus = codec->bus;
2779
2436 codec->power_count++; 2780 codec->power_count++;
2437 if (codec->power_on || codec->power_transition) 2781 if (codec->power_on || codec->power_transition)
2438 return; 2782 return;
2439 2783
2440 codec->power_on = 1; 2784 codec->power_on = 1;
2441 if (codec->bus->ops.pm_notify) 2785 if (bus->ops.pm_notify)
2442 codec->bus->ops.pm_notify(codec); 2786 bus->ops.pm_notify(bus);
2443 hda_call_codec_resume(codec); 2787 hda_call_codec_resume(codec);
2444 cancel_delayed_work(&codec->power_work); 2788 cancel_delayed_work(&codec->power_work);
2445 codec->power_transition = 0; 2789 codec->power_transition = 0;
2446} 2790}
2791EXPORT_SYMBOL_HDA(snd_hda_power_up);
2792
2793#define power_save(codec) \
2794 ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
2795
2796#define power_save(codec) \
2797 ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
2447 2798
2448void snd_hda_power_down(struct hda_codec *codec) 2799void snd_hda_power_down(struct hda_codec *codec)
2449{ 2800{
2450 --codec->power_count; 2801 --codec->power_count;
2451 if (!codec->power_on || codec->power_count || codec->power_transition) 2802 if (!codec->power_on || codec->power_count || codec->power_transition)
2452 return; 2803 return;
2453 if (power_save) { 2804 if (power_save(codec)) {
2454 codec->power_transition = 1; /* avoid reentrance */ 2805 codec->power_transition = 1; /* avoid reentrance */
2455 schedule_delayed_work(&codec->power_work, 2806 schedule_delayed_work(&codec->power_work,
2456 msecs_to_jiffies(power_save * 1000)); 2807 msecs_to_jiffies(power_save(codec) * 1000));
2457 } 2808 }
2458} 2809}
2810EXPORT_SYMBOL_HDA(snd_hda_power_down);
2459 2811
2460int snd_hda_check_amp_list_power(struct hda_codec *codec, 2812int snd_hda_check_amp_list_power(struct hda_codec *codec,
2461 struct hda_loopback_check *check, 2813 struct hda_loopback_check *check,
@@ -2492,6 +2844,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
2492 } 2844 }
2493 return 0; 2845 return 0;
2494} 2846}
2847EXPORT_SYMBOL_HDA(snd_hda_check_amp_list_power);
2495#endif 2848#endif
2496 2849
2497/* 2850/*
@@ -2511,6 +2864,7 @@ int snd_hda_ch_mode_info(struct hda_codec *codec,
2511 chmode[uinfo->value.enumerated.item].channels); 2864 chmode[uinfo->value.enumerated.item].channels);
2512 return 0; 2865 return 0;
2513} 2866}
2867EXPORT_SYMBOL_HDA(snd_hda_ch_mode_info);
2514 2868
2515int snd_hda_ch_mode_get(struct hda_codec *codec, 2869int snd_hda_ch_mode_get(struct hda_codec *codec,
2516 struct snd_ctl_elem_value *ucontrol, 2870 struct snd_ctl_elem_value *ucontrol,
@@ -2528,6 +2882,7 @@ int snd_hda_ch_mode_get(struct hda_codec *codec,
2528 } 2882 }
2529 return 0; 2883 return 0;
2530} 2884}
2885EXPORT_SYMBOL_HDA(snd_hda_ch_mode_get);
2531 2886
2532int snd_hda_ch_mode_put(struct hda_codec *codec, 2887int snd_hda_ch_mode_put(struct hda_codec *codec,
2533 struct snd_ctl_elem_value *ucontrol, 2888 struct snd_ctl_elem_value *ucontrol,
@@ -2548,6 +2903,7 @@ int snd_hda_ch_mode_put(struct hda_codec *codec,
2548 snd_hda_sequence_write_cache(codec, chmode[mode].sequence); 2903 snd_hda_sequence_write_cache(codec, chmode[mode].sequence);
2549 return 1; 2904 return 1;
2550} 2905}
2906EXPORT_SYMBOL_HDA(snd_hda_ch_mode_put);
2551 2907
2552/* 2908/*
2553 * input MUX helper 2909 * input MUX helper
@@ -2568,6 +2924,7 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux,
2568 strcpy(uinfo->value.enumerated.name, imux->items[index].label); 2924 strcpy(uinfo->value.enumerated.name, imux->items[index].label);
2569 return 0; 2925 return 0;
2570} 2926}
2927EXPORT_SYMBOL_HDA(snd_hda_input_mux_info);
2571 2928
2572int snd_hda_input_mux_put(struct hda_codec *codec, 2929int snd_hda_input_mux_put(struct hda_codec *codec,
2573 const struct hda_input_mux *imux, 2930 const struct hda_input_mux *imux,
@@ -2589,6 +2946,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec,
2589 *cur_val = idx; 2946 *cur_val = idx;
2590 return 1; 2947 return 1;
2591} 2948}
2949EXPORT_SYMBOL_HDA(snd_hda_input_mux_put);
2592 2950
2593 2951
2594/* 2952/*
@@ -2641,6 +2999,7 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec,
2641 mutex_unlock(&codec->spdif_mutex); 2999 mutex_unlock(&codec->spdif_mutex);
2642 return 0; 3000 return 0;
2643} 3001}
3002EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_open);
2644 3003
2645int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, 3004int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
2646 struct hda_multi_out *mout, 3005 struct hda_multi_out *mout,
@@ -2653,6 +3012,7 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
2653 mutex_unlock(&codec->spdif_mutex); 3012 mutex_unlock(&codec->spdif_mutex);
2654 return 0; 3013 return 0;
2655} 3014}
3015EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare);
2656 3016
2657/* 3017/*
2658 * release the digital out 3018 * release the digital out
@@ -2665,6 +3025,7 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec,
2665 mutex_unlock(&codec->spdif_mutex); 3025 mutex_unlock(&codec->spdif_mutex);
2666 return 0; 3026 return 0;
2667} 3027}
3028EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_close);
2668 3029
2669/* 3030/*
2670 * set up more restrictions for analog out 3031 * set up more restrictions for analog out
@@ -2704,6 +3065,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec,
2704 return snd_pcm_hw_constraint_step(substream->runtime, 0, 3065 return snd_pcm_hw_constraint_step(substream->runtime, 0,
2705 SNDRV_PCM_HW_PARAM_CHANNELS, 2); 3066 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
2706} 3067}
3068EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open);
2707 3069
2708/* 3070/*
2709 * set up the i/o for analog out 3071 * set up the i/o for analog out
@@ -2762,6 +3124,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
2762 } 3124 }
2763 return 0; 3125 return 0;
2764} 3126}
3127EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare);
2765 3128
2766/* 3129/*
2767 * clean up the setting for analog out 3130 * clean up the setting for analog out
@@ -2788,6 +3151,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
2788 mutex_unlock(&codec->spdif_mutex); 3151 mutex_unlock(&codec->spdif_mutex);
2789 return 0; 3152 return 0;
2790} 3153}
3154EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
2791 3155
2792/* 3156/*
2793 * Helper for automatic pin configuration 3157 * Helper for automatic pin configuration
@@ -3073,11 +3437,13 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
3073 3437
3074 return 0; 3438 return 0;
3075} 3439}
3440EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config);
3076 3441
3077/* labels for input pins */ 3442/* labels for input pins */
3078const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = { 3443const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = {
3079 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux" 3444 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
3080}; 3445};
3446EXPORT_SYMBOL_HDA(auto_pin_cfg_labels);
3081 3447
3082 3448
3083#ifdef CONFIG_PM 3449#ifdef CONFIG_PM
@@ -3105,11 +3471,11 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state)
3105 } 3471 }
3106 return 0; 3472 return 0;
3107} 3473}
3474EXPORT_SYMBOL_HDA(snd_hda_suspend);
3108 3475
3109/** 3476/**
3110 * snd_hda_resume - resume the codecs 3477 * snd_hda_resume - resume the codecs
3111 * @bus: the HDA bus 3478 * @bus: the HDA bus
3112 * @state: resume state
3113 * 3479 *
3114 * Returns 0 if successful. 3480 * Returns 0 if successful.
3115 * 3481 *
@@ -3126,16 +3492,79 @@ int snd_hda_resume(struct hda_bus *bus)
3126 } 3492 }
3127 return 0; 3493 return 0;
3128} 3494}
3129#ifdef CONFIG_SND_HDA_POWER_SAVE 3495EXPORT_SYMBOL_HDA(snd_hda_resume);
3130int snd_hda_codecs_inuse(struct hda_bus *bus) 3496#endif /* CONFIG_PM */
3131{
3132 struct hda_codec *codec;
3133 3497
3134 list_for_each_entry(codec, &bus->codec_list, list) { 3498/*
3135 if (snd_hda_codec_needs_resume(codec)) 3499 * generic arrays
3136 return 1; 3500 */
3501
3502/* get a new element from the given array
3503 * if it exceeds the pre-allocated array size, re-allocate the array
3504 */
3505void *snd_array_new(struct snd_array *array)
3506{
3507 if (array->used >= array->alloced) {
3508 int num = array->alloced + array->alloc_align;
3509 void *nlist;
3510 if (snd_BUG_ON(num >= 4096))
3511 return NULL;
3512 nlist = kcalloc(num + 1, array->elem_size, GFP_KERNEL);
3513 if (!nlist)
3514 return NULL;
3515 if (array->list) {
3516 memcpy(nlist, array->list,
3517 array->elem_size * array->alloced);
3518 kfree(array->list);
3519 }
3520 array->list = nlist;
3521 array->alloced = num;
3137 } 3522 }
3138 return 0; 3523 return snd_array_elem(array, array->used++);
3139} 3524}
3140#endif 3525EXPORT_SYMBOL_HDA(snd_array_new);
3141#endif 3526
3527/* free the given array elements */
3528void snd_array_free(struct snd_array *array)
3529{
3530 kfree(array->list);
3531 array->used = 0;
3532 array->alloced = 0;
3533 array->list = NULL;
3534}
3535EXPORT_SYMBOL_HDA(snd_array_free);
3536
3537/*
3538 * used by hda_proc.c and hda_eld.c
3539 */
3540void snd_print_pcm_rates(int pcm, char *buf, int buflen)
3541{
3542 static unsigned int rates[] = {
3543 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
3544 96000, 176400, 192000, 384000
3545 };
3546 int i, j;
3547
3548 for (i = 0, j = 0; i < ARRAY_SIZE(rates); i++)
3549 if (pcm & (1 << i))
3550 j += snprintf(buf + j, buflen - j, " %d", rates[i]);
3551
3552 buf[j] = '\0'; /* necessary when j == 0 */
3553}
3554EXPORT_SYMBOL_HDA(snd_print_pcm_rates);
3555
3556void snd_print_pcm_bits(int pcm, char *buf, int buflen)
3557{
3558 static unsigned int bits[] = { 8, 16, 20, 24, 32 };
3559 int i, j;
3560
3561 for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++)
3562 if (pcm & (AC_SUPPCM_BITS_8 << i))
3563 j += snprintf(buf + j, buflen - j, " %d", bits[i]);
3564
3565 buf[j] = '\0'; /* necessary when j == 0 */
3566}
3567EXPORT_SYMBOL_HDA(snd_print_pcm_bits);
3568
3569MODULE_DESCRIPTION("HDA codec core");
3570MODULE_LICENSE("GPL");
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 60468f562400..729fc7642d7f 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -520,6 +520,36 @@ enum {
520#define HDA_MAX_CODEC_ADDRESS 0x0f 520#define HDA_MAX_CODEC_ADDRESS 0x0f
521 521
522/* 522/*
523 * generic arrays
524 */
525struct snd_array {
526 unsigned int used;
527 unsigned int alloced;
528 unsigned int elem_size;
529 unsigned int alloc_align;
530 void *list;
531};
532
533void *snd_array_new(struct snd_array *array);
534void snd_array_free(struct snd_array *array);
535static inline void snd_array_init(struct snd_array *array, unsigned int size,
536 unsigned int align)
537{
538 array->elem_size = size;
539 array->alloc_align = align;
540}
541
542static inline void *snd_array_elem(struct snd_array *array, unsigned int idx)
543{
544 return array->list + idx * array->elem_size;
545}
546
547static inline unsigned int snd_array_index(struct snd_array *array, void *ptr)
548{
549 return (unsigned long)(ptr - array->list) / array->elem_size;
550}
551
552/*
523 * Structures 553 * Structures
524 */ 554 */
525 555
@@ -536,15 +566,17 @@ typedef u16 hda_nid_t;
536/* bus operators */ 566/* bus operators */
537struct hda_bus_ops { 567struct hda_bus_ops {
538 /* send a single command */ 568 /* send a single command */
539 int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct, 569 int (*command)(struct hda_bus *bus, unsigned int cmd);
540 unsigned int verb, unsigned int parm);
541 /* get a response from the last command */ 570 /* get a response from the last command */
542 unsigned int (*get_response)(struct hda_codec *codec); 571 unsigned int (*get_response)(struct hda_bus *bus);
543 /* free the private data */ 572 /* free the private data */
544 void (*private_free)(struct hda_bus *); 573 void (*private_free)(struct hda_bus *);
574 /* attach a PCM stream */
575 int (*attach_pcm)(struct hda_bus *bus, struct hda_codec *codec,
576 struct hda_pcm *pcm);
545#ifdef CONFIG_SND_HDA_POWER_SAVE 577#ifdef CONFIG_SND_HDA_POWER_SAVE
546 /* notify power-up/down from codec to controller */ 578 /* notify power-up/down from codec to controller */
547 void (*pm_notify)(struct hda_codec *codec); 579 void (*pm_notify)(struct hda_bus *bus);
548#endif 580#endif
549}; 581};
550 582
@@ -553,6 +585,7 @@ struct hda_bus_template {
553 void *private_data; 585 void *private_data;
554 struct pci_dev *pci; 586 struct pci_dev *pci;
555 const char *modelname; 587 const char *modelname;
588 int *power_save;
556 struct hda_bus_ops ops; 589 struct hda_bus_ops ops;
557}; 590};
558 591
@@ -569,6 +602,7 @@ struct hda_bus {
569 void *private_data; 602 void *private_data;
570 struct pci_dev *pci; 603 struct pci_dev *pci;
571 const char *modelname; 604 const char *modelname;
605 int *power_save;
572 struct hda_bus_ops ops; 606 struct hda_bus_ops ops;
573 607
574 /* codec linked list */ 608 /* codec linked list */
@@ -581,10 +615,12 @@ struct hda_bus {
581 /* unsolicited event queue */ 615 /* unsolicited event queue */
582 struct hda_bus_unsolicited *unsol; 616 struct hda_bus_unsolicited *unsol;
583 617
584 struct snd_info_entry *proc; 618 /* assigned PCMs */
619 DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
585 620
586 /* misc op flags */ 621 /* misc op flags */
587 unsigned int needs_damn_long_delay :1; 622 unsigned int needs_damn_long_delay :1;
623 unsigned int shutdown :1; /* being unloaded */
588}; 624};
589 625
590/* 626/*
@@ -604,6 +640,16 @@ struct hda_codec_preset {
604 int (*patch)(struct hda_codec *codec); 640 int (*patch)(struct hda_codec *codec);
605}; 641};
606 642
643struct hda_codec_preset_list {
644 const struct hda_codec_preset *preset;
645 struct module *owner;
646 struct list_head list;
647};
648
649/* initial hook */
650int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset);
651int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset);
652
607/* ops set by the preset patch */ 653/* ops set by the preset patch */
608struct hda_codec_ops { 654struct hda_codec_ops {
609 int (*build_controls)(struct hda_codec *codec); 655 int (*build_controls)(struct hda_codec *codec);
@@ -635,10 +681,7 @@ struct hda_amp_info {
635 681
636struct hda_cache_rec { 682struct hda_cache_rec {
637 u16 hash[64]; /* hash table for index */ 683 u16 hash[64]; /* hash table for index */
638 unsigned int num_entries; /* number of assigned entries */ 684 struct snd_array buf; /* record entries */
639 unsigned int size; /* allocated size */
640 unsigned int record_size; /* record size (including header) */
641 void *buffer; /* hash table entries */
642}; 685};
643 686
644/* PCM callbacks */ 687/* PCM callbacks */
@@ -680,7 +723,8 @@ struct hda_pcm {
680 char *name; 723 char *name;
681 struct hda_pcm_stream stream[2]; 724 struct hda_pcm_stream stream[2];
682 unsigned int pcm_type; /* HDA_PCM_TYPE_XXX */ 725 unsigned int pcm_type; /* HDA_PCM_TYPE_XXX */
683 int device; /* assigned device number */ 726 int device; /* device number to assign */
727 struct snd_pcm *pcm; /* assigned PCM instance */
684}; 728};
685 729
686/* codec information */ 730/* codec information */
@@ -699,6 +743,9 @@ struct hda_codec {
699 743
700 /* detected preset */ 744 /* detected preset */
701 const struct hda_codec_preset *preset; 745 const struct hda_codec_preset *preset;
746 struct module *owner;
747 const char *name; /* codec name */
748 const char *modelname; /* model name for preset */
702 749
703 /* set by patch */ 750 /* set by patch */
704 struct hda_codec_ops patch_ops; 751 struct hda_codec_ops patch_ops;
@@ -718,6 +765,8 @@ struct hda_codec {
718 hda_nid_t start_nid; 765 hda_nid_t start_nid;
719 u32 *wcaps; 766 u32 *wcaps;
720 767
768 struct snd_array mixers; /* list of assigned mixer elements */
769
721 struct hda_cache_rec amp_cache; /* cache for amp access */ 770 struct hda_cache_rec amp_cache; /* cache for amp access */
722 struct hda_cache_rec cmd_cache; /* cache for other commands */ 771 struct hda_cache_rec cmd_cache; /* cache for other commands */
723 772
@@ -727,7 +776,11 @@ struct hda_codec {
727 unsigned int spdif_in_enable; /* SPDIF input enable? */ 776 unsigned int spdif_in_enable; /* SPDIF input enable? */
728 hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ 777 hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
729 778
779#ifdef CONFIG_SND_HDA_HWDEP
730 struct snd_hwdep *hwdep; /* assigned hwdep device */ 780 struct snd_hwdep *hwdep; /* assigned hwdep device */
781 struct snd_array init_verbs; /* additional init verbs */
782 struct snd_array hints; /* additional hints */
783#endif
731 784
732 /* misc flags */ 785 /* misc flags */
733 unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each 786 unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each
@@ -740,6 +793,10 @@ struct hda_codec {
740 int power_count; /* current (global) power refcount */ 793 int power_count; /* current (global) power refcount */
741 struct delayed_work power_work; /* delayed task for powerdown */ 794 struct delayed_work power_work; /* delayed task for powerdown */
742#endif 795#endif
796
797 /* codec-specific additional proc output */
798 void (*proc_widget_hook)(struct snd_info_buffer *buffer,
799 struct hda_codec *codec, hda_nid_t nid);
743}; 800};
744 801
745/* direction */ 802/* direction */
@@ -754,7 +811,7 @@ enum {
754int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, 811int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp,
755 struct hda_bus **busp); 812 struct hda_bus **busp);
756int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, 813int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
757 struct hda_codec **codecp); 814 int do_init, struct hda_codec **codecp);
758 815
759/* 816/*
760 * low level functions 817 * low level functions
@@ -799,11 +856,13 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec);
799 * Mixer 856 * Mixer
800 */ 857 */
801int snd_hda_build_controls(struct hda_bus *bus); 858int snd_hda_build_controls(struct hda_bus *bus);
859int snd_hda_codec_build_controls(struct hda_codec *codec);
802 860
803/* 861/*
804 * PCM 862 * PCM
805 */ 863 */
806int snd_hda_build_pcms(struct hda_bus *bus); 864int snd_hda_build_pcms(struct hda_bus *bus);
865int snd_hda_codec_build_pcms(struct hda_codec *codec);
807void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, 866void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
808 u32 stream_tag, 867 u32 stream_tag,
809 int channel_id, int format); 868 int channel_id, int format);
@@ -812,8 +871,6 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate,
812 unsigned int channels, 871 unsigned int channels,
813 unsigned int format, 872 unsigned int format,
814 unsigned int maxbps); 873 unsigned int maxbps);
815int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
816 u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
817int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, 874int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
818 unsigned int format); 875 unsigned int format);
819 876
@@ -831,18 +888,38 @@ int snd_hda_resume(struct hda_bus *bus);
831#endif 888#endif
832 889
833/* 890/*
891 * get widget information
892 */
893const char *snd_hda_get_jack_connectivity(u32 cfg);
894const char *snd_hda_get_jack_type(u32 cfg);
895const char *snd_hda_get_jack_location(u32 cfg);
896
897/*
834 * power saving 898 * power saving
835 */ 899 */
836#ifdef CONFIG_SND_HDA_POWER_SAVE 900#ifdef CONFIG_SND_HDA_POWER_SAVE
837void snd_hda_power_up(struct hda_codec *codec); 901void snd_hda_power_up(struct hda_codec *codec);
838void snd_hda_power_down(struct hda_codec *codec); 902void snd_hda_power_down(struct hda_codec *codec);
839#define snd_hda_codec_needs_resume(codec) codec->power_count 903#define snd_hda_codec_needs_resume(codec) codec->power_count
840int snd_hda_codecs_inuse(struct hda_bus *bus);
841#else 904#else
842static inline void snd_hda_power_up(struct hda_codec *codec) {} 905static inline void snd_hda_power_up(struct hda_codec *codec) {}
843static inline void snd_hda_power_down(struct hda_codec *codec) {} 906static inline void snd_hda_power_down(struct hda_codec *codec) {}
844#define snd_hda_codec_needs_resume(codec) 1 907#define snd_hda_codec_needs_resume(codec) 1
845#define snd_hda_codecs_inuse(bus) 1 908#endif
909
910/*
911 * Codec modularization
912 */
913
914/* Export symbols only for communication with codec drivers;
915 * When built in kernel, all HD-audio drivers are supposed to be statically
916 * linked to the kernel. Thus, the symbols don't have to (or shouldn't) be
917 * exported unless it's built as a module.
918 */
919#ifdef MODULE
920#define EXPORT_SYMBOL_HDA(sym) EXPORT_SYMBOL_GPL(sym)
921#else
922#define EXPORT_SYMBOL_HDA(sym)
846#endif 923#endif
847 924
848#endif /* __SOUND_HDA_CODEC_H */ 925#endif /* __SOUND_HDA_CODEC_H */
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
new file mode 100644
index 000000000000..fcad5ec31773
--- /dev/null
+++ b/sound/pci/hda/hda_eld.c
@@ -0,0 +1,590 @@
1/*
2 * Generic routines and proc interface for ELD(EDID Like Data) information
3 *
4 * Copyright(c) 2008 Intel Corporation.
5 *
6 * Authors:
7 * Wu Fengguang <wfg@linux.intel.com>
8 *
9 * This driver is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This driver is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24#include <linux/init.h>
25#include <sound/core.h>
26#include <asm/unaligned.h>
27#include "hda_codec.h"
28#include "hda_local.h"
29
30enum eld_versions {
31 ELD_VER_CEA_861D = 2,
32 ELD_VER_PARTIAL = 31,
33};
34
35enum cea_edid_versions {
36 CEA_EDID_VER_NONE = 0,
37 CEA_EDID_VER_CEA861 = 1,
38 CEA_EDID_VER_CEA861A = 2,
39 CEA_EDID_VER_CEA861BCD = 3,
40 CEA_EDID_VER_RESERVED = 4,
41};
42
43static char *cea_speaker_allocation_names[] = {
44 /* 0 */ "FL/FR",
45 /* 1 */ "LFE",
46 /* 2 */ "FC",
47 /* 3 */ "RL/RR",
48 /* 4 */ "RC",
49 /* 5 */ "FLC/FRC",
50 /* 6 */ "RLC/RRC",
51 /* 7 */ "FLW/FRW",
52 /* 8 */ "FLH/FRH",
53 /* 9 */ "TC",
54 /* 10 */ "FCH",
55};
56
57static char *eld_connection_type_names[4] = {
58 "HDMI",
59 "DisplayPort",
60 "2-reserved",
61 "3-reserved"
62};
63
64enum cea_audio_coding_types {
65 AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
66 AUDIO_CODING_TYPE_LPCM = 1,
67 AUDIO_CODING_TYPE_AC3 = 2,
68 AUDIO_CODING_TYPE_MPEG1 = 3,
69 AUDIO_CODING_TYPE_MP3 = 4,
70 AUDIO_CODING_TYPE_MPEG2 = 5,
71 AUDIO_CODING_TYPE_AACLC = 6,
72 AUDIO_CODING_TYPE_DTS = 7,
73 AUDIO_CODING_TYPE_ATRAC = 8,
74 AUDIO_CODING_TYPE_SACD = 9,
75 AUDIO_CODING_TYPE_EAC3 = 10,
76 AUDIO_CODING_TYPE_DTS_HD = 11,
77 AUDIO_CODING_TYPE_MLP = 12,
78 AUDIO_CODING_TYPE_DST = 13,
79 AUDIO_CODING_TYPE_WMAPRO = 14,
80 AUDIO_CODING_TYPE_REF_CXT = 15,
81 /* also include valid xtypes below */
82 AUDIO_CODING_TYPE_HE_AAC = 15,
83 AUDIO_CODING_TYPE_HE_AAC2 = 16,
84 AUDIO_CODING_TYPE_MPEG_SURROUND = 17,
85};
86
87enum cea_audio_coding_xtypes {
88 AUDIO_CODING_XTYPE_HE_REF_CT = 0,
89 AUDIO_CODING_XTYPE_HE_AAC = 1,
90 AUDIO_CODING_XTYPE_HE_AAC2 = 2,
91 AUDIO_CODING_XTYPE_MPEG_SURROUND = 3,
92 AUDIO_CODING_XTYPE_FIRST_RESERVED = 4,
93};
94
95static char *cea_audio_coding_type_names[] = {
96 /* 0 */ "undefined",
97 /* 1 */ "LPCM",
98 /* 2 */ "AC-3",
99 /* 3 */ "MPEG1",
100 /* 4 */ "MP3",
101 /* 5 */ "MPEG2",
102 /* 6 */ "AAC-LC",
103 /* 7 */ "DTS",
104 /* 8 */ "ATRAC",
105 /* 9 */ "DSD (One Bit Audio)",
106 /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)",
107 /* 11 */ "DTS-HD",
108 /* 12 */ "MLP (Dolby TrueHD)",
109 /* 13 */ "DST",
110 /* 14 */ "WMAPro",
111 /* 15 */ "HE-AAC",
112 /* 16 */ "HE-AACv2",
113 /* 17 */ "MPEG Surround",
114};
115
116/*
117 * The following two lists are shared between
118 * - HDMI audio InfoFrame (source to sink)
119 * - CEA E-EDID Extension (sink to source)
120 */
121
122/*
123 * SS1:SS0 index => sample size
124 */
125static int cea_sample_sizes[4] = {
126 0, /* 0: Refer to Stream Header */
127 AC_SUPPCM_BITS_16, /* 1: 16 bits */
128 AC_SUPPCM_BITS_20, /* 2: 20 bits */
129 AC_SUPPCM_BITS_24, /* 3: 24 bits */
130};
131
132/*
133 * SF2:SF1:SF0 index => sampling frequency
134 */
135static int cea_sampling_frequencies[8] = {
136 0, /* 0: Refer to Stream Header */
137 SNDRV_PCM_RATE_32000, /* 1: 32000Hz */
138 SNDRV_PCM_RATE_44100, /* 2: 44100Hz */
139 SNDRV_PCM_RATE_48000, /* 3: 48000Hz */
140 SNDRV_PCM_RATE_88200, /* 4: 88200Hz */
141 SNDRV_PCM_RATE_96000, /* 5: 96000Hz */
142 SNDRV_PCM_RATE_176400, /* 6: 176400Hz */
143 SNDRV_PCM_RATE_192000, /* 7: 192000Hz */
144};
145
146static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid,
147 int byte_index)
148{
149 unsigned int val;
150
151 val = snd_hda_codec_read(codec, nid, 0,
152 AC_VERB_GET_HDMI_ELDD, byte_index);
153
154#ifdef BE_PARANOID
155 printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
156#endif
157
158 if ((val & AC_ELDD_ELD_VALID) == 0) {
159 snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n",
160 byte_index);
161 val = 0;
162 }
163
164 return val & AC_ELDD_ELD_DATA;
165}
166
167#define GRAB_BITS(buf, byte, lowbit, bits) \
168({ \
169 BUILD_BUG_ON(lowbit > 7); \
170 BUILD_BUG_ON(bits > 8); \
171 BUILD_BUG_ON(bits <= 0); \
172 \
173 (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \
174})
175
176static void hdmi_update_short_audio_desc(struct cea_sad *a,
177 const unsigned char *buf)
178{
179 int i;
180 int val;
181
182 val = GRAB_BITS(buf, 1, 0, 7);
183 a->rates = 0;
184 for (i = 0; i < 7; i++)
185 if (val & (1 << i))
186 a->rates |= cea_sampling_frequencies[i + 1];
187
188 a->channels = GRAB_BITS(buf, 0, 0, 3);
189 a->channels++;
190
191 a->format = GRAB_BITS(buf, 0, 3, 4);
192 switch (a->format) {
193 case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
194 snd_printd(KERN_INFO
195 "HDMI: audio coding type 0 not expected\n");
196 break;
197
198 case AUDIO_CODING_TYPE_LPCM:
199 val = GRAB_BITS(buf, 2, 0, 3);
200 a->sample_bits = 0;
201 for (i = 0; i < 3; i++)
202 if (val & (1 << i))
203 a->sample_bits |= cea_sample_sizes[i + 1];
204 break;
205
206 case AUDIO_CODING_TYPE_AC3:
207 case AUDIO_CODING_TYPE_MPEG1:
208 case AUDIO_CODING_TYPE_MP3:
209 case AUDIO_CODING_TYPE_MPEG2:
210 case AUDIO_CODING_TYPE_AACLC:
211 case AUDIO_CODING_TYPE_DTS:
212 case AUDIO_CODING_TYPE_ATRAC:
213 a->max_bitrate = GRAB_BITS(buf, 2, 0, 8);
214 a->max_bitrate *= 8000;
215 break;
216
217 case AUDIO_CODING_TYPE_SACD:
218 break;
219
220 case AUDIO_CODING_TYPE_EAC3:
221 break;
222
223 case AUDIO_CODING_TYPE_DTS_HD:
224 break;
225
226 case AUDIO_CODING_TYPE_MLP:
227 break;
228
229 case AUDIO_CODING_TYPE_DST:
230 break;
231
232 case AUDIO_CODING_TYPE_WMAPRO:
233 a->profile = GRAB_BITS(buf, 2, 0, 3);
234 break;
235
236 case AUDIO_CODING_TYPE_REF_CXT:
237 a->format = GRAB_BITS(buf, 2, 3, 5);
238 if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT ||
239 a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) {
240 snd_printd(KERN_INFO
241 "HDMI: audio coding xtype %d not expected\n",
242 a->format);
243 a->format = 0;
244 } else
245 a->format += AUDIO_CODING_TYPE_HE_AAC -
246 AUDIO_CODING_XTYPE_HE_AAC;
247 break;
248 }
249}
250
251/*
252 * Be careful, ELD buf could be totally rubbish!
253 */
254static int hdmi_update_eld(struct hdmi_eld *e,
255 const unsigned char *buf, int size)
256{
257 int mnl;
258 int i;
259
260 e->eld_ver = GRAB_BITS(buf, 0, 3, 5);
261 if (e->eld_ver != ELD_VER_CEA_861D &&
262 e->eld_ver != ELD_VER_PARTIAL) {
263 snd_printd(KERN_INFO "HDMI: Unknown ELD version %d\n",
264 e->eld_ver);
265 goto out_fail;
266 }
267
268 e->eld_size = size;
269 e->baseline_len = GRAB_BITS(buf, 2, 0, 8);
270 mnl = GRAB_BITS(buf, 4, 0, 5);
271 e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3);
272
273 e->support_hdcp = GRAB_BITS(buf, 5, 0, 1);
274 e->support_ai = GRAB_BITS(buf, 5, 1, 1);
275 e->conn_type = GRAB_BITS(buf, 5, 2, 2);
276 e->sad_count = GRAB_BITS(buf, 5, 4, 4);
277
278 e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2;
279 e->spk_alloc = GRAB_BITS(buf, 7, 0, 7);
280
281 e->port_id = get_unaligned_le64(buf + 8);
282
283 /* not specified, but the spec's tendency is little endian */
284 e->manufacture_id = get_unaligned_le16(buf + 16);
285 e->product_id = get_unaligned_le16(buf + 18);
286
287 if (mnl > ELD_MAX_MNL) {
288 snd_printd(KERN_INFO "HDMI: MNL is reserved value %d\n", mnl);
289 goto out_fail;
290 } else if (ELD_FIXED_BYTES + mnl > size) {
291 snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl);
292 goto out_fail;
293 } else
294 strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl);
295
296 for (i = 0; i < e->sad_count; i++) {
297 if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) {
298 snd_printd(KERN_INFO "HDMI: out of range SAD %d\n", i);
299 goto out_fail;
300 }
301 hdmi_update_short_audio_desc(e->sad + i,
302 buf + ELD_FIXED_BYTES + mnl + 3 * i);
303 }
304
305 return 0;
306
307out_fail:
308 e->eld_ver = 0;
309 return -EINVAL;
310}
311
312static int hdmi_present_sense(struct hda_codec *codec, hda_nid_t nid)
313{
314 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0);
315}
316
317static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid)
318{
319 int eldv;
320 int present;
321
322 present = hdmi_present_sense(codec, nid);
323 eldv = (present & AC_PINSENSE_ELDV);
324 present = (present & AC_PINSENSE_PRESENCE);
325
326#ifdef CONFIG_SND_DEBUG_VERBOSE
327 printk(KERN_INFO "HDMI: sink_present = %d, eld_valid = %d\n",
328 !!present, !!eldv);
329#endif
330
331 return eldv && present;
332}
333
334int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid)
335{
336 return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE,
337 AC_DIPSIZE_ELD_BUF);
338}
339
340int snd_hdmi_get_eld(struct hdmi_eld *eld,
341 struct hda_codec *codec, hda_nid_t nid)
342{
343 int i;
344 int ret;
345 int size;
346 unsigned char *buf;
347
348 if (!hdmi_eld_valid(codec, nid))
349 return -ENOENT;
350
351 size = snd_hdmi_get_eld_size(codec, nid);
352 if (size == 0) {
353 /* wfg: workaround for ASUS P5E-VM HDMI board */
354 snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n");
355 size = 128;
356 }
357 if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) {
358 snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size);
359 return -ERANGE;
360 }
361
362 buf = kmalloc(size, GFP_KERNEL);
363 if (!buf)
364 return -ENOMEM;
365
366 for (i = 0; i < size; i++)
367 buf[i] = hdmi_get_eld_byte(codec, nid, i);
368
369 ret = hdmi_update_eld(eld, buf, size);
370
371 kfree(buf);
372 return ret;
373}
374
375static void hdmi_show_short_audio_desc(struct cea_sad *a)
376{
377 char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
378 char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits =";
379
380 if (!a->format)
381 return;
382
383 snd_print_pcm_rates(a->rates, buf, sizeof(buf));
384
385 if (a->format == AUDIO_CODING_TYPE_LPCM)
386 snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2 - 8));
387 else if (a->max_bitrate)
388 snprintf(buf2, sizeof(buf2),
389 ", max bitrate = %d", a->max_bitrate);
390 else
391 buf2[0] = '\0';
392
393 printk(KERN_INFO "HDMI: supports coding type %s:"
394 " channels = %d, rates =%s%s\n",
395 cea_audio_coding_type_names[a->format],
396 a->channels,
397 buf,
398 buf2);
399}
400
401void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen)
402{
403 int i, j;
404
405 for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) {
406 if (spk_alloc & (1 << i))
407 j += snprintf(buf + j, buflen - j, " %s",
408 cea_speaker_allocation_names[i]);
409 }
410 buf[j] = '\0'; /* necessary when j == 0 */
411}
412
413void snd_hdmi_show_eld(struct hdmi_eld *e)
414{
415 int i;
416
417 printk(KERN_INFO "HDMI: detected monitor %s at connection type %s\n",
418 e->monitor_name,
419 eld_connection_type_names[e->conn_type]);
420
421 if (e->spk_alloc) {
422 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
423 snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
424 printk(KERN_INFO "HDMI: available speakers:%s\n", buf);
425 }
426
427 for (i = 0; i < e->sad_count; i++)
428 hdmi_show_short_audio_desc(e->sad + i);
429}
430
431#ifdef CONFIG_PROC_FS
432
433static void hdmi_print_sad_info(int i, struct cea_sad *a,
434 struct snd_info_buffer *buffer)
435{
436 char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
437
438 snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n",
439 i, a->format, cea_audio_coding_type_names[a->format]);
440 snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels);
441
442 snd_print_pcm_rates(a->rates, buf, sizeof(buf));
443 snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf);
444
445 if (a->format == AUDIO_CODING_TYPE_LPCM) {
446 snd_print_pcm_bits(a->sample_bits, buf, sizeof(buf));
447 snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n",
448 i, a->sample_bits, buf);
449 }
450
451 if (a->max_bitrate)
452 snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n",
453 i, a->max_bitrate);
454
455 if (a->profile)
456 snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile);
457}
458
459static void hdmi_print_eld_info(struct snd_info_entry *entry,
460 struct snd_info_buffer *buffer)
461{
462 struct hdmi_eld *e = entry->private_data;
463 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
464 int i;
465 static char *eld_versoin_names[32] = {
466 "reserved",
467 "reserved",
468 "CEA-861D or below",
469 [3 ... 30] = "reserved",
470 [31] = "partial"
471 };
472 static char *cea_edid_version_names[8] = {
473 "no CEA EDID Timing Extension block present",
474 "CEA-861",
475 "CEA-861-A",
476 "CEA-861-B, C or D",
477 [4 ... 7] = "reserved"
478 };
479
480 snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name);
481 snd_iprintf(buffer, "connection_type\t\t%s\n",
482 eld_connection_type_names[e->conn_type]);
483 snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver,
484 eld_versoin_names[e->eld_ver]);
485 snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver,
486 cea_edid_version_names[e->cea_edid_ver]);
487 snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id);
488 snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id);
489 snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id);
490 snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp);
491 snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai);
492 snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay);
493
494 snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf));
495 snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf);
496
497 snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count);
498
499 for (i = 0; i < e->sad_count; i++)
500 hdmi_print_sad_info(i, e->sad + i, buffer);
501}
502
503static void hdmi_write_eld_info(struct snd_info_entry *entry,
504 struct snd_info_buffer *buffer)
505{
506 struct hdmi_eld *e = entry->private_data;
507 char line[64];
508 char name[64];
509 char *sname;
510 long long val;
511 int n;
512
513 while (!snd_info_get_line(buffer, line, sizeof(line))) {
514 if (sscanf(line, "%s %llx", name, &val) != 2)
515 continue;
516 /*
517 * We don't allow modification to these fields:
518 * monitor_name manufacture_id product_id
519 * eld_version edid_version
520 */
521 if (!strcmp(name, "connection_type"))
522 e->conn_type = val;
523 else if (!strcmp(name, "port_id"))
524 e->port_id = val;
525 else if (!strcmp(name, "support_hdcp"))
526 e->support_hdcp = val;
527 else if (!strcmp(name, "support_ai"))
528 e->support_ai = val;
529 else if (!strcmp(name, "audio_sync_delay"))
530 e->aud_synch_delay = val;
531 else if (!strcmp(name, "speakers"))
532 e->spk_alloc = val;
533 else if (!strcmp(name, "sad_count"))
534 e->sad_count = val;
535 else if (!strncmp(name, "sad", 3)) {
536 sname = name + 4;
537 n = name[3] - '0';
538 if (name[4] >= '0' && name[4] <= '9') {
539 sname++;
540 n = 10 * n + name[4] - '0';
541 }
542 if (n < 0 || n > 31) /* double the CEA limit */
543 continue;
544 if (!strcmp(sname, "_coding_type"))
545 e->sad[n].format = val;
546 else if (!strcmp(sname, "_channels"))
547 e->sad[n].channels = val;
548 else if (!strcmp(sname, "_rates"))
549 e->sad[n].rates = val;
550 else if (!strcmp(sname, "_bits"))
551 e->sad[n].sample_bits = val;
552 else if (!strcmp(sname, "_max_bitrate"))
553 e->sad[n].max_bitrate = val;
554 else if (!strcmp(sname, "_profile"))
555 e->sad[n].profile = val;
556 if (n >= e->sad_count)
557 e->sad_count = n + 1;
558 }
559 }
560}
561
562
563int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld)
564{
565 char name[32];
566 struct snd_info_entry *entry;
567 int err;
568
569 snprintf(name, sizeof(name), "eld#%d", codec->addr);
570 err = snd_card_proc_new(codec->bus->card, name, &entry);
571 if (err < 0)
572 return err;
573
574 snd_info_set_text_ops(entry, eld, hdmi_print_eld_info);
575 entry->c.text.write = hdmi_write_eld_info;
576 entry->mode |= S_IWUSR;
577 eld->proc_entry = entry;
578
579 return 0;
580}
581
582void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld)
583{
584 if (!codec->bus->shutdown && eld->proc_entry) {
585 snd_device_free(codec->bus->card, eld->proc_entry);
586 eld->proc_entry = NULL;
587 }
588}
589
590#endif /* CONFIG_PROC_FS */
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 0ca30894f7c6..65745e96dc70 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -723,7 +723,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
723 if (is_loopback) 723 if (is_loopback)
724 add_input_loopback(codec, node->nid, HDA_INPUT, index); 724 add_input_loopback(codec, node->nid, HDA_INPUT, index);
725 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); 725 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
726 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 726 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
727 if (err < 0)
727 return err; 728 return err;
728 created = 1; 729 created = 1;
729 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && 730 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
@@ -732,7 +733,8 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
732 if (is_loopback) 733 if (is_loopback)
733 add_input_loopback(codec, node->nid, HDA_OUTPUT, 0); 734 add_input_loopback(codec, node->nid, HDA_OUTPUT, 0);
734 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); 735 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
735 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 736 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
737 if (err < 0)
736 return err; 738 return err;
737 created = 1; 739 created = 1;
738 } 740 }
@@ -745,14 +747,16 @@ static int create_mixer(struct hda_codec *codec, struct hda_gnode *node,
745 (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) { 747 (node->amp_in_caps & AC_AMPCAP_NUM_STEPS)) {
746 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT); 748 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, index, HDA_INPUT);
747 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index); 749 snd_printdd("[%s] NID=0x%x, DIR=IN, IDX=0x%x\n", name, node->nid, index);
748 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 750 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
751 if (err < 0)
749 return err; 752 return err;
750 created = 1; 753 created = 1;
751 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) && 754 } else if ((node->wid_caps & AC_WCAP_OUT_AMP) &&
752 (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) { 755 (node->amp_out_caps & AC_AMPCAP_NUM_STEPS)) {
753 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT); 756 knew = (struct snd_kcontrol_new)HDA_CODEC_VOLUME(name, node->nid, 0, HDA_OUTPUT);
754 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid); 757 snd_printdd("[%s] NID=0x%x, DIR=OUT\n", name, node->nid);
755 if ((err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&knew, codec))) < 0) 758 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
759 if (err < 0)
756 return err; 760 return err;
757 created = 1; 761 created = 1;
758 } 762 }
@@ -849,8 +853,8 @@ static int build_input_controls(struct hda_codec *codec)
849 } 853 }
850 854
851 /* create input MUX if multiple sources are available */ 855 /* create input MUX if multiple sources are available */
852 if ((err = snd_ctl_add(codec->bus->card, 856 err = snd_hda_ctl_add(codec, snd_ctl_new1(&cap_sel, codec));
853 snd_ctl_new1(&cap_sel, codec))) < 0) 857 if (err < 0)
854 return err; 858 return err;
855 859
856 /* no volume control? */ 860 /* no volume control? */
@@ -867,8 +871,8 @@ static int build_input_controls(struct hda_codec *codec)
867 HDA_CODEC_VOLUME(name, adc_node->nid, 871 HDA_CODEC_VOLUME(name, adc_node->nid,
868 spec->input_mux.items[i].index, 872 spec->input_mux.items[i].index,
869 HDA_INPUT); 873 HDA_INPUT);
870 if ((err = snd_ctl_add(codec->bus->card, 874 err = snd_hda_ctl_add(codec, snd_ctl_new1(&knew, codec));
871 snd_ctl_new1(&knew, codec))) < 0) 875 if (err < 0)
872 return err; 876 return err;
873 } 877 }
874 878
@@ -1097,3 +1101,4 @@ int snd_hda_parse_generic_codec(struct hda_codec *codec)
1097 snd_hda_generic_free(codec); 1101 snd_hda_generic_free(codec);
1098 return err; 1102 return err;
1099} 1103}
1104EXPORT_SYMBOL(snd_hda_parse_generic_codec);
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index 6e18a422d993..300ab407cf42 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -23,10 +23,12 @@
23#include <linux/pci.h> 23#include <linux/pci.h>
24#include <linux/compat.h> 24#include <linux/compat.h>
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/ctype.h>
26#include <sound/core.h> 27#include <sound/core.h>
27#include "hda_codec.h" 28#include "hda_codec.h"
28#include "hda_local.h" 29#include "hda_local.h"
29#include <sound/hda_hwdep.h> 30#include <sound/hda_hwdep.h>
31#include <sound/minors.h>
30 32
31/* 33/*
32 * write/read an out-of-bound verb 34 * write/read an out-of-bound verb
@@ -95,7 +97,26 @@ static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)
95 return 0; 97 return 0;
96} 98}
97 99
98int __devinit snd_hda_create_hwdep(struct hda_codec *codec) 100static void clear_hwdep_elements(struct hda_codec *codec)
101{
102 char **head;
103 int i;
104
105 /* clear init verbs */
106 snd_array_free(&codec->init_verbs);
107 /* clear hints */
108 head = codec->hints.list;
109 for (i = 0; i < codec->hints.used; i++, head++)
110 kfree(*head);
111 snd_array_free(&codec->hints);
112}
113
114static void hwdep_free(struct snd_hwdep *hwdep)
115{
116 clear_hwdep_elements(hwdep->private_data);
117}
118
119int /*__devinit*/ snd_hda_create_hwdep(struct hda_codec *codec)
99{ 120{
100 char hwname[16]; 121 char hwname[16];
101 struct snd_hwdep *hwdep; 122 struct snd_hwdep *hwdep;
@@ -109,6 +130,7 @@ int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
109 sprintf(hwdep->name, "HDA Codec %d", codec->addr); 130 sprintf(hwdep->name, "HDA Codec %d", codec->addr);
110 hwdep->iface = SNDRV_HWDEP_IFACE_HDA; 131 hwdep->iface = SNDRV_HWDEP_IFACE_HDA;
111 hwdep->private_data = codec; 132 hwdep->private_data = codec;
133 hwdep->private_free = hwdep_free;
112 hwdep->exclusive = 1; 134 hwdep->exclusive = 1;
113 135
114 hwdep->ops.open = hda_hwdep_open; 136 hwdep->ops.open = hda_hwdep_open;
@@ -117,5 +139,215 @@ int __devinit snd_hda_create_hwdep(struct hda_codec *codec)
117 hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat; 139 hwdep->ops.ioctl_compat = hda_hwdep_ioctl_compat;
118#endif 140#endif
119 141
142 snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32);
143 snd_array_init(&codec->hints, sizeof(char *), 32);
144
120 return 0; 145 return 0;
121} 146}
147
148#ifdef CONFIG_SND_HDA_RECONFIG
149
150/*
151 * sysfs interface
152 */
153
154static int clear_codec(struct hda_codec *codec)
155{
156 snd_hda_codec_reset(codec);
157 clear_hwdep_elements(codec);
158 return 0;
159}
160
161static int reconfig_codec(struct hda_codec *codec)
162{
163 int err;
164
165 snd_printk(KERN_INFO "hda-codec: reconfiguring\n");
166 snd_hda_codec_reset(codec);
167 err = snd_hda_codec_configure(codec);
168 if (err < 0)
169 return err;
170 /* rebuild PCMs */
171 err = snd_hda_codec_build_pcms(codec);
172 if (err < 0)
173 return err;
174 /* rebuild mixers */
175 err = snd_hda_codec_build_controls(codec);
176 if (err < 0)
177 return err;
178 return 0;
179}
180
181/*
182 * allocate a string at most len chars, and remove the trailing EOL
183 */
184static char *kstrndup_noeol(const char *src, size_t len)
185{
186 char *s = kstrndup(src, len, GFP_KERNEL);
187 char *p;
188 if (!s)
189 return NULL;
190 p = strchr(s, '\n');
191 if (p)
192 *p = 0;
193 return s;
194}
195
196#define CODEC_INFO_SHOW(type) \
197static ssize_t type##_show(struct device *dev, \
198 struct device_attribute *attr, \
199 char *buf) \
200{ \
201 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
202 struct hda_codec *codec = hwdep->private_data; \
203 return sprintf(buf, "0x%x\n", codec->type); \
204}
205
206#define CODEC_INFO_STR_SHOW(type) \
207static ssize_t type##_show(struct device *dev, \
208 struct device_attribute *attr, \
209 char *buf) \
210{ \
211 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
212 struct hda_codec *codec = hwdep->private_data; \
213 return sprintf(buf, "%s\n", \
214 codec->type ? codec->type : ""); \
215}
216
217CODEC_INFO_SHOW(vendor_id);
218CODEC_INFO_SHOW(subsystem_id);
219CODEC_INFO_SHOW(revision_id);
220CODEC_INFO_SHOW(afg);
221CODEC_INFO_SHOW(mfg);
222CODEC_INFO_STR_SHOW(name);
223CODEC_INFO_STR_SHOW(modelname);
224
225#define CODEC_INFO_STORE(type) \
226static ssize_t type##_store(struct device *dev, \
227 struct device_attribute *attr, \
228 const char *buf, size_t count) \
229{ \
230 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
231 struct hda_codec *codec = hwdep->private_data; \
232 char *after; \
233 codec->type = simple_strtoul(buf, &after, 0); \
234 return count; \
235}
236
237#define CODEC_INFO_STR_STORE(type) \
238static ssize_t type##_store(struct device *dev, \
239 struct device_attribute *attr, \
240 const char *buf, size_t count) \
241{ \
242 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
243 struct hda_codec *codec = hwdep->private_data; \
244 char *s = kstrndup_noeol(buf, 64); \
245 if (!s) \
246 return -ENOMEM; \
247 kfree(codec->type); \
248 codec->type = s; \
249 return count; \
250}
251
252CODEC_INFO_STORE(vendor_id);
253CODEC_INFO_STORE(subsystem_id);
254CODEC_INFO_STORE(revision_id);
255CODEC_INFO_STR_STORE(name);
256CODEC_INFO_STR_STORE(modelname);
257
258#define CODEC_ACTION_STORE(type) \
259static ssize_t type##_store(struct device *dev, \
260 struct device_attribute *attr, \
261 const char *buf, size_t count) \
262{ \
263 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
264 struct hda_codec *codec = hwdep->private_data; \
265 int err = 0; \
266 if (*buf) \
267 err = type##_codec(codec); \
268 return err < 0 ? err : count; \
269}
270
271CODEC_ACTION_STORE(reconfig);
272CODEC_ACTION_STORE(clear);
273
274static ssize_t init_verbs_store(struct device *dev,
275 struct device_attribute *attr,
276 const char *buf, size_t count)
277{
278 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
279 struct hda_codec *codec = hwdep->private_data;
280 char *p;
281 struct hda_verb verb, *v;
282
283 verb.nid = simple_strtoul(buf, &p, 0);
284 verb.verb = simple_strtoul(p, &p, 0);
285 verb.param = simple_strtoul(p, &p, 0);
286 if (!verb.nid || !verb.verb || !verb.param)
287 return -EINVAL;
288 v = snd_array_new(&codec->init_verbs);
289 if (!v)
290 return -ENOMEM;
291 *v = verb;
292 return count;
293}
294
295static ssize_t hints_store(struct device *dev,
296 struct device_attribute *attr,
297 const char *buf, size_t count)
298{
299 struct snd_hwdep *hwdep = dev_get_drvdata(dev);
300 struct hda_codec *codec = hwdep->private_data;
301 char *p;
302 char **hint;
303
304 if (!*buf || isspace(*buf) || *buf == '#' || *buf == '\n')
305 return count;
306 p = kstrndup_noeol(buf, 1024);
307 if (!p)
308 return -ENOMEM;
309 hint = snd_array_new(&codec->hints);
310 if (!hint) {
311 kfree(p);
312 return -ENOMEM;
313 }
314 *hint = p;
315 return count;
316}
317
318#define CODEC_ATTR_RW(type) \
319 __ATTR(type, 0644, type##_show, type##_store)
320#define CODEC_ATTR_RO(type) \
321 __ATTR_RO(type)
322#define CODEC_ATTR_WO(type) \
323 __ATTR(type, 0200, NULL, type##_store)
324
325static struct device_attribute codec_attrs[] = {
326 CODEC_ATTR_RW(vendor_id),
327 CODEC_ATTR_RW(subsystem_id),
328 CODEC_ATTR_RW(revision_id),
329 CODEC_ATTR_RO(afg),
330 CODEC_ATTR_RO(mfg),
331 CODEC_ATTR_RW(name),
332 CODEC_ATTR_RW(modelname),
333 CODEC_ATTR_WO(init_verbs),
334 CODEC_ATTR_WO(hints),
335 CODEC_ATTR_WO(reconfig),
336 CODEC_ATTR_WO(clear),
337};
338
339/*
340 * create sysfs files on hwdep directory
341 */
342int snd_hda_hwdep_add_sysfs(struct hda_codec *codec)
343{
344 struct snd_hwdep *hwdep = codec->hwdep;
345 int i;
346
347 for (i = 0; i < ARRAY_SIZE(codec_attrs); i++)
348 snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card,
349 hwdep->device, &codec_attrs[i]);
350 return 0;
351}
352
353#endif /* CONFIG_SND_HDA_RECONFIG */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 35722ec920cb..f04de115ee11 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -58,6 +58,7 @@ static char *model[SNDRV_CARDS];
58static int position_fix[SNDRV_CARDS]; 58static int position_fix[SNDRV_CARDS];
59static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; 59static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
60static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; 60static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
61static int probe_only[SNDRV_CARDS];
61static int single_cmd; 62static int single_cmd;
62static int enable_msi; 63static int enable_msi;
63 64
@@ -76,6 +77,8 @@ module_param_array(bdl_pos_adj, int, NULL, 0644);
76MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 77MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
77module_param_array(probe_mask, int, NULL, 0444); 78module_param_array(probe_mask, int, NULL, 0444);
78MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); 79MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
80module_param_array(probe_only, bool, NULL, 0444);
81MODULE_PARM_DESC(probe_only, "Only probing and no codec initialization.");
79module_param(single_cmd, bool, 0444); 82module_param(single_cmd, bool, 0444);
80MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " 83MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
81 "(for debugging only)."); 84 "(for debugging only).");
@@ -83,7 +86,10 @@ module_param(enable_msi, int, 0444);
83MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); 86MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
84 87
85#ifdef CONFIG_SND_HDA_POWER_SAVE 88#ifdef CONFIG_SND_HDA_POWER_SAVE
86/* power_save option is defined in hda_codec.c */ 89static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;
90module_param(power_save, int, 0644);
91MODULE_PARM_DESC(power_save, "Automatic power-saving timeout "
92 "(in second, 0 = disable).");
87 93
88/* reset the HD-audio controller in power save mode. 94/* reset the HD-audio controller in power save mode.
89 * this may give more power-saving, but will take longer time to 95 * this may give more power-saving, but will take longer time to
@@ -292,6 +298,8 @@ enum {
292/* Define VIA HD Audio Device ID*/ 298/* Define VIA HD Audio Device ID*/
293#define VIA_HDAC_DEVICE_ID 0x3288 299#define VIA_HDAC_DEVICE_ID 0x3288
294 300
301/* HD Audio class code */
302#define PCI_CLASS_MULTIMEDIA_HD_AUDIO 0x0403
295 303
296/* 304/*
297 */ 305 */
@@ -392,6 +400,7 @@ struct azx {
392 unsigned int msi :1; 400 unsigned int msi :1;
393 unsigned int irq_pending_warned :1; 401 unsigned int irq_pending_warned :1;
394 unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */ 402 unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */
403 unsigned int probing :1; /* codec probing phase */
395 404
396 /* for debugging */ 405 /* for debugging */
397 unsigned int last_cmd; /* last issued command (to sync) */ 406 unsigned int last_cmd; /* last issued command (to sync) */
@@ -414,6 +423,7 @@ enum {
414 AZX_DRIVER_ULI, 423 AZX_DRIVER_ULI,
415 AZX_DRIVER_NVIDIA, 424 AZX_DRIVER_NVIDIA,
416 AZX_DRIVER_TERA, 425 AZX_DRIVER_TERA,
426 AZX_DRIVER_GENERIC,
417 AZX_NUM_DRIVERS, /* keep this as last entry */ 427 AZX_NUM_DRIVERS, /* keep this as last entry */
418}; 428};
419 429
@@ -427,6 +437,7 @@ static char *driver_short_names[] __devinitdata = {
427 [AZX_DRIVER_ULI] = "HDA ULI M5461", 437 [AZX_DRIVER_ULI] = "HDA ULI M5461",
428 [AZX_DRIVER_NVIDIA] = "HDA NVidia", 438 [AZX_DRIVER_NVIDIA] = "HDA NVidia",
429 [AZX_DRIVER_TERA] = "HDA Teradici", 439 [AZX_DRIVER_TERA] = "HDA Teradici",
440 [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
430}; 441};
431 442
432/* 443/*
@@ -527,9 +538,9 @@ static void azx_free_cmd_io(struct azx *chip)
527} 538}
528 539
529/* send a command */ 540/* send a command */
530static int azx_corb_send_cmd(struct hda_codec *codec, u32 val) 541static int azx_corb_send_cmd(struct hda_bus *bus, u32 val)
531{ 542{
532 struct azx *chip = codec->bus->private_data; 543 struct azx *chip = bus->private_data;
533 unsigned int wp; 544 unsigned int wp;
534 545
535 /* add command to corb */ 546 /* add command to corb */
@@ -577,9 +588,9 @@ static void azx_update_rirb(struct azx *chip)
577} 588}
578 589
579/* receive a response */ 590/* receive a response */
580static unsigned int azx_rirb_get_response(struct hda_codec *codec) 591static unsigned int azx_rirb_get_response(struct hda_bus *bus)
581{ 592{
582 struct azx *chip = codec->bus->private_data; 593 struct azx *chip = bus->private_data;
583 unsigned long timeout; 594 unsigned long timeout;
584 595
585 again: 596 again:
@@ -596,7 +607,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
596 } 607 }
597 if (time_after(jiffies, timeout)) 608 if (time_after(jiffies, timeout))
598 break; 609 break;
599 if (codec->bus->needs_damn_long_delay) 610 if (bus->needs_damn_long_delay)
600 msleep(2); /* temporary workaround */ 611 msleep(2); /* temporary workaround */
601 else { 612 else {
602 udelay(10); 613 udelay(10);
@@ -624,6 +635,14 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
624 goto again; 635 goto again;
625 } 636 }
626 637
638 if (chip->probing) {
639 /* If this critical timeout happens during the codec probing
640 * phase, this is likely an access to a non-existing codec
641 * slot. Better to return an error and reset the system.
642 */
643 return -1;
644 }
645
627 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " 646 snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, "
628 "switching to single_cmd mode: last cmd=0x%08x\n", 647 "switching to single_cmd mode: last cmd=0x%08x\n",
629 chip->last_cmd); 648 chip->last_cmd);
@@ -646,9 +665,9 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec)
646 */ 665 */
647 666
648/* send a command */ 667/* send a command */
649static int azx_single_send_cmd(struct hda_codec *codec, u32 val) 668static int azx_single_send_cmd(struct hda_bus *bus, u32 val)
650{ 669{
651 struct azx *chip = codec->bus->private_data; 670 struct azx *chip = bus->private_data;
652 int timeout = 50; 671 int timeout = 50;
653 672
654 while (timeout--) { 673 while (timeout--) {
@@ -671,9 +690,9 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val)
671} 690}
672 691
673/* receive a response */ 692/* receive a response */
674static unsigned int azx_single_get_response(struct hda_codec *codec) 693static unsigned int azx_single_get_response(struct hda_bus *bus)
675{ 694{
676 struct azx *chip = codec->bus->private_data; 695 struct azx *chip = bus->private_data;
677 int timeout = 50; 696 int timeout = 50;
678 697
679 while (timeout--) { 698 while (timeout--) {
@@ -696,38 +715,29 @@ static unsigned int azx_single_get_response(struct hda_codec *codec)
696 */ 715 */
697 716
698/* send a command */ 717/* send a command */
699static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, 718static int azx_send_cmd(struct hda_bus *bus, unsigned int val)
700 int direct, unsigned int verb,
701 unsigned int para)
702{ 719{
703 struct azx *chip = codec->bus->private_data; 720 struct azx *chip = bus->private_data;
704 u32 val;
705
706 val = (u32)(codec->addr & 0x0f) << 28;
707 val |= (u32)direct << 27;
708 val |= (u32)nid << 20;
709 val |= verb << 8;
710 val |= para;
711 chip->last_cmd = val;
712 721
722 chip->last_cmd = val;
713 if (chip->single_cmd) 723 if (chip->single_cmd)
714 return azx_single_send_cmd(codec, val); 724 return azx_single_send_cmd(bus, val);
715 else 725 else
716 return azx_corb_send_cmd(codec, val); 726 return azx_corb_send_cmd(bus, val);
717} 727}
718 728
719/* get a response */ 729/* get a response */
720static unsigned int azx_get_response(struct hda_codec *codec) 730static unsigned int azx_get_response(struct hda_bus *bus)
721{ 731{
722 struct azx *chip = codec->bus->private_data; 732 struct azx *chip = bus->private_data;
723 if (chip->single_cmd) 733 if (chip->single_cmd)
724 return azx_single_get_response(codec); 734 return azx_single_get_response(bus);
725 else 735 else
726 return azx_rirb_get_response(codec); 736 return azx_rirb_get_response(bus);
727} 737}
728 738
729#ifdef CONFIG_SND_HDA_POWER_SAVE 739#ifdef CONFIG_SND_HDA_POWER_SAVE
730static void azx_power_notify(struct hda_codec *codec); 740static void azx_power_notify(struct hda_bus *bus);
731#endif 741#endif
732 742
733/* reset codec link */ 743/* reset codec link */
@@ -1184,6 +1194,28 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1184 return 0; 1194 return 0;
1185} 1195}
1186 1196
1197/*
1198 * Probe the given codec address
1199 */
1200static int probe_codec(struct azx *chip, int addr)
1201{
1202 unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
1203 (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
1204 unsigned int res;
1205
1206 chip->probing = 1;
1207 azx_send_cmd(chip->bus, cmd);
1208 res = azx_get_response(chip->bus);
1209 chip->probing = 0;
1210 if (res == -1)
1211 return -EIO;
1212 snd_printdd("hda_intel: codec #%d probed OK\n", addr);
1213 return 0;
1214}
1215
1216static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1217 struct hda_pcm *cpcm);
1218static void azx_stop_chip(struct azx *chip);
1187 1219
1188/* 1220/*
1189 * Codec initialization 1221 * Codec initialization
@@ -1194,21 +1226,13 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1194 [AZX_DRIVER_TERA] = 1, 1226 [AZX_DRIVER_TERA] = 1,
1195}; 1227};
1196 1228
1197/* number of slots to probe as default
1198 * this can be different from azx_max_codecs[] -- e.g. some boards
1199 * report wrongly the non-existing 4th slot availability
1200 */
1201static unsigned int azx_default_codecs[AZX_NUM_DRIVERS] __devinitdata = {
1202 [AZX_DRIVER_ICH] = 3,
1203 [AZX_DRIVER_ATI] = 3,
1204};
1205
1206static int __devinit azx_codec_create(struct azx *chip, const char *model, 1229static int __devinit azx_codec_create(struct azx *chip, const char *model,
1207 unsigned int codec_probe_mask) 1230 unsigned int codec_probe_mask,
1231 int no_init)
1208{ 1232{
1209 struct hda_bus_template bus_temp; 1233 struct hda_bus_template bus_temp;
1210 int c, codecs, audio_codecs, err; 1234 int c, codecs, err;
1211 int def_slots, max_slots; 1235 int max_slots;
1212 1236
1213 memset(&bus_temp, 0, sizeof(bus_temp)); 1237 memset(&bus_temp, 0, sizeof(bus_temp));
1214 bus_temp.private_data = chip; 1238 bus_temp.private_data = chip;
@@ -1216,7 +1240,9 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1216 bus_temp.pci = chip->pci; 1240 bus_temp.pci = chip->pci;
1217 bus_temp.ops.command = azx_send_cmd; 1241 bus_temp.ops.command = azx_send_cmd;
1218 bus_temp.ops.get_response = azx_get_response; 1242 bus_temp.ops.get_response = azx_get_response;
1243 bus_temp.ops.attach_pcm = azx_attach_pcm_stream;
1219#ifdef CONFIG_SND_HDA_POWER_SAVE 1244#ifdef CONFIG_SND_HDA_POWER_SAVE
1245 bus_temp.power_save = &power_save;
1220 bus_temp.ops.pm_notify = azx_power_notify; 1246 bus_temp.ops.pm_notify = azx_power_notify;
1221#endif 1247#endif
1222 1248
@@ -1227,33 +1253,43 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model,
1227 if (chip->driver_type == AZX_DRIVER_NVIDIA) 1253 if (chip->driver_type == AZX_DRIVER_NVIDIA)
1228 chip->bus->needs_damn_long_delay = 1; 1254 chip->bus->needs_damn_long_delay = 1;
1229 1255
1230 codecs = audio_codecs = 0; 1256 codecs = 0;
1231 max_slots = azx_max_codecs[chip->driver_type]; 1257 max_slots = azx_max_codecs[chip->driver_type];
1232 if (!max_slots) 1258 if (!max_slots)
1233 max_slots = AZX_MAX_CODECS; 1259 max_slots = AZX_MAX_CODECS;
1234 def_slots = azx_default_codecs[chip->driver_type]; 1260
1235 if (!def_slots) 1261 /* First try to probe all given codec slots */
1236 def_slots = max_slots; 1262 for (c = 0; c < max_slots; c++) {
1237 for (c = 0; c < def_slots; c++) { 1263 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
1264 if (probe_codec(chip, c) < 0) {
1265 /* Some BIOSen give you wrong codec addresses
1266 * that don't exist
1267 */
1268 snd_printk(KERN_WARNING
1269 "hda_intel: Codec #%d probe error; "
1270 "disabling it...\n", c);
1271 chip->codec_mask &= ~(1 << c);
1272 /* More badly, accessing to a non-existing
1273 * codec often screws up the controller chip,
1274 * and distrubs the further communications.
1275 * Thus if an error occurs during probing,
1276 * better to reset the controller chip to
1277 * get back to the sanity state.
1278 */
1279 azx_stop_chip(chip);
1280 azx_init_chip(chip);
1281 }
1282 }
1283 }
1284
1285 /* Then create codec instances */
1286 for (c = 0; c < max_slots; c++) {
1238 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { 1287 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
1239 struct hda_codec *codec; 1288 struct hda_codec *codec;
1240 err = snd_hda_codec_new(chip->bus, c, &codec); 1289 err = snd_hda_codec_new(chip->bus, c, !no_init, &codec);
1241 if (err < 0) 1290 if (err < 0)
1242 continue; 1291 continue;
1243 codecs++; 1292 codecs++;
1244 if (codec->afg)
1245 audio_codecs++;
1246 }
1247 }
1248 if (!audio_codecs) {
1249 /* probe additional slots if no codec is found */
1250 for (; c < max_slots; c++) {
1251 if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
1252 err = snd_hda_codec_new(chip->bus, c, NULL);
1253 if (err < 0)
1254 continue;
1255 codecs++;
1256 }
1257 } 1293 }
1258 } 1294 }
1259 if (!codecs) { 1295 if (!codecs) {
@@ -1722,111 +1758,59 @@ static struct snd_pcm_ops azx_pcm_ops = {
1722 1758
1723static void azx_pcm_free(struct snd_pcm *pcm) 1759static void azx_pcm_free(struct snd_pcm *pcm)
1724{ 1760{
1725 kfree(pcm->private_data); 1761 struct azx_pcm *apcm = pcm->private_data;
1762 if (apcm) {
1763 apcm->chip->pcm[pcm->device] = NULL;
1764 kfree(apcm);
1765 }
1726} 1766}
1727 1767
1728static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, 1768static int
1729 struct hda_pcm *cpcm) 1769azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
1770 struct hda_pcm *cpcm)
1730{ 1771{
1731 int err; 1772 struct azx *chip = bus->private_data;
1732 struct snd_pcm *pcm; 1773 struct snd_pcm *pcm;
1733 struct azx_pcm *apcm; 1774 struct azx_pcm *apcm;
1775 int pcm_dev = cpcm->device;
1776 int s, err;
1734 1777
1735 /* if no substreams are defined for both playback and capture, 1778 if (pcm_dev >= AZX_MAX_PCMS) {
1736 * it's just a placeholder. ignore it. 1779 snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n",
1737 */ 1780 pcm_dev);
1738 if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
1739 return 0;
1740
1741 if (snd_BUG_ON(!cpcm->name))
1742 return -EINVAL; 1781 return -EINVAL;
1743 1782 }
1744 err = snd_pcm_new(chip->card, cpcm->name, cpcm->device, 1783 if (chip->pcm[pcm_dev]) {
1745 cpcm->stream[0].substreams, 1784 snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev);
1746 cpcm->stream[1].substreams, 1785 return -EBUSY;
1786 }
1787 err = snd_pcm_new(chip->card, cpcm->name, pcm_dev,
1788 cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams,
1789 cpcm->stream[SNDRV_PCM_STREAM_CAPTURE].substreams,
1747 &pcm); 1790 &pcm);
1748 if (err < 0) 1791 if (err < 0)
1749 return err; 1792 return err;
1750 strcpy(pcm->name, cpcm->name); 1793 strcpy(pcm->name, cpcm->name);
1751 apcm = kmalloc(sizeof(*apcm), GFP_KERNEL); 1794 apcm = kzalloc(sizeof(*apcm), GFP_KERNEL);
1752 if (apcm == NULL) 1795 if (apcm == NULL)
1753 return -ENOMEM; 1796 return -ENOMEM;
1754 apcm->chip = chip; 1797 apcm->chip = chip;
1755 apcm->codec = codec; 1798 apcm->codec = codec;
1756 apcm->hinfo[0] = &cpcm->stream[0];
1757 apcm->hinfo[1] = &cpcm->stream[1];
1758 pcm->private_data = apcm; 1799 pcm->private_data = apcm;
1759 pcm->private_free = azx_pcm_free; 1800 pcm->private_free = azx_pcm_free;
1760 if (cpcm->stream[0].substreams) 1801 if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM)
1761 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &azx_pcm_ops); 1802 pcm->dev_class = SNDRV_PCM_CLASS_MODEM;
1762 if (cpcm->stream[1].substreams) 1803 chip->pcm[pcm_dev] = pcm;
1763 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops); 1804 cpcm->pcm = pcm;
1805 for (s = 0; s < 2; s++) {
1806 apcm->hinfo[s] = &cpcm->stream[s];
1807 if (cpcm->stream[s].substreams)
1808 snd_pcm_set_ops(pcm, s, &azx_pcm_ops);
1809 }
1810 /* buffer pre-allocation */
1764 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, 1811 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
1765 snd_dma_pci_data(chip->pci), 1812 snd_dma_pci_data(chip->pci),
1766 1024 * 64, 32 * 1024 * 1024); 1813 1024 * 64, 32 * 1024 * 1024);
1767 chip->pcm[cpcm->device] = pcm;
1768 return 0;
1769}
1770
1771static int __devinit azx_pcm_create(struct azx *chip)
1772{
1773 static const char *dev_name[HDA_PCM_NTYPES] = {
1774 "Audio", "SPDIF", "HDMI", "Modem"
1775 };
1776 /* starting device index for each PCM type */
1777 static int dev_idx[HDA_PCM_NTYPES] = {
1778 [HDA_PCM_TYPE_AUDIO] = 0,
1779 [HDA_PCM_TYPE_SPDIF] = 1,
1780 [HDA_PCM_TYPE_HDMI] = 3,
1781 [HDA_PCM_TYPE_MODEM] = 6
1782 };
1783 /* normal audio device indices; not linear to keep compatibility */
1784 static int audio_idx[4] = { 0, 2, 4, 5 };
1785 struct hda_codec *codec;
1786 int c, err;
1787 int num_devs[HDA_PCM_NTYPES];
1788
1789 err = snd_hda_build_pcms(chip->bus);
1790 if (err < 0)
1791 return err;
1792
1793 /* create audio PCMs */
1794 memset(num_devs, 0, sizeof(num_devs));
1795 list_for_each_entry(codec, &chip->bus->codec_list, list) {
1796 for (c = 0; c < codec->num_pcms; c++) {
1797 struct hda_pcm *cpcm = &codec->pcm_info[c];
1798 int type = cpcm->pcm_type;
1799 switch (type) {
1800 case HDA_PCM_TYPE_AUDIO:
1801 if (num_devs[type] >= ARRAY_SIZE(audio_idx)) {
1802 snd_printk(KERN_WARNING
1803 "Too many audio devices\n");
1804 continue;
1805 }
1806 cpcm->device = audio_idx[num_devs[type]];
1807 break;
1808 case HDA_PCM_TYPE_SPDIF:
1809 case HDA_PCM_TYPE_HDMI:
1810 case HDA_PCM_TYPE_MODEM:
1811 if (num_devs[type]) {
1812 snd_printk(KERN_WARNING
1813 "%s already defined\n",
1814 dev_name[type]);
1815 continue;
1816 }
1817 cpcm->device = dev_idx[type];
1818 break;
1819 default:
1820 snd_printk(KERN_WARNING
1821 "Invalid PCM type %d\n", type);
1822 continue;
1823 }
1824 num_devs[type]++;
1825 err = create_codec_pcm(chip, codec, cpcm);
1826 if (err < 0)
1827 return err;
1828 }
1829 }
1830 return 0; 1814 return 0;
1831} 1815}
1832 1816
@@ -1903,13 +1887,13 @@ static void azx_stop_chip(struct azx *chip)
1903 1887
1904#ifdef CONFIG_SND_HDA_POWER_SAVE 1888#ifdef CONFIG_SND_HDA_POWER_SAVE
1905/* power-up/down the controller */ 1889/* power-up/down the controller */
1906static void azx_power_notify(struct hda_codec *codec) 1890static void azx_power_notify(struct hda_bus *bus)
1907{ 1891{
1908 struct azx *chip = codec->bus->private_data; 1892 struct azx *chip = bus->private_data;
1909 struct hda_codec *c; 1893 struct hda_codec *c;
1910 int power_on = 0; 1894 int power_on = 0;
1911 1895
1912 list_for_each_entry(c, &codec->bus->codec_list, list) { 1896 list_for_each_entry(c, &bus->codec_list, list) {
1913 if (c->power_on) { 1897 if (c->power_on) {
1914 power_on = 1; 1898 power_on = 1;
1915 break; 1899 break;
@@ -1926,6 +1910,18 @@ static void azx_power_notify(struct hda_codec *codec)
1926/* 1910/*
1927 * power management 1911 * power management
1928 */ 1912 */
1913
1914static int snd_hda_codecs_inuse(struct hda_bus *bus)
1915{
1916 struct hda_codec *codec;
1917
1918 list_for_each_entry(codec, &bus->codec_list, list) {
1919 if (snd_hda_codec_needs_resume(codec))
1920 return 1;
1921 }
1922 return 0;
1923}
1924
1929static int azx_suspend(struct pci_dev *pci, pm_message_t state) 1925static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1930{ 1926{
1931 struct snd_card *card = pci_get_drvdata(pci); 1927 struct snd_card *card = pci_get_drvdata(pci);
@@ -1951,13 +1947,16 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
1951 return 0; 1947 return 0;
1952} 1948}
1953 1949
1950static int azx_resume_early(struct pci_dev *pci)
1951{
1952 return pci_restore_state(pci);
1953}
1954
1954static int azx_resume(struct pci_dev *pci) 1955static int azx_resume(struct pci_dev *pci)
1955{ 1956{
1956 struct snd_card *card = pci_get_drvdata(pci); 1957 struct snd_card *card = pci_get_drvdata(pci);
1957 struct azx *chip = card->private_data; 1958 struct azx *chip = card->private_data;
1958 1959
1959 pci_set_power_state(pci, PCI_D0);
1960 pci_restore_state(pci);
1961 if (pci_enable_device(pci) < 0) { 1960 if (pci_enable_device(pci) < 0) {
1962 printk(KERN_ERR "hda-intel: pci_enable_device failed, " 1961 printk(KERN_ERR "hda-intel: pci_enable_device failed, "
1963 "disabling device\n"); 1962 "disabling device\n");
@@ -2095,6 +2094,10 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = {
2095 SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01), 2094 SND_PCI_QUIRK(0x1014, 0x05b7, "Thinkpad Z60", 0x01),
2096 SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01), 2095 SND_PCI_QUIRK(0x17aa, 0x2010, "Thinkpad X/T/R60", 0x01),
2097 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01), 2096 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01),
2097 /* broken BIOS */
2098 SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01),
2099 /* including bogus ALC268 in slot#2 that conflicts with ALC888 */
2100 SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01),
2098 {} 2101 {}
2099}; 2102};
2100 2103
@@ -2229,6 +2232,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
2229 chip->playback_streams = ATIHDMI_NUM_PLAYBACK; 2232 chip->playback_streams = ATIHDMI_NUM_PLAYBACK;
2230 chip->capture_streams = ATIHDMI_NUM_CAPTURE; 2233 chip->capture_streams = ATIHDMI_NUM_CAPTURE;
2231 break; 2234 break;
2235 case AZX_DRIVER_GENERIC:
2232 default: 2236 default:
2233 chip->playback_streams = ICH6_NUM_PLAYBACK; 2237 chip->playback_streams = ICH6_NUM_PLAYBACK;
2234 chip->capture_streams = ICH6_NUM_CAPTURE; 2238 chip->capture_streams = ICH6_NUM_CAPTURE;
@@ -2338,40 +2342,31 @@ static int __devinit azx_probe(struct pci_dev *pci,
2338 } 2342 }
2339 2343
2340 err = azx_create(card, pci, dev, pci_id->driver_data, &chip); 2344 err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
2341 if (err < 0) { 2345 if (err < 0)
2342 snd_card_free(card); 2346 goto out_free;
2343 return err;
2344 }
2345 card->private_data = chip; 2347 card->private_data = chip;
2346 2348
2347 /* create codec instances */ 2349 /* create codec instances */
2348 err = azx_codec_create(chip, model[dev], probe_mask[dev]); 2350 err = azx_codec_create(chip, model[dev], probe_mask[dev],
2349 if (err < 0) { 2351 probe_only[dev]);
2350 snd_card_free(card); 2352 if (err < 0)
2351 return err; 2353 goto out_free;
2352 }
2353 2354
2354 /* create PCM streams */ 2355 /* create PCM streams */
2355 err = azx_pcm_create(chip); 2356 err = snd_hda_build_pcms(chip->bus);
2356 if (err < 0) { 2357 if (err < 0)
2357 snd_card_free(card); 2358 goto out_free;
2358 return err;
2359 }
2360 2359
2361 /* create mixer controls */ 2360 /* create mixer controls */
2362 err = azx_mixer_create(chip); 2361 err = azx_mixer_create(chip);
2363 if (err < 0) { 2362 if (err < 0)
2364 snd_card_free(card); 2363 goto out_free;
2365 return err;
2366 }
2367 2364
2368 snd_card_set_dev(card, &pci->dev); 2365 snd_card_set_dev(card, &pci->dev);
2369 2366
2370 err = snd_card_register(card); 2367 err = snd_card_register(card);
2371 if (err < 0) { 2368 if (err < 0)
2372 snd_card_free(card); 2369 goto out_free;
2373 return err;
2374 }
2375 2370
2376 pci_set_drvdata(pci, card); 2371 pci_set_drvdata(pci, card);
2377 chip->running = 1; 2372 chip->running = 1;
@@ -2380,6 +2375,9 @@ static int __devinit azx_probe(struct pci_dev *pci,
2380 2375
2381 dev++; 2376 dev++;
2382 return err; 2377 return err;
2378out_free:
2379 snd_card_free(card);
2380 return err;
2383} 2381}
2384 2382
2385static void __devexit azx_remove(struct pci_dev *pci) 2383static void __devexit azx_remove(struct pci_dev *pci)
@@ -2453,6 +2451,11 @@ static struct pci_device_id azx_ids[] = {
2453 { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA }, 2451 { PCI_DEVICE(0x10de, 0x0bd7), .driver_data = AZX_DRIVER_NVIDIA },
2454 /* Teradici */ 2452 /* Teradici */
2455 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, 2453 { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA },
2454 /* AMD Generic, PCI class code and Vendor ID for HD Audio */
2455 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
2456 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
2457 .class_mask = 0xffffff,
2458 .driver_data = AZX_DRIVER_GENERIC },
2456 { 0, } 2459 { 0, }
2457}; 2460};
2458MODULE_DEVICE_TABLE(pci, azx_ids); 2461MODULE_DEVICE_TABLE(pci, azx_ids);
@@ -2465,6 +2468,7 @@ static struct pci_driver driver = {
2465 .remove = __devexit_p(azx_remove), 2468 .remove = __devexit_p(azx_remove),
2466#ifdef CONFIG_PM 2469#ifdef CONFIG_PM
2467 .suspend = azx_suspend, 2470 .suspend = azx_suspend,
2471 .resume_early = azx_resume_early,
2468 .resume = azx_resume, 2472 .resume = azx_resume,
2469#endif 2473#endif
2470}; 2474};
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 7957fefda730..6f2fe0f9fdd8 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -96,6 +96,8 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
96 const char *name); 96 const char *name);
97int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 97int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
98 unsigned int *tlv, const char **slaves); 98 unsigned int *tlv, const char **slaves);
99void snd_hda_codec_reset(struct hda_codec *codec);
100int snd_hda_codec_configure(struct hda_codec *codec);
99 101
100/* amp value bits */ 102/* amp value bits */
101#define HDA_AMP_MUTE 0x80 103#define HDA_AMP_MUTE 0x80
@@ -282,6 +284,12 @@ int snd_hda_codec_proc_new(struct hda_codec *codec);
282static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } 284static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
283#endif 285#endif
284 286
287#define SND_PRINT_RATES_ADVISED_BUFSIZE 80
288void snd_print_pcm_rates(int pcm, char *buf, int buflen);
289
290#define SND_PRINT_BITS_ADVISED_BUFSIZE 16
291void snd_print_pcm_bits(int pcm, char *buf, int buflen);
292
285/* 293/*
286 * Misc 294 * Misc
287 */ 295 */
@@ -364,17 +372,17 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
364/* amp values */ 372/* amp values */
365#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) 373#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
366#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8)) 374#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8))
367#define AMP_OUT_MUTE 0xb080 375#define AMP_OUT_MUTE 0xb080
368#define AMP_OUT_UNMUTE 0xb000 376#define AMP_OUT_UNMUTE 0xb000
369#define AMP_OUT_ZERO 0xb000 377#define AMP_OUT_ZERO 0xb000
370/* pinctl values */ 378/* pinctl values */
371#define PIN_IN (AC_PINCTL_IN_EN) 379#define PIN_IN (AC_PINCTL_IN_EN)
372#define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ) 380#define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ)
373#define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50) 381#define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50)
374#define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD) 382#define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD)
375#define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80) 383#define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80)
376#define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100) 384#define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100)
377#define PIN_OUT (AC_PINCTL_OUT_EN) 385#define PIN_OUT (AC_PINCTL_OUT_EN)
378#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN) 386#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN)
379#define PIN_HP_AMP (AC_PINCTL_HP_EN) 387#define PIN_HP_AMP (AC_PINCTL_HP_EN)
380 388
@@ -393,10 +401,26 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction);
393int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 401int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
394 unsigned int caps); 402 unsigned int caps);
395 403
404int snd_hda_ctl_add(struct hda_codec *codec, struct snd_kcontrol *kctl);
405void snd_hda_ctls_clear(struct hda_codec *codec);
406
396/* 407/*
397 * hwdep interface 408 * hwdep interface
398 */ 409 */
410#ifdef CONFIG_SND_HDA_HWDEP
399int snd_hda_create_hwdep(struct hda_codec *codec); 411int snd_hda_create_hwdep(struct hda_codec *codec);
412#else
413static inline int snd_hda_create_hwdep(struct hda_codec *codec) { return 0; }
414#endif
415
416#ifdef CONFIG_SND_HDA_RECONFIG
417int snd_hda_hwdep_add_sysfs(struct hda_codec *codec);
418#else
419static inline int snd_hda_hwdep_add_sysfs(struct hda_codec *codec)
420{
421 return 0;
422}
423#endif
400 424
401/* 425/*
402 * power-management 426 * power-management
@@ -430,4 +454,66 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec,
430#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) 454#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1)
431#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) 455#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf)
432 456
457/*
458 * CEA Short Audio Descriptor data
459 */
460struct cea_sad {
461 int channels;
462 int format; /* (format == 0) indicates invalid SAD */
463 int rates;
464 int sample_bits; /* for LPCM */
465 int max_bitrate; /* for AC3...ATRAC */
466 int profile; /* for WMAPRO */
467};
468
469#define ELD_FIXED_BYTES 20
470#define ELD_MAX_MNL 16
471#define ELD_MAX_SAD 16
472
473/*
474 * ELD: EDID Like Data
475 */
476struct hdmi_eld {
477 int eld_size;
478 int baseline_len;
479 int eld_ver; /* (eld_ver == 0) indicates invalid ELD */
480 int cea_edid_ver;
481 char monitor_name[ELD_MAX_MNL + 1];
482 int manufacture_id;
483 int product_id;
484 u64 port_id;
485 int support_hdcp;
486 int support_ai;
487 int conn_type;
488 int aud_synch_delay;
489 int spk_alloc;
490 int sad_count;
491 struct cea_sad sad[ELD_MAX_SAD];
492#ifdef CONFIG_PROC_FS
493 struct snd_info_entry *proc_entry;
494#endif
495};
496
497int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid);
498int snd_hdmi_get_eld(struct hdmi_eld *, struct hda_codec *, hda_nid_t);
499void snd_hdmi_show_eld(struct hdmi_eld *eld);
500
501#ifdef CONFIG_PROC_FS
502int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld);
503void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld);
504#else
505static inline int snd_hda_eld_proc_new(struct hda_codec *codec,
506 struct hdmi_eld *eld)
507{
508 return 0;
509}
510static inline void snd_hda_eld_proc_free(struct hda_codec *codec,
511 struct hdmi_eld *eld)
512{
513}
514#endif
515
516#define SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE 80
517void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen);
518
433#endif /* __SOUND_HDA_LOCAL_H */ 519#endif /* __SOUND_HDA_LOCAL_H */
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
deleted file mode 100644
index dfbcfa88da44..000000000000
--- a/sound/pci/hda/hda_patch.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * HDA Patches - included by hda_codec.c
3 */
4
5/* Realtek codecs */
6extern struct hda_codec_preset snd_hda_preset_realtek[];
7/* C-Media codecs */
8extern struct hda_codec_preset snd_hda_preset_cmedia[];
9/* Analog Devices codecs */
10extern struct hda_codec_preset snd_hda_preset_analog[];
11/* SigmaTel codecs */
12extern struct hda_codec_preset snd_hda_preset_sigmatel[];
13/* SiLabs 3054/3055 modem codecs */
14extern struct hda_codec_preset snd_hda_preset_si3054[];
15/* ATI HDMI codecs */
16extern struct hda_codec_preset snd_hda_preset_atihdmi[];
17/* Conexant audio codec */
18extern struct hda_codec_preset snd_hda_preset_conexant[];
19/* VIA codecs */
20extern struct hda_codec_preset snd_hda_preset_via[];
21/* NVIDIA HDMI codecs */
22extern struct hda_codec_preset snd_hda_preset_nvhdmi[];
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index c39af986bff1..7ca66d654148 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -91,31 +91,21 @@ static void print_amp_vals(struct snd_info_buffer *buffer,
91 91
92static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm) 92static void print_pcm_rates(struct snd_info_buffer *buffer, unsigned int pcm)
93{ 93{
94 static unsigned int rates[] = { 94 char buf[SND_PRINT_RATES_ADVISED_BUFSIZE];
95 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
96 96000, 176400, 192000, 384000
97 };
98 int i;
99 95
100 pcm &= AC_SUPPCM_RATES; 96 pcm &= AC_SUPPCM_RATES;
101 snd_iprintf(buffer, " rates [0x%x]:", pcm); 97 snd_iprintf(buffer, " rates [0x%x]:", pcm);
102 for (i = 0; i < ARRAY_SIZE(rates); i++) 98 snd_print_pcm_rates(pcm, buf, sizeof(buf));
103 if (pcm & (1 << i)) 99 snd_iprintf(buffer, "%s\n", buf);
104 snd_iprintf(buffer, " %d", rates[i]);
105 snd_iprintf(buffer, "\n");
106} 100}
107 101
108static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm) 102static void print_pcm_bits(struct snd_info_buffer *buffer, unsigned int pcm)
109{ 103{
110 static unsigned int bits[] = { 8, 16, 20, 24, 32 }; 104 char buf[SND_PRINT_BITS_ADVISED_BUFSIZE];
111 int i;
112 105
113 pcm = (pcm >> 16) & 0xff; 106 snd_iprintf(buffer, " bits [0x%x]:", (pcm >> 16) & 0xff);
114 snd_iprintf(buffer, " bits [0x%x]:", pcm); 107 snd_print_pcm_bits(pcm, buf, sizeof(buf));
115 for (i = 0; i < ARRAY_SIZE(bits); i++) 108 snd_iprintf(buffer, "%s\n", buf);
116 if (pcm & (1 << i))
117 snd_iprintf(buffer, " %d", bits[i]);
118 snd_iprintf(buffer, "\n");
119} 109}
120 110
121static void print_pcm_formats(struct snd_info_buffer *buffer, 111static void print_pcm_formats(struct snd_info_buffer *buffer,
@@ -145,32 +135,6 @@ static void print_pcm_caps(struct snd_info_buffer *buffer,
145 print_pcm_formats(buffer, stream); 135 print_pcm_formats(buffer, stream);
146} 136}
147 137
148static const char *get_jack_location(u32 cfg)
149{
150 static char *bases[7] = {
151 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
152 };
153 static unsigned char specials_idx[] = {
154 0x07, 0x08,
155 0x17, 0x18, 0x19,
156 0x37, 0x38
157 };
158 static char *specials[] = {
159 "Rear Panel", "Drive Bar",
160 "Riser", "HDMI", "ATAPI",
161 "Mobile-In", "Mobile-Out"
162 };
163 int i;
164 cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
165 if ((cfg & 0x0f) < 7)
166 return bases[cfg & 0x0f];
167 for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
168 if (cfg == specials_idx[i])
169 return specials[i];
170 }
171 return "UNKNOWN";
172}
173
174static const char *get_jack_connection(u32 cfg) 138static const char *get_jack_connection(u32 cfg)
175{ 139{
176 static char *names[16] = { 140 static char *names[16] = {
@@ -206,13 +170,6 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
206 int *supports_vref) 170 int *supports_vref)
207{ 171{
208 static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" }; 172 static char *jack_conns[4] = { "Jack", "N/A", "Fixed", "Both" };
209 static char *jack_types[16] = {
210 "Line Out", "Speaker", "HP Out", "CD",
211 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
212 "Line In", "Aux", "Mic", "Telephony",
213 "SPDIF In", "Digitial In", "Reserved", "Other"
214 };
215 static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
216 unsigned int caps, val; 173 unsigned int caps, val;
217 174
218 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 175 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
@@ -274,9 +231,9 @@ static void print_pin_caps(struct snd_info_buffer *buffer,
274 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); 231 caps = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
275 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps, 232 snd_iprintf(buffer, " Pin Default 0x%08x: [%s] %s at %s %s\n", caps,
276 jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT], 233 jack_conns[(caps & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT],
277 jack_types[(caps & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT], 234 snd_hda_get_jack_type(caps),
278 jack_locations[(caps >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3], 235 snd_hda_get_jack_connectivity(caps),
279 get_jack_location(caps)); 236 snd_hda_get_jack_location(caps));
280 snd_iprintf(buffer, " Conn = %s, Color = %s\n", 237 snd_iprintf(buffer, " Conn = %s, Color = %s\n",
281 get_jack_connection(caps), 238 get_jack_connection(caps),
282 get_jack_color(caps)); 239 get_jack_color(caps));
@@ -457,17 +414,6 @@ static void print_conn_list(struct snd_info_buffer *buffer,
457 } 414 }
458} 415}
459 416
460static void print_realtek_coef(struct snd_info_buffer *buffer,
461 struct hda_codec *codec, hda_nid_t nid)
462{
463 int coeff = snd_hda_codec_read(codec, nid, 0,
464 AC_VERB_GET_PROC_COEF, 0);
465 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
466 coeff = snd_hda_codec_read(codec, nid, 0,
467 AC_VERB_GET_COEF_INDEX, 0);
468 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
469}
470
471static void print_gpio(struct snd_info_buffer *buffer, 417static void print_gpio(struct snd_info_buffer *buffer,
472 struct hda_codec *codec, hda_nid_t nid) 418 struct hda_codec *codec, hda_nid_t nid)
473{ 419{
@@ -500,12 +446,13 @@ static void print_gpio(struct snd_info_buffer *buffer,
500 for (i = 0; i < max; ++i) 446 for (i = 0; i < max; ++i)
501 snd_iprintf(buffer, 447 snd_iprintf(buffer,
502 " IO[%d]: enable=%d, dir=%d, wake=%d, " 448 " IO[%d]: enable=%d, dir=%d, wake=%d, "
503 "sticky=%d, data=%d\n", i, 449 "sticky=%d, data=%d, unsol=%d\n", i,
504 (enable & (1<<i)) ? 1 : 0, 450 (enable & (1<<i)) ? 1 : 0,
505 (direction & (1<<i)) ? 1 : 0, 451 (direction & (1<<i)) ? 1 : 0,
506 (wake & (1<<i)) ? 1 : 0, 452 (wake & (1<<i)) ? 1 : 0,
507 (sticky & (1<<i)) ? 1 : 0, 453 (sticky & (1<<i)) ? 1 : 0,
508 (data & (1<<i)) ? 1 : 0); 454 (data & (1<<i)) ? 1 : 0,
455 (unsol & (1<<i)) ? 1 : 0);
509 /* FIXME: add GPO and GPI pin information */ 456 /* FIXME: add GPO and GPI pin information */
510} 457}
511 458
@@ -513,12 +460,11 @@ static void print_codec_info(struct snd_info_entry *entry,
513 struct snd_info_buffer *buffer) 460 struct snd_info_buffer *buffer)
514{ 461{
515 struct hda_codec *codec = entry->private_data; 462 struct hda_codec *codec = entry->private_data;
516 char buf[32];
517 hda_nid_t nid; 463 hda_nid_t nid;
518 int i, nodes; 464 int i, nodes;
519 465
520 snd_hda_get_codec_name(codec, buf, sizeof(buf)); 466 snd_iprintf(buffer, "Codec: %s\n",
521 snd_iprintf(buffer, "Codec: %s\n", buf); 467 codec->name ? codec->name : "Not Set");
522 snd_iprintf(buffer, "Address: %d\n", codec->addr); 468 snd_iprintf(buffer, "Address: %d\n", codec->addr);
523 snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id); 469 snd_iprintf(buffer, "Vendor Id: 0x%x\n", codec->vendor_id);
524 snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id); 470 snd_iprintf(buffer, "Subsystem Id: 0x%x\n", codec->subsystem_id);
@@ -547,6 +493,8 @@ static void print_codec_info(struct snd_info_entry *entry,
547 } 493 }
548 494
549 print_gpio(buffer, codec, codec->afg); 495 print_gpio(buffer, codec, codec->afg);
496 if (codec->proc_widget_hook)
497 codec->proc_widget_hook(buffer, codec, codec->afg);
550 498
551 for (i = 0; i < nodes; i++, nid++) { 499 for (i = 0; i < nodes; i++, nid++) {
552 unsigned int wid_caps = 500 unsigned int wid_caps =
@@ -649,9 +597,8 @@ static void print_codec_info(struct snd_info_entry *entry,
649 if (wid_caps & AC_WCAP_PROC_WID) 597 if (wid_caps & AC_WCAP_PROC_WID)
650 print_proc_caps(buffer, codec, nid); 598 print_proc_caps(buffer, codec, nid);
651 599
652 /* NID 0x20 == Realtek Define Registers */ 600 if (codec->proc_widget_hook)
653 if (codec->vendor_id == 0x10ec && nid == 0x20) 601 codec->proc_widget_hook(buffer, codec, nid);
654 print_realtek_coef(buffer, codec, nid);
655 } 602 }
656 snd_hda_power_down(codec); 603 snd_hda_power_down(codec);
657} 604}
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 686c77491dea..26247cfe749d 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -27,7 +27,6 @@
27#include <sound/core.h> 27#include <sound/core.h>
28#include "hda_codec.h" 28#include "hda_codec.h"
29#include "hda_local.h" 29#include "hda_local.h"
30#include "hda_patch.h"
31 30
32struct ad198x_spec { 31struct ad198x_spec {
33 struct snd_kcontrol_new *mixers[5]; 32 struct snd_kcontrol_new *mixers[5];
@@ -67,8 +66,7 @@ struct ad198x_spec {
67 66
68 /* dynamic controls, init_verbs and input_mux */ 67 /* dynamic controls, init_verbs and input_mux */
69 struct auto_pin_cfg autocfg; 68 struct auto_pin_cfg autocfg;
70 unsigned int num_kctl_alloc, num_kctl_used; 69 struct snd_array kctls;
71 struct snd_kcontrol_new *kctl_alloc;
72 struct hda_input_mux private_imux; 70 struct hda_input_mux private_imux;
73 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 71 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
74 72
@@ -154,6 +152,8 @@ static const char *ad_slave_sws[] = {
154 NULL 152 NULL
155}; 153};
156 154
155static void ad198x_free_kctls(struct hda_codec *codec);
156
157static int ad198x_build_controls(struct hda_codec *codec) 157static int ad198x_build_controls(struct hda_codec *codec)
158{ 158{
159 struct ad198x_spec *spec = codec->spec; 159 struct ad198x_spec *spec = codec->spec;
@@ -202,6 +202,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
202 return err; 202 return err;
203 } 203 }
204 204
205 ad198x_free_kctls(codec); /* no longer needed */
205 return 0; 206 return 0;
206} 207}
207 208
@@ -375,16 +376,27 @@ static int ad198x_build_pcms(struct hda_codec *codec)
375 return 0; 376 return 0;
376} 377}
377 378
378static void ad198x_free(struct hda_codec *codec) 379static void ad198x_free_kctls(struct hda_codec *codec)
379{ 380{
380 struct ad198x_spec *spec = codec->spec; 381 struct ad198x_spec *spec = codec->spec;
381 unsigned int i;
382 382
383 if (spec->kctl_alloc) { 383 if (spec->kctls.list) {
384 for (i = 0; i < spec->num_kctl_used; i++) 384 struct snd_kcontrol_new *kctl = spec->kctls.list;
385 kfree(spec->kctl_alloc[i].name); 385 int i;
386 kfree(spec->kctl_alloc); 386 for (i = 0; i < spec->kctls.used; i++)
387 kfree(kctl[i].name);
387 } 388 }
389 snd_array_free(&spec->kctls);
390}
391
392static void ad198x_free(struct hda_codec *codec)
393{
394 struct ad198x_spec *spec = codec->spec;
395
396 if (!spec)
397 return;
398
399 ad198x_free_kctls(codec);
388 kfree(codec->spec); 400 kfree(codec->spec);
389} 401}
390 402
@@ -629,6 +641,36 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
629 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), 641 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
630 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 642 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
631 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 643 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
644 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
645 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
646 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
647 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
648 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
649 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
650 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
651 {
652 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
653 .name = "Capture Source",
654 .info = ad198x_mux_enum_info,
655 .get = ad198x_mux_enum_get,
656 .put = ad198x_mux_enum_put,
657 },
658 {
659 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
660 .name = "External Amplifier",
661 .info = ad198x_eapd_info,
662 .get = ad198x_eapd_get,
663 .put = ad198x_eapd_put,
664 .private_value = 0x1b | (1 << 8), /* port-D, inversed */
665 },
666 { } /* end */
667};
668
669static struct snd_kcontrol_new ad1986a_samsung_mixers[] = {
670 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
671 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
672 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
673 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
632 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
633 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 675 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
634 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 676 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT),
@@ -917,6 +959,7 @@ enum {
917 AD1986A_LAPTOP_EAPD, 959 AD1986A_LAPTOP_EAPD,
918 AD1986A_LAPTOP_AUTOMUTE, 960 AD1986A_LAPTOP_AUTOMUTE,
919 AD1986A_ULTRA, 961 AD1986A_ULTRA,
962 AD1986A_SAMSUNG,
920 AD1986A_MODELS 963 AD1986A_MODELS
921}; 964};
922 965
@@ -927,6 +970,7 @@ static const char *ad1986a_models[AD1986A_MODELS] = {
927 [AD1986A_LAPTOP_EAPD] = "laptop-eapd", 970 [AD1986A_LAPTOP_EAPD] = "laptop-eapd",
928 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", 971 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
929 [AD1986A_ULTRA] = "ultra", 972 [AD1986A_ULTRA] = "ultra",
973 [AD1986A_SAMSUNG] = "samsung",
930}; 974};
931 975
932static struct snd_pci_quirk ad1986a_cfg_tbl[] = { 976static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
@@ -949,9 +993,9 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
949 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD), 993 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba", AD1986A_LAPTOP_EAPD),
950 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), 994 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
951 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), 995 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
952 SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_LAPTOP_EAPD), 996 SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_SAMSUNG),
953 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_LAPTOP_EAPD), 997 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_SAMSUNG),
954 SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_LAPTOP_EAPD), 998 SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_SAMSUNG),
955 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), 999 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
956 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), 1000 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
957 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP), 1001 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
@@ -1033,6 +1077,17 @@ static int patch_ad1986a(struct hda_codec *codec)
1033 break; 1077 break;
1034 case AD1986A_LAPTOP_EAPD: 1078 case AD1986A_LAPTOP_EAPD:
1035 spec->mixers[0] = ad1986a_laptop_eapd_mixers; 1079 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1080 spec->num_init_verbs = 2;
1081 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1082 spec->multiout.max_channels = 2;
1083 spec->multiout.num_dacs = 1;
1084 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1085 if (!is_jack_available(codec, 0x25))
1086 spec->multiout.dig_out_nid = 0;
1087 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1088 break;
1089 case AD1986A_SAMSUNG:
1090 spec->mixers[0] = ad1986a_samsung_mixers;
1036 spec->num_init_verbs = 3; 1091 spec->num_init_verbs = 3;
1037 spec->init_verbs[1] = ad1986a_eapd_init_verbs; 1092 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1038 spec->init_verbs[2] = ad1986a_automic_verbs; 1093 spec->init_verbs[2] = ad1986a_automic_verbs;
@@ -2452,9 +2507,6 @@ static struct hda_amp_list ad1988_loopbacks[] = {
2452 * Automatic parse of I/O pins from the BIOS configuration 2507 * Automatic parse of I/O pins from the BIOS configuration
2453 */ 2508 */
2454 2509
2455#define NUM_CONTROL_ALLOC 32
2456#define NUM_VERB_ALLOC 32
2457
2458enum { 2510enum {
2459 AD_CTL_WIDGET_VOL, 2511 AD_CTL_WIDGET_VOL,
2460 AD_CTL_WIDGET_MUTE, 2512 AD_CTL_WIDGET_MUTE,
@@ -2472,27 +2524,15 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name,
2472{ 2524{
2473 struct snd_kcontrol_new *knew; 2525 struct snd_kcontrol_new *knew;
2474 2526
2475 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 2527 snd_array_init(&spec->kctls, sizeof(*knew), 32);
2476 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 2528 knew = snd_array_new(&spec->kctls);
2477 2529 if (!knew)
2478 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ 2530 return -ENOMEM;
2479 if (! knew)
2480 return -ENOMEM;
2481 if (spec->kctl_alloc) {
2482 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2483 kfree(spec->kctl_alloc);
2484 }
2485 spec->kctl_alloc = knew;
2486 spec->num_kctl_alloc = num;
2487 }
2488
2489 knew = &spec->kctl_alloc[spec->num_kctl_used];
2490 *knew = ad1988_control_templates[type]; 2531 *knew = ad1988_control_templates[type];
2491 knew->name = kstrdup(name, GFP_KERNEL); 2532 knew->name = kstrdup(name, GFP_KERNEL);
2492 if (! knew->name) 2533 if (! knew->name)
2493 return -ENOMEM; 2534 return -ENOMEM;
2494 knew->private_value = val; 2535 knew->private_value = val;
2495 spec->num_kctl_used++;
2496 return 0; 2536 return 0;
2497} 2537}
2498 2538
@@ -2846,8 +2886,8 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
2846 if (spec->autocfg.dig_in_pin) 2886 if (spec->autocfg.dig_in_pin)
2847 spec->dig_in_nid = AD1988_SPDIF_IN; 2887 spec->dig_in_nid = AD1988_SPDIF_IN;
2848 2888
2849 if (spec->kctl_alloc) 2889 if (spec->kctls.list)
2850 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2890 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2851 2891
2852 spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs; 2892 spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs;
2853 2893
@@ -3861,6 +3901,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
3861static struct snd_pci_quirk ad1884a_cfg_tbl[] = { 3901static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
3862 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), 3902 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
3863 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), 3903 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
3904 SND_PCI_QUIRK(0x103c, 0x30e6, "HP 6730b", AD1884A_LAPTOP),
3864 SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP), 3905 SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP),
3865 SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP), 3906 SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP),
3866 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), 3907 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
@@ -4267,7 +4308,7 @@ static int patch_ad1882(struct hda_codec *codec)
4267/* 4308/*
4268 * patch entries 4309 * patch entries
4269 */ 4310 */
4270struct hda_codec_preset snd_hda_preset_analog[] = { 4311static struct hda_codec_preset snd_hda_preset_analog[] = {
4271 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, 4312 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a },
4272 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, 4313 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
4273 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, 4314 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a },
@@ -4285,3 +4326,26 @@ struct hda_codec_preset snd_hda_preset_analog[] = {
4285 { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, 4326 { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 },
4286 {} /* terminator */ 4327 {} /* terminator */
4287}; 4328};
4329
4330MODULE_ALIAS("snd-hda-codec-id:11d4*");
4331
4332MODULE_LICENSE("GPL");
4333MODULE_DESCRIPTION("Analog Devices HD-audio codec");
4334
4335static struct hda_codec_preset_list analog_list = {
4336 .preset = snd_hda_preset_analog,
4337 .owner = THIS_MODULE,
4338};
4339
4340static int __init patch_analog_init(void)
4341{
4342 return snd_hda_add_codec_preset(&analog_list);
4343}
4344
4345static void __exit patch_analog_exit(void)
4346{
4347 snd_hda_delete_codec_preset(&analog_list);
4348}
4349
4350module_init(patch_analog_init)
4351module_exit(patch_analog_exit)
diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c
index ba61575983fd..233e4778bba9 100644
--- a/sound/pci/hda/patch_atihdmi.c
+++ b/sound/pci/hda/patch_atihdmi.c
@@ -27,7 +27,6 @@
27#include <sound/core.h> 27#include <sound/core.h>
28#include "hda_codec.h" 28#include "hda_codec.h"
29#include "hda_local.h" 29#include "hda_local.h"
30#include "hda_patch.h"
31 30
32struct atihdmi_spec { 31struct atihdmi_spec {
33 struct hda_multi_out multiout; 32 struct hda_multi_out multiout;
@@ -187,13 +186,40 @@ static int patch_atihdmi(struct hda_codec *codec)
187/* 186/*
188 * patch entries 187 * patch entries
189 */ 188 */
190struct hda_codec_preset snd_hda_preset_atihdmi[] = { 189static struct hda_codec_preset snd_hda_preset_atihdmi[] = {
191 { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, 190 { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
192 { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, 191 { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
193 { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, 192 { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
194 { .id = 0x1002aa01, .name = "ATI R6xx HDMI", .patch = patch_atihdmi }, 193 { .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi },
195 { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi }, 194 { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi },
196 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_atihdmi },
197 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi }, 195 { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi },
198 {} /* terminator */ 196 {} /* terminator */
199}; 197};
198
199MODULE_ALIAS("snd-hda-codec-id:1002793c");
200MODULE_ALIAS("snd-hda-codec-id:10027919");
201MODULE_ALIAS("snd-hda-codec-id:1002791a");
202MODULE_ALIAS("snd-hda-codec-id:1002aa01");
203MODULE_ALIAS("snd-hda-codec-id:10951390");
204MODULE_ALIAS("snd-hda-codec-id:17e80047");
205
206MODULE_LICENSE("GPL");
207MODULE_DESCRIPTION("ATI HDMI HD-audio codec");
208
209static struct hda_codec_preset_list atihdmi_list = {
210 .preset = snd_hda_preset_atihdmi,
211 .owner = THIS_MODULE,
212};
213
214static int __init patch_atihdmi_init(void)
215{
216 return snd_hda_add_codec_preset(&atihdmi_list);
217}
218
219static void __exit patch_atihdmi_exit(void)
220{
221 snd_hda_delete_codec_preset(&atihdmi_list);
222}
223
224module_init(patch_atihdmi_init)
225module_exit(patch_atihdmi_exit)
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 6ef57fbfb6eb..f3ebe837f2d5 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -28,7 +28,6 @@
28#include <sound/core.h> 28#include <sound/core.h>
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31#include "hda_patch.h"
32#define NUM_PINS 11 31#define NUM_PINS 11
33 32
34 33
@@ -736,8 +735,32 @@ static int patch_cmi9880(struct hda_codec *codec)
736/* 735/*
737 * patch entries 736 * patch entries
738 */ 737 */
739struct hda_codec_preset snd_hda_preset_cmedia[] = { 738static struct hda_codec_preset snd_hda_preset_cmedia[] = {
740 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, 739 { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 },
741 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, 740 { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 },
742 {} /* terminator */ 741 {} /* terminator */
743}; 742};
743
744MODULE_ALIAS("snd-hda-codec-id:13f69880");
745MODULE_ALIAS("snd-hda-codec-id:434d4980");
746
747MODULE_LICENSE("GPL");
748MODULE_DESCRIPTION("C-Media HD-audio codec");
749
750static struct hda_codec_preset_list cmedia_list = {
751 .preset = snd_hda_preset_cmedia,
752 .owner = THIS_MODULE,
753};
754
755static int __init patch_cmedia_init(void)
756{
757 return snd_hda_add_codec_preset(&cmedia_list);
758}
759
760static void __exit patch_cmedia_exit(void)
761{
762 snd_hda_delete_codec_preset(&cmedia_list);
763}
764
765module_init(patch_cmedia_init)
766module_exit(patch_cmedia_exit)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 7c1eb23f0cec..b20e1cede00b 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -27,7 +27,6 @@
27#include <sound/core.h> 27#include <sound/core.h>
28#include "hda_codec.h" 28#include "hda_codec.h"
29#include "hda_local.h" 29#include "hda_local.h"
30#include "hda_patch.h"
31 30
32#define CXT_PIN_DIR_IN 0x00 31#define CXT_PIN_DIR_IN 0x00
33#define CXT_PIN_DIR_OUT 0x01 32#define CXT_PIN_DIR_OUT 0x01
@@ -86,8 +85,6 @@ struct conexant_spec {
86 85
87 /* dynamic controls, init_verbs and input_mux */ 86 /* dynamic controls, init_verbs and input_mux */
88 struct auto_pin_cfg autocfg; 87 struct auto_pin_cfg autocfg;
89 unsigned int num_kctl_alloc, num_kctl_used;
90 struct snd_kcontrol_new *kctl_alloc;
91 struct hda_input_mux private_imux; 88 struct hda_input_mux private_imux;
92 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 89 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
93 90
@@ -344,15 +341,6 @@ static int conexant_init(struct hda_codec *codec)
344 341
345static void conexant_free(struct hda_codec *codec) 342static void conexant_free(struct hda_codec *codec)
346{ 343{
347 struct conexant_spec *spec = codec->spec;
348 unsigned int i;
349
350 if (spec->kctl_alloc) {
351 for (i = 0; i < spec->num_kctl_used; i++)
352 kfree(spec->kctl_alloc[i].name);
353 kfree(spec->kctl_alloc);
354 }
355
356 kfree(codec->spec); 344 kfree(codec->spec);
357} 345}
358 346
@@ -1782,7 +1770,7 @@ static int patch_cxt5051(struct hda_codec *codec)
1782/* 1770/*
1783 */ 1771 */
1784 1772
1785struct hda_codec_preset snd_hda_preset_conexant[] = { 1773static struct hda_codec_preset snd_hda_preset_conexant[] = {
1786 { .id = 0x14f15045, .name = "CX20549 (Venice)", 1774 { .id = 0x14f15045, .name = "CX20549 (Venice)",
1787 .patch = patch_cxt5045 }, 1775 .patch = patch_cxt5045 },
1788 { .id = 0x14f15047, .name = "CX20551 (Waikiki)", 1776 { .id = 0x14f15047, .name = "CX20551 (Waikiki)",
@@ -1791,3 +1779,28 @@ struct hda_codec_preset snd_hda_preset_conexant[] = {
1791 .patch = patch_cxt5051 }, 1779 .patch = patch_cxt5051 },
1792 {} /* terminator */ 1780 {} /* terminator */
1793}; 1781};
1782
1783MODULE_ALIAS("snd-hda-codec-id:14f15045");
1784MODULE_ALIAS("snd-hda-codec-id:14f15047");
1785MODULE_ALIAS("snd-hda-codec-id:14f15051");
1786
1787MODULE_LICENSE("GPL");
1788MODULE_DESCRIPTION("Conexant HD-audio codec");
1789
1790static struct hda_codec_preset_list conexant_list = {
1791 .preset = snd_hda_preset_conexant,
1792 .owner = THIS_MODULE,
1793};
1794
1795static int __init patch_conexant_init(void)
1796{
1797 return snd_hda_add_codec_preset(&conexant_list);
1798}
1799
1800static void __exit patch_conexant_exit(void)
1801{
1802 snd_hda_delete_codec_preset(&conexant_list);
1803}
1804
1805module_init(patch_conexant_init)
1806module_exit(patch_conexant_exit)
diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c
new file mode 100644
index 000000000000..3564f4e4b74c
--- /dev/null
+++ b/sound/pci/hda/patch_intelhdmi.c
@@ -0,0 +1,711 @@
1/*
2 *
3 * patch_intelhdmi.c - Patch for Intel HDMI codecs
4 *
5 * Copyright(c) 2008 Intel Corporation. All rights reserved.
6 *
7 * Authors:
8 * Jiang Zhe <zhe.jiang@intel.com>
9 * Wu Fengguang <wfg@linux.intel.com>
10 *
11 * Maintained by:
12 * Wu Fengguang <wfg@linux.intel.com>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the Free
16 * Software Foundation; either version 2 of the License, or (at your option)
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 * for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software Foundation,
26 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 */
28
29#include <linux/init.h>
30#include <linux/delay.h>
31#include <linux/slab.h>
32#include <sound/core.h>
33#include "hda_codec.h"
34#include "hda_local.h"
35
36#define CVT_NID 0x02 /* audio converter */
37#define PIN_NID 0x03 /* HDMI output pin */
38
39#define INTEL_HDMI_EVENT_TAG 0x08
40
41struct intel_hdmi_spec {
42 struct hda_multi_out multiout;
43 struct hda_pcm pcm_rec;
44 struct hdmi_eld sink_eld;
45};
46
47static struct hda_verb pinout_enable_verb[] = {
48 {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
49 {} /* terminator */
50};
51
52static struct hda_verb pinout_disable_verb[] = {
53 {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00},
54 {}
55};
56
57static struct hda_verb unsolicited_response_verb[] = {
58 {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN |
59 INTEL_HDMI_EVENT_TAG},
60 {}
61};
62
63static struct hda_verb def_chan_map[] = {
64 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x00},
65 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x11},
66 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x22},
67 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x33},
68 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x44},
69 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x55},
70 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x66},
71 {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x77},
72 {}
73};
74
75
76struct hdmi_audio_infoframe {
77 u8 type; /* 0x84 */
78 u8 ver; /* 0x01 */
79 u8 len; /* 0x0a */
80
81 u8 checksum; /* PB0 */
82 u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */
83 u8 SS01_SF24;
84 u8 CXT04;
85 u8 CA;
86 u8 LFEPBL01_LSV36_DM_INH7;
87 u8 reserved[5]; /* PB6 - PB10 */
88};
89
90/*
91 * CEA speaker placement:
92 *
93 * FLH FCH FRH
94 * FLW FL FLC FC FRC FR FRW
95 *
96 * LFE
97 * TC
98 *
99 * RL RLC RC RRC RR
100 *
101 * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to
102 * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC.
103 */
104enum cea_speaker_placement {
105 FL = (1 << 0), /* Front Left */
106 FC = (1 << 1), /* Front Center */
107 FR = (1 << 2), /* Front Right */
108 FLC = (1 << 3), /* Front Left Center */
109 FRC = (1 << 4), /* Front Right Center */
110 RL = (1 << 5), /* Rear Left */
111 RC = (1 << 6), /* Rear Center */
112 RR = (1 << 7), /* Rear Right */
113 RLC = (1 << 8), /* Rear Left Center */
114 RRC = (1 << 9), /* Rear Right Center */
115 LFE = (1 << 10), /* Low Frequency Effect */
116 FLW = (1 << 11), /* Front Left Wide */
117 FRW = (1 << 12), /* Front Right Wide */
118 FLH = (1 << 13), /* Front Left High */
119 FCH = (1 << 14), /* Front Center High */
120 FRH = (1 << 15), /* Front Right High */
121 TC = (1 << 16), /* Top Center */
122};
123
124/*
125 * ELD SA bits in the CEA Speaker Allocation data block
126 */
127static int eld_speaker_allocation_bits[] = {
128 [0] = FL | FR,
129 [1] = LFE,
130 [2] = FC,
131 [3] = RL | RR,
132 [4] = RC,
133 [5] = FLC | FRC,
134 [6] = RLC | RRC,
135 /* the following are not defined in ELD yet */
136 [7] = FLW | FRW,
137 [8] = FLH | FRH,
138 [9] = TC,
139 [10] = FCH,
140};
141
142struct cea_channel_speaker_allocation {
143 int ca_index;
144 int speakers[8];
145
146 /* derived values, just for convenience */
147 int channels;
148 int spk_mask;
149};
150
151/*
152 * This is an ordered list!
153 *
154 * The preceding ones have better chances to be selected by
155 * hdmi_setup_channel_allocation().
156 */
157static struct cea_channel_speaker_allocation channel_allocations[] = {
158/* channel: 8 7 6 5 4 3 2 1 */
159{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } },
160 /* 2.1 */
161{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } },
162 /* Dolby Surround */
163{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } },
164{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } },
165{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } },
166{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } },
167{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } },
168{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } },
169{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } },
170{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } },
171{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } },
172 /* 5.1 */
173{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } },
174{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } },
175{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } },
176{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } },
177 /* 6.1 */
178{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } },
179{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } },
180{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } },
181{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } },
182 /* 7.1 */
183{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } },
184{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } },
185{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } },
186{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } },
187{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } },
188{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } },
189{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } },
190{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } },
191{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } },
192{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } },
193{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } },
194{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } },
195{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } },
196{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } },
197{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } },
198{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } },
199{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } },
200{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } },
201{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } },
202{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } },
203{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } },
204{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } },
205{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } },
206{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } },
207{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } },
208{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } },
209{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } },
210{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } },
211{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } },
212{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } },
213{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } },
214};
215
216/*
217 * HDMI routines
218 */
219
220#ifdef BE_PARANOID
221static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t nid,
222 int *packet_index, int *byte_index)
223{
224 int val;
225
226 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_INDEX, 0);
227
228 *packet_index = val >> 5;
229 *byte_index = val & 0x1f;
230}
231#endif
232
233static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t nid,
234 int packet_index, int byte_index)
235{
236 int val;
237
238 val = (packet_index << 5) | (byte_index & 0x1f);
239
240 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
241}
242
243static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid,
244 unsigned char val)
245{
246 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val);
247}
248
249static void hdmi_enable_output(struct hda_codec *codec)
250{
251 /* Enable Audio InfoFrame Transmission */
252 hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0);
253 snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT,
254 AC_DIPXMIT_BEST);
255 /* Unmute */
256 if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
257 snd_hda_codec_write(codec, PIN_NID, 0,
258 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
259 /* Enable pin out */
260 snd_hda_sequence_write(codec, pinout_enable_verb);
261}
262
263static void hdmi_disable_output(struct hda_codec *codec)
264{
265 snd_hda_sequence_write(codec, pinout_disable_verb);
266 if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP)
267 snd_hda_codec_write(codec, PIN_NID, 0,
268 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
269
270 /*
271 * FIXME: noises may arise when playing music after reloading the
272 * kernel module, until the next X restart or monitor repower.
273 */
274}
275
276static int hdmi_get_channel_count(struct hda_codec *codec)
277{
278 return 1 + snd_hda_codec_read(codec, CVT_NID, 0,
279 AC_VERB_GET_CVT_CHAN_COUNT, 0);
280}
281
282static void hdmi_set_channel_count(struct hda_codec *codec, int chs)
283{
284 snd_hda_codec_write(codec, CVT_NID, 0,
285 AC_VERB_SET_CVT_CHAN_COUNT, chs - 1);
286
287 if (chs != hdmi_get_channel_count(codec))
288 snd_printd(KERN_INFO "HDMI channel count: expect %d, get %d\n",
289 chs, hdmi_get_channel_count(codec));
290}
291
292static void hdmi_debug_channel_mapping(struct hda_codec *codec)
293{
294#ifdef CONFIG_SND_DEBUG_VERBOSE
295 int i;
296 int slot;
297
298 for (i = 0; i < 8; i++) {
299 slot = snd_hda_codec_read(codec, CVT_NID, 0,
300 AC_VERB_GET_HDMI_CHAN_SLOT, i);
301 printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n",
302 slot >> 4, slot & 0x7);
303 }
304#endif
305}
306
307static void hdmi_parse_eld(struct hda_codec *codec)
308{
309 struct intel_hdmi_spec *spec = codec->spec;
310 struct hdmi_eld *eld = &spec->sink_eld;
311
312 if (!snd_hdmi_get_eld(eld, codec, PIN_NID))
313 snd_hdmi_show_eld(eld);
314}
315
316
317/*
318 * Audio InfoFrame routines
319 */
320
321static void hdmi_debug_dip_size(struct hda_codec *codec)
322{
323#ifdef CONFIG_SND_DEBUG_VERBOSE
324 int i;
325 int size;
326
327 size = snd_hdmi_get_eld_size(codec, PIN_NID);
328 printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size);
329
330 for (i = 0; i < 8; i++) {
331 size = snd_hda_codec_read(codec, PIN_NID, 0,
332 AC_VERB_GET_HDMI_DIP_SIZE, i);
333 printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size);
334 }
335#endif
336}
337
338static void hdmi_clear_dip_buffers(struct hda_codec *codec)
339{
340#ifdef BE_PARANOID
341 int i, j;
342 int size;
343 int pi, bi;
344 for (i = 0; i < 8; i++) {
345 size = snd_hda_codec_read(codec, PIN_NID, 0,
346 AC_VERB_GET_HDMI_DIP_SIZE, i);
347 if (size == 0)
348 continue;
349
350 hdmi_set_dip_index(codec, PIN_NID, i, 0x0);
351 for (j = 1; j < 1000; j++) {
352 hdmi_write_dip_byte(codec, PIN_NID, 0x0);
353 hdmi_get_dip_index(codec, PIN_NID, &pi, &bi);
354 if (pi != i)
355 snd_printd(KERN_INFO "dip index %d: %d != %d\n",
356 bi, pi, i);
357 if (bi == 0) /* byte index wrapped around */
358 break;
359 }
360 snd_printd(KERN_INFO
361 "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n",
362 i, size, j);
363 }
364#endif
365}
366
367static void hdmi_fill_audio_infoframe(struct hda_codec *codec,
368 struct hdmi_audio_infoframe *ai)
369{
370 u8 *params = (u8 *)ai;
371 int i;
372
373 hdmi_debug_dip_size(codec);
374 hdmi_clear_dip_buffers(codec); /* be paranoid */
375
376 hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0);
377 for (i = 0; i < sizeof(ai); i++)
378 hdmi_write_dip_byte(codec, PIN_NID, params[i]);
379}
380
381/*
382 * Compute derived values in channel_allocations[].
383 */
384static void init_channel_allocations(void)
385{
386 int i, j;
387 struct cea_channel_speaker_allocation *p;
388
389 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
390 p = channel_allocations + i;
391 p->channels = 0;
392 p->spk_mask = 0;
393 for (j = 0; j < ARRAY_SIZE(p->speakers); j++)
394 if (p->speakers[j]) {
395 p->channels++;
396 p->spk_mask |= p->speakers[j];
397 }
398 }
399}
400
401/*
402 * The transformation takes two steps:
403 *
404 * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask
405 * spk_mask => (channel_allocations[]) => ai->CA
406 *
407 * TODO: it could select the wrong CA from multiple candidates.
408*/
409static int hdmi_setup_channel_allocation(struct hda_codec *codec,
410 struct hdmi_audio_infoframe *ai)
411{
412 struct intel_hdmi_spec *spec = codec->spec;
413 struct hdmi_eld *eld = &spec->sink_eld;
414 int i;
415 int spk_mask = 0;
416 int channels = 1 + (ai->CC02_CT47 & 0x7);
417 char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE];
418
419 /*
420 * CA defaults to 0 for basic stereo audio
421 */
422 if (!eld->eld_ver)
423 return 0;
424 if (!eld->spk_alloc)
425 return 0;
426 if (channels <= 2)
427 return 0;
428
429 /*
430 * expand ELD's speaker allocation mask
431 *
432 * ELD tells the speaker mask in a compact(paired) form,
433 * expand ELD's notions to match the ones used by Audio InfoFrame.
434 */
435 for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) {
436 if (eld->spk_alloc & (1 << i))
437 spk_mask |= eld_speaker_allocation_bits[i];
438 }
439
440 /* search for the first working match in the CA table */
441 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
442 if (channels == channel_allocations[i].channels &&
443 (spk_mask & channel_allocations[i].spk_mask) ==
444 channel_allocations[i].spk_mask) {
445 ai->CA = channel_allocations[i].ca_index;
446 break;
447 }
448 }
449
450 snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf));
451 snd_printdd(KERN_INFO
452 "HDMI: select CA 0x%x for %d-channel allocation: %s\n",
453 ai->CA, channels, buf);
454
455 return ai->CA;
456}
457
458static void hdmi_setup_channel_mapping(struct hda_codec *codec,
459 struct hdmi_audio_infoframe *ai)
460{
461 if (!ai->CA)
462 return;
463
464 /*
465 * TODO: adjust channel mapping if necessary
466 * ALSA sequence is front/surr/clfe/side?
467 */
468
469 snd_hda_sequence_write(codec, def_chan_map);
470 hdmi_debug_channel_mapping(codec);
471}
472
473
474static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
475 struct snd_pcm_substream *substream)
476{
477 struct hdmi_audio_infoframe ai = {
478 .type = 0x84,
479 .ver = 0x01,
480 .len = 0x0a,
481 .CC02_CT47 = substream->runtime->channels - 1,
482 };
483
484 hdmi_setup_channel_allocation(codec, &ai);
485 hdmi_setup_channel_mapping(codec, &ai);
486
487 hdmi_fill_audio_infoframe(codec, &ai);
488}
489
490
491/*
492 * Unsolicited events
493 */
494
495static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
496{
497 int pind = !!(res & AC_UNSOL_RES_PD);
498 int eldv = !!(res & AC_UNSOL_RES_ELDV);
499
500 printk(KERN_INFO
501 "HDMI hot plug event: Presence_Detect=%d ELD_Valid=%d\n",
502 pind, eldv);
503
504 if (pind && eldv) {
505 hdmi_parse_eld(codec);
506 /* TODO: do real things about ELD */
507 }
508}
509
510static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
511{
512 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
513 int cp_state = !!(res & AC_UNSOL_RES_CP_STATE);
514 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
515
516 printk(KERN_INFO
517 "HDMI content protection event: SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
518 subtag,
519 cp_state,
520 cp_ready);
521
522 /* TODO */
523 if (cp_state)
524 ;
525 if (cp_ready)
526 ;
527}
528
529
530static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res)
531{
532 int tag = res >> AC_UNSOL_RES_TAG_SHIFT;
533 int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT;
534
535 if (tag != INTEL_HDMI_EVENT_TAG) {
536 snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag);
537 return;
538 }
539
540 if (subtag == 0)
541 hdmi_intrinsic_event(codec, res);
542 else
543 hdmi_non_intrinsic_event(codec, res);
544}
545
546/*
547 * Callbacks
548 */
549
550static int intel_hdmi_playback_pcm_open(struct hda_pcm_stream *hinfo,
551 struct hda_codec *codec,
552 struct snd_pcm_substream *substream)
553{
554 struct intel_hdmi_spec *spec = codec->spec;
555
556 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
557}
558
559static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo,
560 struct hda_codec *codec,
561 struct snd_pcm_substream *substream)
562{
563 struct intel_hdmi_spec *spec = codec->spec;
564
565 hdmi_disable_output(codec);
566
567 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
568}
569
570static int intel_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
571 struct hda_codec *codec,
572 unsigned int stream_tag,
573 unsigned int format,
574 struct snd_pcm_substream *substream)
575{
576 struct intel_hdmi_spec *spec = codec->spec;
577
578 snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
579 format, substream);
580
581 hdmi_set_channel_count(codec, substream->runtime->channels);
582
583 hdmi_setup_audio_infoframe(codec, substream);
584
585 hdmi_enable_output(codec);
586
587 return 0;
588}
589
590static struct hda_pcm_stream intel_hdmi_pcm_playback = {
591 .substreams = 1,
592 .channels_min = 2,
593 .channels_max = 8,
594 .nid = CVT_NID, /* NID to query formats and rates and setup streams */
595 .ops = {
596 .open = intel_hdmi_playback_pcm_open,
597 .close = intel_hdmi_playback_pcm_close,
598 .prepare = intel_hdmi_playback_pcm_prepare
599 },
600};
601
602static int intel_hdmi_build_pcms(struct hda_codec *codec)
603{
604 struct intel_hdmi_spec *spec = codec->spec;
605 struct hda_pcm *info = &spec->pcm_rec;
606
607 codec->num_pcms = 1;
608 codec->pcm_info = info;
609
610 info->name = "INTEL HDMI";
611 info->pcm_type = HDA_PCM_TYPE_HDMI;
612 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback;
613
614 return 0;
615}
616
617static int intel_hdmi_build_controls(struct hda_codec *codec)
618{
619 struct intel_hdmi_spec *spec = codec->spec;
620 int err;
621
622 err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid);
623 if (err < 0)
624 return err;
625
626 return 0;
627}
628
629static int intel_hdmi_init(struct hda_codec *codec)
630{
631 /* disable audio output as early as possible */
632 hdmi_disable_output(codec);
633
634 snd_hda_sequence_write(codec, unsolicited_response_verb);
635
636 return 0;
637}
638
639static void intel_hdmi_free(struct hda_codec *codec)
640{
641 struct intel_hdmi_spec *spec = codec->spec;
642
643 snd_hda_eld_proc_free(codec, &spec->sink_eld);
644 kfree(spec);
645}
646
647static struct hda_codec_ops intel_hdmi_patch_ops = {
648 .init = intel_hdmi_init,
649 .free = intel_hdmi_free,
650 .build_pcms = intel_hdmi_build_pcms,
651 .build_controls = intel_hdmi_build_controls,
652 .unsol_event = intel_hdmi_unsol_event,
653};
654
655static int patch_intel_hdmi(struct hda_codec *codec)
656{
657 struct intel_hdmi_spec *spec;
658
659 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
660 if (spec == NULL)
661 return -ENOMEM;
662
663 spec->multiout.num_dacs = 0; /* no analog */
664 spec->multiout.max_channels = 8;
665 spec->multiout.dig_out_nid = CVT_NID;
666
667 codec->spec = spec;
668 codec->patch_ops = intel_hdmi_patch_ops;
669
670 snd_hda_eld_proc_new(codec, &spec->sink_eld);
671
672 init_channel_allocations();
673
674 return 0;
675}
676
677static struct hda_codec_preset snd_hda_preset_intelhdmi[] = {
678 { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi },
679 { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi },
680 { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi },
681 { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi },
682 { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi },
683 {} /* terminator */
684};
685
686MODULE_ALIAS("snd-hda-codec-id:808629fb");
687MODULE_ALIAS("snd-hda-codec-id:80862801");
688MODULE_ALIAS("snd-hda-codec-id:80862802");
689MODULE_ALIAS("snd-hda-codec-id:80862803");
690MODULE_ALIAS("snd-hda-codec-id:10951392");
691
692MODULE_LICENSE("GPL");
693MODULE_DESCRIPTION("Intel HDMI HD-audio codec");
694
695static struct hda_codec_preset_list intel_list = {
696 .preset = snd_hda_preset_intelhdmi,
697 .owner = THIS_MODULE,
698};
699
700static int __init patch_intelhdmi_init(void)
701{
702 return snd_hda_add_codec_preset(&intel_list);
703}
704
705static void __exit patch_intelhdmi_exit(void)
706{
707 snd_hda_delete_codec_preset(&intel_list);
708}
709
710module_init(patch_intelhdmi_init)
711module_exit(patch_intelhdmi_exit)
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 2eed2c8b98da..0270fda0bda5 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -158,8 +158,34 @@ static int patch_nvhdmi(struct hda_codec *codec)
158/* 158/*
159 * patch entries 159 * patch entries
160 */ 160 */
161struct hda_codec_preset snd_hda_preset_nvhdmi[] = { 161static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
162 { .id = 0x10de0002, .name = "NVIDIA MCP78 HDMI", .patch = patch_nvhdmi }, 162 { .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi },
163 { .id = 0x10de0007, .name = "NVIDIA MCP7A HDMI", .patch = patch_nvhdmi }, 163 { .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi },
164 { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi },
164 {} /* terminator */ 165 {} /* terminator */
165}; 166};
167
168MODULE_ALIAS("snd-hda-codec-id:10de0002");
169MODULE_ALIAS("snd-hda-codec-id:10de0007");
170MODULE_ALIAS("snd-hda-codec-id:10de0067");
171
172MODULE_LICENSE("GPL");
173MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec");
174
175static struct hda_codec_preset_list nvhdmi_list = {
176 .preset = snd_hda_preset_nvhdmi,
177 .owner = THIS_MODULE,
178};
179
180static int __init patch_nvhdmi_init(void)
181{
182 return snd_hda_add_codec_preset(&nvhdmi_list);
183}
184
185static void __exit patch_nvhdmi_exit(void)
186{
187 snd_hda_delete_codec_preset(&nvhdmi_list);
188}
189
190module_init(patch_nvhdmi_init)
191module_exit(patch_nvhdmi_exit)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a378c0145125..0bd4e6bf354d 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -30,7 +30,6 @@
30#include <sound/core.h> 30#include <sound/core.h>
31#include "hda_codec.h" 31#include "hda_codec.h"
32#include "hda_local.h" 32#include "hda_local.h"
33#include "hda_patch.h"
34 33
35#define ALC880_FRONT_EVENT 0x01 34#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02 35#define ALC880_DCVOL_EVENT 0x02
@@ -114,6 +113,7 @@ enum {
114 ALC268_3ST, 113 ALC268_3ST,
115 ALC268_TOSHIBA, 114 ALC268_TOSHIBA,
116 ALC268_ACER, 115 ALC268_ACER,
116 ALC268_ACER_DMIC,
117 ALC268_ACER_ASPIRE_ONE, 117 ALC268_ACER_ASPIRE_ONE,
118 ALC268_DELL, 118 ALC268_DELL,
119 ALC268_ZEPTO, 119 ALC268_ZEPTO,
@@ -130,6 +130,8 @@ enum {
130 ALC269_QUANTA_FL1, 130 ALC269_QUANTA_FL1,
131 ALC269_ASUS_EEEPC_P703, 131 ALC269_ASUS_EEEPC_P703,
132 ALC269_ASUS_EEEPC_P901, 132 ALC269_ASUS_EEEPC_P901,
133 ALC269_FUJITSU,
134 ALC269_LIFEBOOK,
133 ALC269_AUTO, 135 ALC269_AUTO,
134 ALC269_MODEL_LAST /* last tag */ 136 ALC269_MODEL_LAST /* last tag */
135}; 137};
@@ -152,6 +154,7 @@ enum {
152enum { 154enum {
153 ALC660VD_3ST, 155 ALC660VD_3ST,
154 ALC660VD_3ST_DIG, 156 ALC660VD_3ST_DIG,
157 ALC660VD_ASUS_V1S,
155 ALC861VD_3ST, 158 ALC861VD_3ST,
156 ALC861VD_3ST_DIG, 159 ALC861VD_3ST_DIG,
157 ALC861VD_6ST_DIG, 160 ALC861VD_6ST_DIG,
@@ -212,6 +215,7 @@ enum {
212 ALC883_TARGA_2ch_DIG, 215 ALC883_TARGA_2ch_DIG,
213 ALC883_ACER, 216 ALC883_ACER,
214 ALC883_ACER_ASPIRE, 217 ALC883_ACER_ASPIRE,
218 ALC888_ACER_ASPIRE_4930G,
215 ALC883_MEDION, 219 ALC883_MEDION,
216 ALC883_MEDION_MD2, 220 ALC883_MEDION_MD2,
217 ALC883_LAPTOP_EAPD, 221 ALC883_LAPTOP_EAPD,
@@ -225,9 +229,11 @@ enum {
225 ALC883_MITAC, 229 ALC883_MITAC,
226 ALC883_CLEVO_M720, 230 ALC883_CLEVO_M720,
227 ALC883_FUJITSU_PI2515, 231 ALC883_FUJITSU_PI2515,
232 ALC888_FUJITSU_XA3530,
228 ALC883_3ST_6ch_INTEL, 233 ALC883_3ST_6ch_INTEL,
229 ALC888_ASUS_M90V, 234 ALC888_ASUS_M90V,
230 ALC888_ASUS_EEE1601, 235 ALC888_ASUS_EEE1601,
236 ALC1200_ASUS_P5Q,
231 ALC883_AUTO, 237 ALC883_AUTO,
232 ALC883_MODEL_LAST, 238 ALC883_MODEL_LAST,
233}; 239};
@@ -239,6 +245,7 @@ struct alc_spec {
239 /* codec parameterization */ 245 /* codec parameterization */
240 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 246 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
241 unsigned int num_mixers; 247 unsigned int num_mixers;
248 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
242 249
243 const struct hda_verb *init_verbs[5]; /* initialization verbs 250 const struct hda_verb *init_verbs[5]; /* initialization verbs
244 * don't forget NULL 251 * don't forget NULL
@@ -268,6 +275,7 @@ struct alc_spec {
268 hda_nid_t *adc_nids; 275 hda_nid_t *adc_nids;
269 hda_nid_t *capsrc_nids; 276 hda_nid_t *capsrc_nids;
270 hda_nid_t dig_in_nid; /* digital-in NID; optional */ 277 hda_nid_t dig_in_nid; /* digital-in NID; optional */
278 unsigned char is_mix_capture; /* matrix-style capture (non-mux) */
271 279
272 /* capture source */ 280 /* capture source */
273 unsigned int num_mux_defs; 281 unsigned int num_mux_defs;
@@ -284,8 +292,7 @@ struct alc_spec {
284 292
285 /* dynamic controls, init_verbs and input_mux */ 293 /* dynamic controls, init_verbs and input_mux */
286 struct auto_pin_cfg autocfg; 294 struct auto_pin_cfg autocfg;
287 unsigned int num_kctl_alloc, num_kctl_used; 295 struct snd_array kctls;
288 struct snd_kcontrol_new *kctl_alloc;
289 struct hda_input_mux private_imux; 296 struct hda_input_mux private_imux;
290 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 297 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
291 298
@@ -323,6 +330,7 @@ struct alc_config_preset {
323 struct snd_kcontrol_new *mixers[5]; /* should be identical size 330 struct snd_kcontrol_new *mixers[5]; /* should be identical size
324 * with spec 331 * with spec
325 */ 332 */
333 struct snd_kcontrol_new *cap_mixer; /* capture mixer */
326 const struct hda_verb *init_verbs[5]; 334 const struct hda_verb *init_verbs[5];
327 unsigned int num_dacs; 335 unsigned int num_dacs;
328 hda_nid_t *dac_nids; 336 hda_nid_t *dac_nids;
@@ -375,14 +383,39 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
375{ 383{
376 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 384 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
377 struct alc_spec *spec = codec->spec; 385 struct alc_spec *spec = codec->spec;
386 const struct hda_input_mux *imux;
378 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 387 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
379 unsigned int mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx; 388 unsigned int mux_idx;
380 hda_nid_t nid = spec->capsrc_nids ? 389 hda_nid_t nid = spec->capsrc_nids ?
381 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; 390 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
382 return snd_hda_input_mux_put(codec, &spec->input_mux[mux_idx], ucontrol,
383 nid, &spec->cur_mux[adc_idx]);
384}
385 391
392 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
393 imux = &spec->input_mux[mux_idx];
394
395 if (spec->is_mix_capture) {
396 /* Matrix-mixer style (e.g. ALC882) */
397 unsigned int *cur_val = &spec->cur_mux[adc_idx];
398 unsigned int i, idx;
399
400 idx = ucontrol->value.enumerated.item[0];
401 if (idx >= imux->num_items)
402 idx = imux->num_items - 1;
403 if (*cur_val == idx)
404 return 0;
405 for (i = 0; i < imux->num_items; i++) {
406 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
407 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
408 imux->items[i].index,
409 HDA_AMP_MUTE, v);
410 }
411 *cur_val = idx;
412 return 1;
413 } else {
414 /* MUX style (e.g. ALC880) */
415 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
416 &spec->cur_mux[adc_idx]);
417 }
418}
386 419
387/* 420/*
388 * channel mode setting 421 * channel mode setting
@@ -717,6 +750,43 @@ static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
717#endif /* CONFIG_SND_DEBUG */ 750#endif /* CONFIG_SND_DEBUG */
718 751
719/* 752/*
753 */
754static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix)
755{
756 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
757 return;
758 spec->mixers[spec->num_mixers++] = mix;
759}
760
761static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
762{
763 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
764 return;
765 spec->init_verbs[spec->num_init_verbs++] = verb;
766}
767
768#ifdef CONFIG_PROC_FS
769/*
770 * hook for proc
771 */
772static void print_realtek_coef(struct snd_info_buffer *buffer,
773 struct hda_codec *codec, hda_nid_t nid)
774{
775 int coeff;
776
777 if (nid != 0x20)
778 return;
779 coeff = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PROC_COEF, 0);
780 snd_iprintf(buffer, " Processing Coefficient: 0x%02x\n", coeff);
781 coeff = snd_hda_codec_read(codec, nid, 0,
782 AC_VERB_GET_COEF_INDEX, 0);
783 snd_iprintf(buffer, " Coefficient Index: 0x%02x\n", coeff);
784}
785#else
786#define print_realtek_coef NULL
787#endif
788
789/*
720 * set up from the preset table 790 * set up from the preset table
721 */ 791 */
722static void setup_preset(struct alc_spec *spec, 792static void setup_preset(struct alc_spec *spec,
@@ -725,11 +795,11 @@ static void setup_preset(struct alc_spec *spec,
725 int i; 795 int i;
726 796
727 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++) 797 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
728 spec->mixers[spec->num_mixers++] = preset->mixers[i]; 798 add_mixer(spec, preset->mixers[i]);
799 spec->cap_mixer = preset->cap_mixer;
729 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i]; 800 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
730 i++) 801 i++)
731 spec->init_verbs[spec->num_init_verbs++] = 802 add_verb(spec, preset->init_verbs[i]);
732 preset->init_verbs[i];
733 803
734 spec->channel_mode = preset->channel_mode; 804 spec->channel_mode = preset->channel_mode;
735 spec->num_channel_mode = preset->num_channel_mode; 805 spec->num_channel_mode = preset->num_channel_mode;
@@ -1107,6 +1177,226 @@ static void alc_fix_pincfg(struct hda_codec *codec,
1107} 1177}
1108 1178
1109/* 1179/*
1180 * ALC888
1181 */
1182
1183/*
1184 * 2ch mode
1185 */
1186static struct hda_verb alc888_4ST_ch2_intel_init[] = {
1187/* Mic-in jack as mic in */
1188 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1189 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1190/* Line-in jack as Line in */
1191 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1192 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1193/* Line-Out as Front */
1194 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1195 { } /* end */
1196};
1197
1198/*
1199 * 4ch mode
1200 */
1201static struct hda_verb alc888_4ST_ch4_intel_init[] = {
1202/* Mic-in jack as mic in */
1203 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1204 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
1205/* Line-in jack as Surround */
1206 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1207 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1208/* Line-Out as Front */
1209 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
1210 { } /* end */
1211};
1212
1213/*
1214 * 6ch mode
1215 */
1216static struct hda_verb alc888_4ST_ch6_intel_init[] = {
1217/* Mic-in jack as CLFE */
1218 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1219 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1220/* Line-in jack as Surround */
1221 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1222 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1223/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
1224 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1225 { } /* end */
1226};
1227
1228/*
1229 * 8ch mode
1230 */
1231static struct hda_verb alc888_4ST_ch8_intel_init[] = {
1232/* Mic-in jack as CLFE */
1233 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1234 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1235/* Line-in jack as Surround */
1236 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1237 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
1238/* Line-Out as Side */
1239 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1240 { } /* end */
1241};
1242
1243static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
1244 { 2, alc888_4ST_ch2_intel_init },
1245 { 4, alc888_4ST_ch4_intel_init },
1246 { 6, alc888_4ST_ch6_intel_init },
1247 { 8, alc888_4ST_ch8_intel_init },
1248};
1249
1250/*
1251 * ALC888 Fujitsu Siemens Amillo xa3530
1252 */
1253
1254static struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
1255/* Front Mic: set to PIN_IN (empty by default) */
1256 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1257/* Connect Internal HP to Front */
1258 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1259 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1260 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1261/* Connect Bass HP to Front */
1262 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1263 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1264 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1265/* Connect Line-Out side jack (SPDIF) to Side */
1266 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1267 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1268 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
1269/* Connect Mic jack to CLFE */
1270 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1271 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1272 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
1273/* Connect Line-in jack to Surround */
1274 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1275 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1276 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
1277/* Connect HP out jack to Front */
1278 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1279 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1280 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
1281/* Enable unsolicited event for HP jack and Line-out jack */
1282 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1283 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1284 {}
1285};
1286
1287static void alc888_fujitsu_xa3530_automute(struct hda_codec *codec)
1288{
1289 unsigned int present;
1290 unsigned int bits;
1291 /* Line out presence */
1292 present = snd_hda_codec_read(codec, 0x17, 0,
1293 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1294 /* HP out presence */
1295 present = present || snd_hda_codec_read(codec, 0x1b, 0,
1296 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1297 bits = present ? HDA_AMP_MUTE : 0;
1298 /* Toggle internal speakers muting */
1299 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1300 HDA_AMP_MUTE, bits);
1301 /* Toggle internal bass muting */
1302 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
1303 HDA_AMP_MUTE, bits);
1304}
1305
1306static void alc888_fujitsu_xa3530_unsol_event(struct hda_codec *codec,
1307 unsigned int res)
1308{
1309 if (res >> 26 == ALC880_HP_EVENT)
1310 alc888_fujitsu_xa3530_automute(codec);
1311}
1312
1313
1314/*
1315 * ALC888 Acer Aspire 4930G model
1316 */
1317
1318static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1319/* Front Mic: set to PIN_IN (empty by default) */
1320 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1321/* Unselect Front Mic by default in input mixer 3 */
1322 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
1323/* Enable unsolicited event for HP jack */
1324 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
1325/* Connect Internal HP to front */
1326 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1327 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1328 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
1329/* Connect HP out to front */
1330 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1331 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1332 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
1333 { }
1334};
1335
1336static struct hda_input_mux alc888_2_capture_sources[2] = {
1337 /* Front mic only available on one ADC */
1338 {
1339 .num_items = 4,
1340 .items = {
1341 { "Mic", 0x0 },
1342 { "Line", 0x2 },
1343 { "CD", 0x4 },
1344 { "Front Mic", 0xb },
1345 },
1346 },
1347 {
1348 .num_items = 3,
1349 .items = {
1350 { "Mic", 0x0 },
1351 { "Line", 0x2 },
1352 { "CD", 0x4 },
1353 },
1354 }
1355};
1356
1357static struct snd_kcontrol_new alc888_base_mixer[] = {
1358 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1359 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
1360 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1361 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
1362 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
1363 HDA_OUTPUT),
1364 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1365 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1366 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1367 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
1368 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
1369 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1370 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1371 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1372 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1373 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1374 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
1375 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1376 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1377 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1378 { } /* end */
1379};
1380
1381static void alc888_acer_aspire_4930g_automute(struct hda_codec *codec)
1382{
1383 unsigned int present;
1384 unsigned int bits;
1385 present = snd_hda_codec_read(codec, 0x15, 0,
1386 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1387 bits = present ? HDA_AMP_MUTE : 0;
1388 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
1389 HDA_AMP_MUTE, bits);
1390}
1391
1392static void alc888_acer_aspire_4930g_unsol_event(struct hda_codec *codec,
1393 unsigned int res)
1394{
1395 if (res >> 26 == ALC880_HP_EVENT)
1396 alc888_acer_aspire_4930g_automute(codec);
1397}
1398
1399/*
1110 * ALC880 3-stack model 1400 * ALC880 3-stack model
1111 * 1401 *
1112 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e) 1402 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
@@ -1205,49 +1495,126 @@ static struct snd_kcontrol_new alc880_three_stack_mixer[] = {
1205}; 1495};
1206 1496
1207/* capture mixer elements */ 1497/* capture mixer elements */
1208static struct snd_kcontrol_new alc880_capture_mixer[] = { 1498static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
1209 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), 1499 struct snd_ctl_elem_info *uinfo)
1210 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), 1500{
1211 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT), 1501 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1212 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT), 1502 struct alc_spec *spec = codec->spec;
1213 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT), 1503 int err;
1214 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
1215 {
1216 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1217 /* The multiple "Capture Source" controls confuse alsamixer
1218 * So call somewhat different..
1219 */
1220 /* .name = "Capture Source", */
1221 .name = "Input Source",
1222 .count = 3,
1223 .info = alc_mux_enum_info,
1224 .get = alc_mux_enum_get,
1225 .put = alc_mux_enum_put,
1226 },
1227 { } /* end */
1228};
1229 1504
1230/* capture mixer elements (in case NID 0x07 not available) */ 1505 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1231static struct snd_kcontrol_new alc880_capture_alt_mixer[] = { 1506 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1232 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1507 HDA_INPUT);
1233 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1508 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
1234 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), 1509 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1235 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), 1510 return err;
1236 { 1511}
1237 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1512
1238 /* The multiple "Capture Source" controls confuse alsamixer 1513static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1239 * So call somewhat different.. 1514 unsigned int size, unsigned int __user *tlv)
1240 */ 1515{
1241 /* .name = "Capture Source", */ 1516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1242 .name = "Input Source", 1517 struct alc_spec *spec = codec->spec;
1243 .count = 2, 1518 int err;
1244 .info = alc_mux_enum_info,
1245 .get = alc_mux_enum_get,
1246 .put = alc_mux_enum_put,
1247 },
1248 { } /* end */
1249};
1250 1519
1520 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1521 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
1522 HDA_INPUT);
1523 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
1524 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1525 return err;
1526}
1527
1528typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1529 struct snd_ctl_elem_value *ucontrol);
1530
1531static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1532 struct snd_ctl_elem_value *ucontrol,
1533 getput_call_t func)
1534{
1535 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1536 struct alc_spec *spec = codec->spec;
1537 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
1538 int err;
1539
1540 mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
1541 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
1542 3, 0, HDA_INPUT);
1543 err = func(kcontrol, ucontrol);
1544 mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
1545 return err;
1546}
1547
1548static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
1549 struct snd_ctl_elem_value *ucontrol)
1550{
1551 return alc_cap_getput_caller(kcontrol, ucontrol,
1552 snd_hda_mixer_amp_volume_get);
1553}
1554
1555static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
1556 struct snd_ctl_elem_value *ucontrol)
1557{
1558 return alc_cap_getput_caller(kcontrol, ucontrol,
1559 snd_hda_mixer_amp_volume_put);
1560}
1561
1562/* capture mixer elements */
1563#define alc_cap_sw_info snd_ctl_boolean_stereo_info
1564
1565static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
1566 struct snd_ctl_elem_value *ucontrol)
1567{
1568 return alc_cap_getput_caller(kcontrol, ucontrol,
1569 snd_hda_mixer_amp_switch_get);
1570}
1571
1572static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
1573 struct snd_ctl_elem_value *ucontrol)
1574{
1575 return alc_cap_getput_caller(kcontrol, ucontrol,
1576 snd_hda_mixer_amp_switch_put);
1577}
1578
1579#define DEFINE_CAPMIX(num) \
1580static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
1581 { \
1582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1583 .name = "Capture Switch", \
1584 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
1585 .count = num, \
1586 .info = alc_cap_sw_info, \
1587 .get = alc_cap_sw_get, \
1588 .put = alc_cap_sw_put, \
1589 }, \
1590 { \
1591 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1592 .name = "Capture Volume", \
1593 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
1594 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
1595 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
1596 .count = num, \
1597 .info = alc_cap_vol_info, \
1598 .get = alc_cap_vol_get, \
1599 .put = alc_cap_vol_put, \
1600 .tlv = { .c = alc_cap_vol_tlv }, \
1601 }, \
1602 { \
1603 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1604 /* .name = "Capture Source", */ \
1605 .name = "Input Source", \
1606 .count = num, \
1607 .info = alc_mux_enum_info, \
1608 .get = alc_mux_enum_get, \
1609 .put = alc_mux_enum_put, \
1610 }, \
1611 { } /* end */ \
1612}
1613
1614/* up to three ADCs */
1615DEFINE_CAPMIX(1);
1616DEFINE_CAPMIX(2);
1617DEFINE_CAPMIX(3);
1251 1618
1252 1619
1253/* 1620/*
@@ -1533,18 +1900,6 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT), 1900 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
1534 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 1901 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
1535 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 1902 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
1536 {
1537 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1538 /* The multiple "Capture Source" controls confuse alsamixer
1539 * So call somewhat different..
1540 */
1541 /* .name = "Capture Source", */
1542 .name = "Input Source",
1543 .count = 1,
1544 .info = alc_mux_enum_info,
1545 .get = alc_mux_enum_get,
1546 .put = alc_mux_enum_put,
1547 },
1548 { } /* end */ 1903 { } /* end */
1549}; 1904};
1550 1905
@@ -1619,6 +1974,7 @@ static const char *alc_slave_vols[] = {
1619 "Speaker Playback Volume", 1974 "Speaker Playback Volume",
1620 "Mono Playback Volume", 1975 "Mono Playback Volume",
1621 "Line-Out Playback Volume", 1976 "Line-Out Playback Volume",
1977 "PCM Playback Volume",
1622 NULL, 1978 NULL,
1623}; 1979};
1624 1980
@@ -1638,6 +1994,9 @@ static const char *alc_slave_sws[] = {
1638/* 1994/*
1639 * build control elements 1995 * build control elements
1640 */ 1996 */
1997
1998static void alc_free_kctls(struct hda_codec *codec);
1999
1641static int alc_build_controls(struct hda_codec *codec) 2000static int alc_build_controls(struct hda_codec *codec)
1642{ 2001{
1643 struct alc_spec *spec = codec->spec; 2002 struct alc_spec *spec = codec->spec;
@@ -1649,7 +2008,11 @@ static int alc_build_controls(struct hda_codec *codec)
1649 if (err < 0) 2008 if (err < 0)
1650 return err; 2009 return err;
1651 } 2010 }
1652 2011 if (spec->cap_mixer) {
2012 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
2013 if (err < 0)
2014 return err;
2015 }
1653 if (spec->multiout.dig_out_nid) { 2016 if (spec->multiout.dig_out_nid) {
1654 err = snd_hda_create_spdif_out_ctls(codec, 2017 err = snd_hda_create_spdif_out_ctls(codec,
1655 spec->multiout.dig_out_nid); 2018 spec->multiout.dig_out_nid);
@@ -1684,6 +2047,7 @@ static int alc_build_controls(struct hda_codec *codec)
1684 return err; 2047 return err;
1685 } 2048 }
1686 2049
2050 alc_free_kctls(codec); /* no longer needed */
1687 return 0; 2051 return 0;
1688} 2052}
1689 2053
@@ -2774,19 +3138,27 @@ static int alc_build_pcms(struct hda_codec *codec)
2774 return 0; 3138 return 0;
2775} 3139}
2776 3140
3141static void alc_free_kctls(struct hda_codec *codec)
3142{
3143 struct alc_spec *spec = codec->spec;
3144
3145 if (spec->kctls.list) {
3146 struct snd_kcontrol_new *kctl = spec->kctls.list;
3147 int i;
3148 for (i = 0; i < spec->kctls.used; i++)
3149 kfree(kctl[i].name);
3150 }
3151 snd_array_free(&spec->kctls);
3152}
3153
2777static void alc_free(struct hda_codec *codec) 3154static void alc_free(struct hda_codec *codec)
2778{ 3155{
2779 struct alc_spec *spec = codec->spec; 3156 struct alc_spec *spec = codec->spec;
2780 unsigned int i;
2781 3157
2782 if (!spec) 3158 if (!spec)
2783 return; 3159 return;
2784 3160
2785 if (spec->kctl_alloc) { 3161 alc_free_kctls(codec);
2786 for (i = 0; i < spec->num_kctl_used; i++)
2787 kfree(spec->kctl_alloc[i].name);
2788 kfree(spec->kctl_alloc);
2789 }
2790 kfree(spec); 3162 kfree(spec);
2791 codec->spec = NULL; /* to be sure */ 3163 codec->spec = NULL; /* to be sure */
2792} 3164}
@@ -3268,6 +3640,8 @@ static struct alc_config_preset alc880_presets[] = {
3268 alc880_gpio2_init_verbs }, 3640 alc880_gpio2_init_verbs },
3269 .num_dacs = ARRAY_SIZE(alc880_dac_nids), 3641 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
3270 .dac_nids = alc880_dac_nids, 3642 .dac_nids = alc880_dac_nids,
3643 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
3644 .num_adc_nids = 1, /* single ADC */
3271 .hp_nid = 0x03, 3645 .hp_nid = 0x03,
3272 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), 3646 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
3273 .channel_mode = alc880_2_jack_modes, 3647 .channel_mode = alc880_2_jack_modes,
@@ -3532,9 +3906,6 @@ static struct alc_config_preset alc880_presets[] = {
3532 * Automatic parse of I/O pins from the BIOS configuration 3906 * Automatic parse of I/O pins from the BIOS configuration
3533 */ 3907 */
3534 3908
3535#define NUM_CONTROL_ALLOC 32
3536#define NUM_VERB_ALLOC 32
3537
3538enum { 3909enum {
3539 ALC_CTL_WIDGET_VOL, 3910 ALC_CTL_WIDGET_VOL,
3540 ALC_CTL_WIDGET_MUTE, 3911 ALC_CTL_WIDGET_MUTE,
@@ -3552,29 +3923,15 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
3552{ 3923{
3553 struct snd_kcontrol_new *knew; 3924 struct snd_kcontrol_new *knew;
3554 3925
3555 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 3926 snd_array_init(&spec->kctls, sizeof(*knew), 32);
3556 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 3927 knew = snd_array_new(&spec->kctls);
3557 3928 if (!knew)
3558 /* array + terminator */ 3929 return -ENOMEM;
3559 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
3560 if (!knew)
3561 return -ENOMEM;
3562 if (spec->kctl_alloc) {
3563 memcpy(knew, spec->kctl_alloc,
3564 sizeof(*knew) * spec->num_kctl_alloc);
3565 kfree(spec->kctl_alloc);
3566 }
3567 spec->kctl_alloc = knew;
3568 spec->num_kctl_alloc = num;
3569 }
3570
3571 knew = &spec->kctl_alloc[spec->num_kctl_used];
3572 *knew = alc880_control_templates[type]; 3930 *knew = alc880_control_templates[type];
3573 knew->name = kstrdup(name, GFP_KERNEL); 3931 knew->name = kstrdup(name, GFP_KERNEL);
3574 if (!knew->name) 3932 if (!knew->name)
3575 return -ENOMEM; 3933 return -ENOMEM;
3576 knew->private_value = val; 3934 knew->private_value = val;
3577 spec->num_kctl_used++;
3578 return 0; 3935 return 0;
3579} 3936}
3580 3937
@@ -3898,10 +4255,10 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
3898 if (spec->autocfg.dig_in_pin) 4255 if (spec->autocfg.dig_in_pin)
3899 spec->dig_in_nid = ALC880_DIGIN_NID; 4256 spec->dig_in_nid = ALC880_DIGIN_NID;
3900 4257
3901 if (spec->kctl_alloc) 4258 if (spec->kctls.list)
3902 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 4259 add_mixer(spec, spec->kctls.list);
3903 4260
3904 spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; 4261 add_verb(spec, alc880_volume_init_verbs);
3905 4262
3906 spec->num_mux_defs = 1; 4263 spec->num_mux_defs = 1;
3907 spec->input_mux = &spec->private_imux; 4264 spec->input_mux = &spec->private_imux;
@@ -3925,6 +4282,17 @@ static void alc880_auto_init(struct hda_codec *codec)
3925 * OK, here we have finally the patch for ALC880 4282 * OK, here we have finally the patch for ALC880
3926 */ 4283 */
3927 4284
4285static void set_capture_mixer(struct alc_spec *spec)
4286{
4287 static struct snd_kcontrol_new *caps[3] = {
4288 alc_capture_mixer1,
4289 alc_capture_mixer2,
4290 alc_capture_mixer3,
4291 };
4292 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3)
4293 spec->cap_mixer = caps[spec->num_adc_nids - 1];
4294}
4295
3928static int patch_alc880(struct hda_codec *codec) 4296static int patch_alc880(struct hda_codec *codec)
3929{ 4297{
3930 struct alc_spec *spec; 4298 struct alc_spec *spec;
@@ -3980,16 +4348,12 @@ static int patch_alc880(struct hda_codec *codec)
3980 if (wcap != AC_WID_AUD_IN) { 4348 if (wcap != AC_WID_AUD_IN) {
3981 spec->adc_nids = alc880_adc_nids_alt; 4349 spec->adc_nids = alc880_adc_nids_alt;
3982 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); 4350 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
3983 spec->mixers[spec->num_mixers] =
3984 alc880_capture_alt_mixer;
3985 spec->num_mixers++;
3986 } else { 4351 } else {
3987 spec->adc_nids = alc880_adc_nids; 4352 spec->adc_nids = alc880_adc_nids;
3988 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids); 4353 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
3989 spec->mixers[spec->num_mixers] = alc880_capture_mixer;
3990 spec->num_mixers++;
3991 } 4354 }
3992 } 4355 }
4356 set_capture_mixer(spec);
3993 4357
3994 spec->vmaster_nid = 0x0c; 4358 spec->vmaster_nid = 0x0c;
3995 4359
@@ -4000,6 +4364,7 @@ static int patch_alc880(struct hda_codec *codec)
4000 if (!spec->loopback.amplist) 4364 if (!spec->loopback.amplist)
4001 spec->loopback.amplist = alc880_loopbacks; 4365 spec->loopback.amplist = alc880_loopbacks;
4002#endif 4366#endif
4367 codec->proc_widget_hook = print_realtek_coef;
4003 4368
4004 return 0; 4369 return 0;
4005} 4370}
@@ -4024,11 +4389,6 @@ static hda_nid_t alc260_adc_nids_alt[1] = {
4024 0x05, 4389 0x05,
4025}; 4390};
4026 4391
4027static hda_nid_t alc260_hp_adc_nids[2] = {
4028 /* ADC1, 0 */
4029 0x05, 0x04
4030};
4031
4032/* NIDs used when simultaneous access to both ADCs makes sense. Note that 4392/* NIDs used when simultaneous access to both ADCs makes sense. Note that
4033 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. 4393 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
4034 */ 4394 */
@@ -4157,13 +4517,13 @@ static void alc260_hp_master_update(struct hda_codec *codec,
4157 struct alc_spec *spec = codec->spec; 4517 struct alc_spec *spec = codec->spec;
4158 unsigned int val = spec->master_sw ? PIN_HP : 0; 4518 unsigned int val = spec->master_sw ? PIN_HP : 0;
4159 /* change HP and line-out pins */ 4519 /* change HP and line-out pins */
4160 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4520 snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4161 val); 4521 val);
4162 snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4522 snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4163 val); 4523 val);
4164 /* mono (speaker) depending on the HP jack sense */ 4524 /* mono (speaker) depending on the HP jack sense */
4165 val = (val && !spec->jack_present) ? PIN_OUT : 0; 4525 val = (val && !spec->jack_present) ? PIN_OUT : 0;
4166 snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 4526 snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4167 val); 4527 val);
4168} 4528}
4169 4529
@@ -4242,7 +4602,7 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
4242 .info = snd_ctl_boolean_mono_info, 4602 .info = snd_ctl_boolean_mono_info,
4243 .get = alc260_hp_master_sw_get, 4603 .get = alc260_hp_master_sw_get,
4244 .put = alc260_hp_master_sw_put, 4604 .put = alc260_hp_master_sw_put,
4245 .private_value = (0x10 << 16) | (0x15 << 8) | 0x11 4605 .private_value = (0x15 << 16) | (0x10 << 8) | 0x11
4246 }, 4606 },
4247 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), 4607 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
4248 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), 4608 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
@@ -4295,7 +4655,7 @@ static void alc260_hp_3013_automute(struct hda_codec *codec)
4295 present = snd_hda_codec_read(codec, 0x15, 0, 4655 present = snd_hda_codec_read(codec, 0x15, 0,
4296 AC_VERB_GET_PIN_SENSE, 0); 4656 AC_VERB_GET_PIN_SENSE, 0);
4297 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0; 4657 spec->jack_present = (present & AC_PINSENSE_PRESENCE) != 0;
4298 alc260_hp_master_update(codec, 0x10, 0x15, 0x11); 4658 alc260_hp_master_update(codec, 0x15, 0x10, 0x11);
4299} 4659}
4300 4660
4301static void alc260_hp_3013_unsol_event(struct hda_codec *codec, 4661static void alc260_hp_3013_unsol_event(struct hda_codec *codec,
@@ -4427,45 +4787,6 @@ static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
4427 { } /* end */ 4787 { } /* end */
4428}; 4788};
4429 4789
4430/* capture mixer elements */
4431static struct snd_kcontrol_new alc260_capture_mixer[] = {
4432 HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT),
4433 HDA_CODEC_MUTE("Capture Switch", 0x04, 0x0, HDA_INPUT),
4434 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x05, 0x0, HDA_INPUT),
4435 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x05, 0x0, HDA_INPUT),
4436 {
4437 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4438 /* The multiple "Capture Source" controls confuse alsamixer
4439 * So call somewhat different..
4440 */
4441 /* .name = "Capture Source", */
4442 .name = "Input Source",
4443 .count = 2,
4444 .info = alc_mux_enum_info,
4445 .get = alc_mux_enum_get,
4446 .put = alc_mux_enum_put,
4447 },
4448 { } /* end */
4449};
4450
4451static struct snd_kcontrol_new alc260_capture_alt_mixer[] = {
4452 HDA_CODEC_VOLUME("Capture Volume", 0x05, 0x0, HDA_INPUT),
4453 HDA_CODEC_MUTE("Capture Switch", 0x05, 0x0, HDA_INPUT),
4454 {
4455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4456 /* The multiple "Capture Source" controls confuse alsamixer
4457 * So call somewhat different..
4458 */
4459 /* .name = "Capture Source", */
4460 .name = "Input Source",
4461 .count = 1,
4462 .info = alc_mux_enum_info,
4463 .get = alc_mux_enum_get,
4464 .put = alc_mux_enum_put,
4465 },
4466 { } /* end */
4467};
4468
4469/* 4790/*
4470 * initialization verbs 4791 * initialization verbs
4471 */ 4792 */
@@ -5282,7 +5603,6 @@ static struct hda_verb alc260_volume_init_verbs[] = {
5282static int alc260_parse_auto_config(struct hda_codec *codec) 5603static int alc260_parse_auto_config(struct hda_codec *codec)
5283{ 5604{
5284 struct alc_spec *spec = codec->spec; 5605 struct alc_spec *spec = codec->spec;
5285 unsigned int wcap;
5286 int err; 5606 int err;
5287 static hda_nid_t alc260_ignore[] = { 0x17, 0 }; 5607 static hda_nid_t alc260_ignore[] = { 0x17, 0 };
5288 5608
@@ -5293,7 +5613,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
5293 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); 5613 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
5294 if (err < 0) 5614 if (err < 0)
5295 return err; 5615 return err;
5296 if (!spec->kctl_alloc) 5616 if (!spec->kctls.list)
5297 return 0; /* can't find valid BIOS pin config */ 5617 return 0; /* can't find valid BIOS pin config */
5298 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); 5618 err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
5299 if (err < 0) 5619 if (err < 0)
@@ -5303,28 +5623,14 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
5303 5623
5304 if (spec->autocfg.dig_out_pin) 5624 if (spec->autocfg.dig_out_pin)
5305 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; 5625 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
5306 if (spec->kctl_alloc) 5626 if (spec->kctls.list)
5307 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 5627 add_mixer(spec, spec->kctls.list);
5308 5628
5309 spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; 5629 add_verb(spec, alc260_volume_init_verbs);
5310 5630
5311 spec->num_mux_defs = 1; 5631 spec->num_mux_defs = 1;
5312 spec->input_mux = &spec->private_imux; 5632 spec->input_mux = &spec->private_imux;
5313 5633
5314 /* check whether NID 0x04 is valid */
5315 wcap = get_wcaps(codec, 0x04);
5316 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */
5317 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5318 spec->adc_nids = alc260_adc_nids_alt;
5319 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5320 spec->mixers[spec->num_mixers] = alc260_capture_alt_mixer;
5321 } else {
5322 spec->adc_nids = alc260_adc_nids;
5323 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5324 spec->mixers[spec->num_mixers] = alc260_capture_mixer;
5325 }
5326 spec->num_mixers++;
5327
5328 store_pin_configs(codec); 5634 store_pin_configs(codec);
5329 return 1; 5635 return 1;
5330} 5636}
@@ -5394,12 +5700,11 @@ static struct alc_config_preset alc260_presets[] = {
5394 [ALC260_BASIC] = { 5700 [ALC260_BASIC] = {
5395 .mixers = { alc260_base_output_mixer, 5701 .mixers = { alc260_base_output_mixer,
5396 alc260_input_mixer, 5702 alc260_input_mixer,
5397 alc260_pc_beep_mixer, 5703 alc260_pc_beep_mixer },
5398 alc260_capture_mixer },
5399 .init_verbs = { alc260_init_verbs }, 5704 .init_verbs = { alc260_init_verbs },
5400 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5705 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5401 .dac_nids = alc260_dac_nids, 5706 .dac_nids = alc260_dac_nids,
5402 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), 5707 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
5403 .adc_nids = alc260_adc_nids, 5708 .adc_nids = alc260_adc_nids,
5404 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5709 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5405 .channel_mode = alc260_modes, 5710 .channel_mode = alc260_modes,
@@ -5407,14 +5712,13 @@ static struct alc_config_preset alc260_presets[] = {
5407 }, 5712 },
5408 [ALC260_HP] = { 5713 [ALC260_HP] = {
5409 .mixers = { alc260_hp_output_mixer, 5714 .mixers = { alc260_hp_output_mixer,
5410 alc260_input_mixer, 5715 alc260_input_mixer },
5411 alc260_capture_alt_mixer },
5412 .init_verbs = { alc260_init_verbs, 5716 .init_verbs = { alc260_init_verbs,
5413 alc260_hp_unsol_verbs }, 5717 alc260_hp_unsol_verbs },
5414 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5718 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5415 .dac_nids = alc260_dac_nids, 5719 .dac_nids = alc260_dac_nids,
5416 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 5720 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5417 .adc_nids = alc260_hp_adc_nids, 5721 .adc_nids = alc260_adc_nids_alt,
5418 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5722 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5419 .channel_mode = alc260_modes, 5723 .channel_mode = alc260_modes,
5420 .input_mux = &alc260_capture_source, 5724 .input_mux = &alc260_capture_source,
@@ -5423,14 +5727,13 @@ static struct alc_config_preset alc260_presets[] = {
5423 }, 5727 },
5424 [ALC260_HP_DC7600] = { 5728 [ALC260_HP_DC7600] = {
5425 .mixers = { alc260_hp_dc7600_mixer, 5729 .mixers = { alc260_hp_dc7600_mixer,
5426 alc260_input_mixer, 5730 alc260_input_mixer },
5427 alc260_capture_alt_mixer },
5428 .init_verbs = { alc260_init_verbs, 5731 .init_verbs = { alc260_init_verbs,
5429 alc260_hp_dc7600_verbs }, 5732 alc260_hp_dc7600_verbs },
5430 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5733 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5431 .dac_nids = alc260_dac_nids, 5734 .dac_nids = alc260_dac_nids,
5432 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 5735 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5433 .adc_nids = alc260_hp_adc_nids, 5736 .adc_nids = alc260_adc_nids_alt,
5434 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5737 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5435 .channel_mode = alc260_modes, 5738 .channel_mode = alc260_modes,
5436 .input_mux = &alc260_capture_source, 5739 .input_mux = &alc260_capture_source,
@@ -5439,14 +5742,13 @@ static struct alc_config_preset alc260_presets[] = {
5439 }, 5742 },
5440 [ALC260_HP_3013] = { 5743 [ALC260_HP_3013] = {
5441 .mixers = { alc260_hp_3013_mixer, 5744 .mixers = { alc260_hp_3013_mixer,
5442 alc260_input_mixer, 5745 alc260_input_mixer },
5443 alc260_capture_alt_mixer },
5444 .init_verbs = { alc260_hp_3013_init_verbs, 5746 .init_verbs = { alc260_hp_3013_init_verbs,
5445 alc260_hp_3013_unsol_verbs }, 5747 alc260_hp_3013_unsol_verbs },
5446 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5748 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5447 .dac_nids = alc260_dac_nids, 5749 .dac_nids = alc260_dac_nids,
5448 .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), 5750 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
5449 .adc_nids = alc260_hp_adc_nids, 5751 .adc_nids = alc260_adc_nids_alt,
5450 .num_channel_mode = ARRAY_SIZE(alc260_modes), 5752 .num_channel_mode = ARRAY_SIZE(alc260_modes),
5451 .channel_mode = alc260_modes, 5753 .channel_mode = alc260_modes,
5452 .input_mux = &alc260_capture_source, 5754 .input_mux = &alc260_capture_source,
@@ -5454,8 +5756,7 @@ static struct alc_config_preset alc260_presets[] = {
5454 .init_hook = alc260_hp_3013_automute, 5756 .init_hook = alc260_hp_3013_automute,
5455 }, 5757 },
5456 [ALC260_FUJITSU_S702X] = { 5758 [ALC260_FUJITSU_S702X] = {
5457 .mixers = { alc260_fujitsu_mixer, 5759 .mixers = { alc260_fujitsu_mixer },
5458 alc260_capture_mixer },
5459 .init_verbs = { alc260_fujitsu_init_verbs }, 5760 .init_verbs = { alc260_fujitsu_init_verbs },
5460 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5761 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5461 .dac_nids = alc260_dac_nids, 5762 .dac_nids = alc260_dac_nids,
@@ -5467,8 +5768,7 @@ static struct alc_config_preset alc260_presets[] = {
5467 .input_mux = alc260_fujitsu_capture_sources, 5768 .input_mux = alc260_fujitsu_capture_sources,
5468 }, 5769 },
5469 [ALC260_ACER] = { 5770 [ALC260_ACER] = {
5470 .mixers = { alc260_acer_mixer, 5771 .mixers = { alc260_acer_mixer },
5471 alc260_capture_mixer },
5472 .init_verbs = { alc260_acer_init_verbs }, 5772 .init_verbs = { alc260_acer_init_verbs },
5473 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5773 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5474 .dac_nids = alc260_dac_nids, 5774 .dac_nids = alc260_dac_nids,
@@ -5480,8 +5780,7 @@ static struct alc_config_preset alc260_presets[] = {
5480 .input_mux = alc260_acer_capture_sources, 5780 .input_mux = alc260_acer_capture_sources,
5481 }, 5781 },
5482 [ALC260_WILL] = { 5782 [ALC260_WILL] = {
5483 .mixers = { alc260_will_mixer, 5783 .mixers = { alc260_will_mixer },
5484 alc260_capture_mixer },
5485 .init_verbs = { alc260_init_verbs, alc260_will_verbs }, 5784 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
5486 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5785 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5487 .dac_nids = alc260_dac_nids, 5786 .dac_nids = alc260_dac_nids,
@@ -5493,8 +5792,7 @@ static struct alc_config_preset alc260_presets[] = {
5493 .input_mux = &alc260_capture_source, 5792 .input_mux = &alc260_capture_source,
5494 }, 5793 },
5495 [ALC260_REPLACER_672V] = { 5794 [ALC260_REPLACER_672V] = {
5496 .mixers = { alc260_replacer_672v_mixer, 5795 .mixers = { alc260_replacer_672v_mixer },
5497 alc260_capture_mixer },
5498 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, 5796 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
5499 .num_dacs = ARRAY_SIZE(alc260_dac_nids), 5797 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
5500 .dac_nids = alc260_dac_nids, 5798 .dac_nids = alc260_dac_nids,
@@ -5509,8 +5807,7 @@ static struct alc_config_preset alc260_presets[] = {
5509 }, 5807 },
5510#ifdef CONFIG_SND_DEBUG 5808#ifdef CONFIG_SND_DEBUG
5511 [ALC260_TEST] = { 5809 [ALC260_TEST] = {
5512 .mixers = { alc260_test_mixer, 5810 .mixers = { alc260_test_mixer },
5513 alc260_capture_mixer },
5514 .init_verbs = { alc260_test_init_verbs }, 5811 .init_verbs = { alc260_test_init_verbs },
5515 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids), 5812 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
5516 .dac_nids = alc260_test_dac_nids, 5813 .dac_nids = alc260_test_dac_nids,
@@ -5569,6 +5866,21 @@ static int patch_alc260(struct hda_codec *codec)
5569 spec->stream_digital_playback = &alc260_pcm_digital_playback; 5866 spec->stream_digital_playback = &alc260_pcm_digital_playback;
5570 spec->stream_digital_capture = &alc260_pcm_digital_capture; 5867 spec->stream_digital_capture = &alc260_pcm_digital_capture;
5571 5868
5869 if (!spec->adc_nids && spec->input_mux) {
5870 /* check whether NID 0x04 is valid */
5871 unsigned int wcap = get_wcaps(codec, 0x04);
5872 wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
5873 /* get type */
5874 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
5875 spec->adc_nids = alc260_adc_nids_alt;
5876 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
5877 } else {
5878 spec->adc_nids = alc260_adc_nids;
5879 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
5880 }
5881 }
5882 set_capture_mixer(spec);
5883
5572 spec->vmaster_nid = 0x08; 5884 spec->vmaster_nid = 0x08;
5573 5885
5574 codec->patch_ops = alc_patch_ops; 5886 codec->patch_ops = alc_patch_ops;
@@ -5578,6 +5890,7 @@ static int patch_alc260(struct hda_codec *codec)
5578 if (!spec->loopback.amplist) 5890 if (!spec->loopback.amplist)
5579 spec->loopback.amplist = alc260_loopbacks; 5891 spec->loopback.amplist = alc260_loopbacks;
5580#endif 5892#endif
5893 codec->proc_widget_hook = print_realtek_coef;
5581 5894
5582 return 0; 5895 return 0;
5583} 5896}
@@ -5625,36 +5938,6 @@ static struct hda_input_mux alc882_capture_source = {
5625 { "CD", 0x4 }, 5938 { "CD", 0x4 },
5626 }, 5939 },
5627}; 5940};
5628#define alc882_mux_enum_info alc_mux_enum_info
5629#define alc882_mux_enum_get alc_mux_enum_get
5630
5631static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol,
5632 struct snd_ctl_elem_value *ucontrol)
5633{
5634 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
5635 struct alc_spec *spec = codec->spec;
5636 const struct hda_input_mux *imux = spec->input_mux;
5637 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
5638 hda_nid_t nid = spec->capsrc_nids ?
5639 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
5640 unsigned int *cur_val = &spec->cur_mux[adc_idx];
5641 unsigned int i, idx;
5642
5643 idx = ucontrol->value.enumerated.item[0];
5644 if (idx >= imux->num_items)
5645 idx = imux->num_items - 1;
5646 if (*cur_val == idx)
5647 return 0;
5648 for (i = 0; i < imux->num_items; i++) {
5649 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
5650 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
5651 imux->items[i].index,
5652 HDA_AMP_MUTE, v);
5653 }
5654 *cur_val = idx;
5655 return 1;
5656}
5657
5658/* 5941/*
5659 * 2ch mode 5942 * 2ch mode
5660 */ 5943 */
@@ -6337,49 +6620,6 @@ static struct hda_verb alc882_auto_init_verbs[] = {
6337 { } 6620 { }
6338}; 6621};
6339 6622
6340/* capture mixer elements */
6341static struct snd_kcontrol_new alc882_capture_alt_mixer[] = {
6342 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
6343 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
6344 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
6345 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
6346 {
6347 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6348 /* The multiple "Capture Source" controls confuse alsamixer
6349 * So call somewhat different..
6350 */
6351 /* .name = "Capture Source", */
6352 .name = "Input Source",
6353 .count = 2,
6354 .info = alc882_mux_enum_info,
6355 .get = alc882_mux_enum_get,
6356 .put = alc882_mux_enum_put,
6357 },
6358 { } /* end */
6359};
6360
6361static struct snd_kcontrol_new alc882_capture_mixer[] = {
6362 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
6363 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
6364 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x08, 0x0, HDA_INPUT),
6365 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x08, 0x0, HDA_INPUT),
6366 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x09, 0x0, HDA_INPUT),
6367 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x09, 0x0, HDA_INPUT),
6368 {
6369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6370 /* The multiple "Capture Source" controls confuse alsamixer
6371 * So call somewhat different..
6372 */
6373 /* .name = "Capture Source", */
6374 .name = "Input Source",
6375 .count = 3,
6376 .info = alc882_mux_enum_info,
6377 .get = alc882_mux_enum_get,
6378 .put = alc882_mux_enum_put,
6379 },
6380 { } /* end */
6381};
6382
6383#ifdef CONFIG_SND_HDA_POWER_SAVE 6623#ifdef CONFIG_SND_HDA_POWER_SAVE
6384#define alc882_loopbacks alc880_loopbacks 6624#define alc882_loopbacks alc880_loopbacks
6385#endif 6625#endif
@@ -6508,8 +6748,7 @@ static struct alc_config_preset alc882_presets[] = {
6508 .init_hook = alc885_imac24_init_hook, 6748 .init_hook = alc885_imac24_init_hook,
6509 }, 6749 },
6510 [ALC882_TARGA] = { 6750 [ALC882_TARGA] = {
6511 .mixers = { alc882_targa_mixer, alc882_chmode_mixer, 6751 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
6512 alc882_capture_mixer },
6513 .init_verbs = { alc882_init_verbs, alc882_targa_verbs}, 6752 .init_verbs = { alc882_init_verbs, alc882_targa_verbs},
6514 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6753 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6515 .dac_nids = alc882_dac_nids, 6754 .dac_nids = alc882_dac_nids,
@@ -6525,8 +6764,7 @@ static struct alc_config_preset alc882_presets[] = {
6525 .init_hook = alc882_targa_automute, 6764 .init_hook = alc882_targa_automute,
6526 }, 6765 },
6527 [ALC882_ASUS_A7J] = { 6766 [ALC882_ASUS_A7J] = {
6528 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer, 6767 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
6529 alc882_capture_mixer },
6530 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs}, 6768 .init_verbs = { alc882_init_verbs, alc882_asus_a7j_verbs},
6531 .num_dacs = ARRAY_SIZE(alc882_dac_nids), 6769 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
6532 .dac_nids = alc882_dac_nids, 6770 .dac_nids = alc882_dac_nids,
@@ -6831,6 +7069,7 @@ static int patch_alc882(struct hda_codec *codec)
6831 spec->stream_digital_playback = &alc882_pcm_digital_playback; 7069 spec->stream_digital_playback = &alc882_pcm_digital_playback;
6832 spec->stream_digital_capture = &alc882_pcm_digital_capture; 7070 spec->stream_digital_capture = &alc882_pcm_digital_capture;
6833 7071
7072 spec->is_mix_capture = 1; /* matrix-style capture */
6834 if (!spec->adc_nids && spec->input_mux) { 7073 if (!spec->adc_nids && spec->input_mux) {
6835 /* check whether NID 0x07 is valid */ 7074 /* check whether NID 0x07 is valid */
6836 unsigned int wcap = get_wcaps(codec, 0x07); 7075 unsigned int wcap = get_wcaps(codec, 0x07);
@@ -6840,17 +7079,13 @@ static int patch_alc882(struct hda_codec *codec)
6840 spec->adc_nids = alc882_adc_nids_alt; 7079 spec->adc_nids = alc882_adc_nids_alt;
6841 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); 7080 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt);
6842 spec->capsrc_nids = alc882_capsrc_nids_alt; 7081 spec->capsrc_nids = alc882_capsrc_nids_alt;
6843 spec->mixers[spec->num_mixers] =
6844 alc882_capture_alt_mixer;
6845 spec->num_mixers++;
6846 } else { 7082 } else {
6847 spec->adc_nids = alc882_adc_nids; 7083 spec->adc_nids = alc882_adc_nids;
6848 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids); 7084 spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids);
6849 spec->capsrc_nids = alc882_capsrc_nids; 7085 spec->capsrc_nids = alc882_capsrc_nids;
6850 spec->mixers[spec->num_mixers] = alc882_capture_mixer;
6851 spec->num_mixers++;
6852 } 7086 }
6853 } 7087 }
7088 set_capture_mixer(spec);
6854 7089
6855 spec->vmaster_nid = 0x0c; 7090 spec->vmaster_nid = 0x0c;
6856 7091
@@ -6861,6 +7096,7 @@ static int patch_alc882(struct hda_codec *codec)
6861 if (!spec->loopback.amplist) 7096 if (!spec->loopback.amplist)
6862 spec->loopback.amplist = alc882_loopbacks; 7097 spec->loopback.amplist = alc882_loopbacks;
6863#endif 7098#endif
7099 codec->proc_widget_hook = print_realtek_coef;
6864 7100
6865 return 0; 7101 return 0;
6866} 7102}
@@ -6879,6 +7115,8 @@ static int patch_alc882(struct hda_codec *codec)
6879#define ALC883_DIGOUT_NID 0x06 7115#define ALC883_DIGOUT_NID 0x06
6880#define ALC883_DIGIN_NID 0x0a 7116#define ALC883_DIGIN_NID 0x0a
6881 7117
7118#define ALC1200_DIGOUT_NID 0x10
7119
6882static hda_nid_t alc883_dac_nids[4] = { 7120static hda_nid_t alc883_dac_nids[4] = {
6883 /* front, rear, clfe, rear_surr */ 7121 /* front, rear, clfe, rear_surr */
6884 0x02, 0x03, 0x04, 0x05 7122 0x02, 0x03, 0x04, 0x05
@@ -6889,8 +7127,20 @@ static hda_nid_t alc883_adc_nids[2] = {
6889 0x08, 0x09, 7127 0x08, 0x09,
6890}; 7128};
6891 7129
7130static hda_nid_t alc883_adc_nids_alt[1] = {
7131 /* ADC1 */
7132 0x08,
7133};
7134
7135static hda_nid_t alc883_adc_nids_rev[2] = {
7136 /* ADC2-1 */
7137 0x09, 0x08
7138};
7139
6892static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 }; 7140static hda_nid_t alc883_capsrc_nids[2] = { 0x23, 0x22 };
6893 7141
7142static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7143
6894/* input MUX */ 7144/* input MUX */
6895/* FIXME: should be a matrix-type input source selection */ 7145/* FIXME: should be a matrix-type input source selection */
6896 7146
@@ -6957,11 +7207,6 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = {
6957 }, 7207 },
6958}; 7208};
6959 7209
6960#define alc883_mux_enum_info alc_mux_enum_info
6961#define alc883_mux_enum_get alc_mux_enum_get
6962/* ALC883 has the ALC882-type input selection */
6963#define alc883_mux_enum_put alc882_mux_enum_put
6964
6965/* 7210/*
6966 * 2ch mode 7211 * 2ch mode
6967 */ 7212 */
@@ -7115,19 +7360,6 @@ static struct snd_kcontrol_new alc883_base_mixer[] = {
7115 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7360 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7116 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7361 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7117 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7362 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7118 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7119 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7120 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7121 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7122 {
7123 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7124 /* .name = "Capture Source", */
7125 .name = "Input Source",
7126 .count = 2,
7127 .info = alc883_mux_enum_info,
7128 .get = alc883_mux_enum_get,
7129 .put = alc883_mux_enum_put,
7130 },
7131 { } /* end */ 7363 { } /* end */
7132}; 7364};
7133 7365
@@ -7145,19 +7377,6 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = {
7145 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7377 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7146 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7378 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7147 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7379 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7148 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7149 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7150 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7151 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7152 {
7153 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7154 /* .name = "Capture Source", */
7155 .name = "Input Source",
7156 .count = 2,
7157 .info = alc883_mux_enum_info,
7158 .get = alc883_mux_enum_get,
7159 .put = alc883_mux_enum_put,
7160 },
7161 { } /* end */ 7380 { } /* end */
7162}; 7381};
7163 7382
@@ -7172,19 +7391,6 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
7172 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7391 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7173 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7392 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7174 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7393 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7175 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7176 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7177 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7178 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7179 {
7180 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7181 /* .name = "Capture Source", */
7182 .name = "Input Source",
7183 .count = 2,
7184 .info = alc883_mux_enum_info,
7185 .get = alc883_mux_enum_get,
7186 .put = alc883_mux_enum_put,
7187 },
7188 { } /* end */ 7394 { } /* end */
7189}; 7395};
7190 7396
@@ -7199,19 +7405,6 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
7199 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7405 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7200 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7406 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7201 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7407 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7202 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7203 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7204 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7205 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7206 {
7207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7208 /* .name = "Capture Source", */
7209 .name = "Input Source",
7210 .count = 2,
7211 .info = alc883_mux_enum_info,
7212 .get = alc883_mux_enum_get,
7213 .put = alc883_mux_enum_put,
7214 },
7215 { } /* end */ 7408 { } /* end */
7216}; 7409};
7217 7410
@@ -7231,19 +7424,6 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
7231 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7424 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7232 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7425 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7233 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7426 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7234 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7235 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7236 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7237 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7238 {
7239 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7240 /* .name = "Capture Source", */
7241 .name = "Input Source",
7242 .count = 2,
7243 .info = alc883_mux_enum_info,
7244 .get = alc883_mux_enum_get,
7245 .put = alc883_mux_enum_put,
7246 },
7247 { } /* end */ 7427 { } /* end */
7248}; 7428};
7249 7429
@@ -7269,17 +7449,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
7269 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7449 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7270 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7450 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7271 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7451 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7272 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7273 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7274 {
7275 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7276 /* .name = "Capture Source", */
7277 .name = "Input Source",
7278 .count = 1,
7279 .info = alc883_mux_enum_info,
7280 .get = alc883_mux_enum_get,
7281 .put = alc883_mux_enum_put,
7282 },
7283 { } /* end */ 7452 { } /* end */
7284}; 7453};
7285 7454
@@ -7306,19 +7475,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
7306 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7475 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7307 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7476 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7308 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7477 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7309 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7310 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7311 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7312 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7313 {
7314 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7315 /* .name = "Capture Source", */
7316 .name = "Input Source",
7317 .count = 2,
7318 .info = alc883_mux_enum_info,
7319 .get = alc883_mux_enum_get,
7320 .put = alc883_mux_enum_put,
7321 },
7322 { } /* end */ 7478 { } /* end */
7323}; 7479};
7324 7480
@@ -7344,18 +7500,6 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
7344 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7500 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7345 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 7501 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
7346 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 7502 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
7347 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7348 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7349
7350 {
7351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7352 /* .name = "Capture Source", */
7353 .name = "Input Source",
7354 .count = 1,
7355 .info = alc883_mux_enum_info,
7356 .get = alc883_mux_enum_get,
7357 .put = alc883_mux_enum_put,
7358 },
7359 { } /* end */ 7503 { } /* end */
7360}; 7504};
7361 7505
@@ -7376,19 +7520,6 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = {
7376 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7520 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7377 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7521 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7378 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7522 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7379 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7380 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7381 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7382 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7383 {
7384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7385 /* .name = "Capture Source", */
7386 .name = "Input Source",
7387 .count = 2,
7388 .info = alc883_mux_enum_info,
7389 .get = alc883_mux_enum_get,
7390 .put = alc883_mux_enum_put,
7391 },
7392 { } /* end */ 7523 { } /* end */
7393}; 7524};
7394 7525
@@ -7404,19 +7535,6 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
7404 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7535 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7405 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 7536 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT),
7406 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7537 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7407 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7408 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7409 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7410 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7411 {
7412 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7413 /* .name = "Capture Source", */
7414 .name = "Input Source",
7415 .count = 2,
7416 .info = alc883_mux_enum_info,
7417 .get = alc883_mux_enum_get,
7418 .put = alc883_mux_enum_put,
7419 },
7420 { } /* end */ 7538 { } /* end */
7421}; 7539};
7422 7540
@@ -7429,17 +7547,6 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
7429 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7547 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7430 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7548 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7431 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7549 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7432 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7433 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7434 {
7435 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7436 /* .name = "Capture Source", */
7437 .name = "Input Source",
7438 .count = 1,
7439 .info = alc883_mux_enum_info,
7440 .get = alc883_mux_enum_get,
7441 .put = alc883_mux_enum_put,
7442 },
7443 { } /* end */ 7550 { } /* end */
7444}; 7551};
7445 7552
@@ -7453,19 +7560,6 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
7453 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7560 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7454 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7561 HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7455 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7562 HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7456 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7457 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7458 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7459 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7460 {
7461 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7462 /* .name = "Capture Source", */
7463 .name = "Input Source",
7464 .count = 2,
7465 .info = alc883_mux_enum_info,
7466 .get = alc883_mux_enum_get,
7467 .put = alc883_mux_enum_put,
7468 },
7469 { } /* end */ 7563 { } /* end */
7470}; 7564};
7471 7565
@@ -7479,19 +7573,6 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
7479 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7573 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7480 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7574 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7481 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7575 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7482 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7483 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7484 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7485 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7486 {
7487 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7488 /* .name = "Capture Source", */
7489 .name = "Input Source",
7490 .count = 2,
7491 .info = alc883_mux_enum_info,
7492 .get = alc883_mux_enum_get,
7493 .put = alc883_mux_enum_put,
7494 },
7495 { } /* end */ 7576 { } /* end */
7496}; 7577};
7497 7578
@@ -7504,19 +7585,6 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
7504 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7585 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7505 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7586 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7506 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7587 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7507 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7508 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7509 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7510 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7511 {
7512 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7513 /* .name = "Capture Source", */
7514 .name = "Input Source",
7515 .count = 2,
7516 .info = alc883_mux_enum_info,
7517 .get = alc883_mux_enum_get,
7518 .put = alc883_mux_enum_put,
7519 },
7520 { } /* end */ 7588 { } /* end */
7521}; 7589};
7522 7590
@@ -7544,19 +7612,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
7544 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7612 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7545 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7613 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
7546 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7614 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7547 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7548 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7549 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
7550 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
7551 {
7552 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7553 /* .name = "Capture Source", */
7554 .name = "Input Source",
7555 .count = 2,
7556 .info = alc883_mux_enum_info,
7557 .get = alc883_mux_enum_get,
7558 .put = alc883_mux_enum_put,
7559 },
7560 { } /* end */ 7615 { } /* end */
7561}; 7616};
7562 7617
@@ -7587,6 +7642,10 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7587 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7642 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7588 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7643 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
7589 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7644 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7645 { } /* end */
7646};
7647
7648static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
7590 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), 7649 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
7591 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), 7650 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
7592 { 7651 {
@@ -7594,9 +7653,9 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
7594 /* .name = "Capture Source", */ 7653 /* .name = "Capture Source", */
7595 .name = "Input Source", 7654 .name = "Input Source",
7596 .count = 1, 7655 .count = 1,
7597 .info = alc883_mux_enum_info, 7656 .info = alc_mux_enum_info,
7598 .get = alc883_mux_enum_get, 7657 .get = alc_mux_enum_get,
7599 .put = alc883_mux_enum_put, 7658 .put = alc_mux_enum_put,
7600 }, 7659 },
7601 { } /* end */ 7660 { } /* end */
7602}; 7661};
@@ -8251,27 +8310,6 @@ static struct hda_verb alc883_auto_init_verbs[] = {
8251 { } 8310 { }
8252}; 8311};
8253 8312
8254/* capture mixer elements */
8255static struct snd_kcontrol_new alc883_capture_mixer[] = {
8256 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
8257 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
8258 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
8259 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
8260 {
8261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8262 /* The multiple "Capture Source" controls confuse alsamixer
8263 * So call somewhat different..
8264 */
8265 /* .name = "Capture Source", */
8266 .name = "Input Source",
8267 .count = 2,
8268 .info = alc882_mux_enum_info,
8269 .get = alc882_mux_enum_get,
8270 .put = alc882_mux_enum_put,
8271 },
8272 { } /* end */
8273};
8274
8275static struct hda_verb alc888_asus_m90v_verbs[] = { 8313static struct hda_verb alc888_asus_m90v_verbs[] = {
8276 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8314 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8277 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 8315 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -8394,6 +8432,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
8394 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", 8432 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
8395 [ALC883_ACER] = "acer", 8433 [ALC883_ACER] = "acer",
8396 [ALC883_ACER_ASPIRE] = "acer-aspire", 8434 [ALC883_ACER_ASPIRE] = "acer-aspire",
8435 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
8397 [ALC883_MEDION] = "medion", 8436 [ALC883_MEDION] = "medion",
8398 [ALC883_MEDION_MD2] = "medion-md2", 8437 [ALC883_MEDION_MD2] = "medion-md2",
8399 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 8438 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
@@ -8407,7 +8446,9 @@ static const char *alc883_models[ALC883_MODEL_LAST] = {
8407 [ALC883_MITAC] = "mitac", 8446 [ALC883_MITAC] = "mitac",
8408 [ALC883_CLEVO_M720] = "clevo-m720", 8447 [ALC883_CLEVO_M720] = "clevo-m720",
8409 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", 8448 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
8449 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
8410 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel", 8450 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
8451 [ALC1200_ASUS_P5Q] = "asus-p5q",
8411 [ALC883_AUTO] = "auto", 8452 [ALC883_AUTO] = "auto",
8412}; 8453};
8413 8454
@@ -8418,6 +8459,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8418 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), 8459 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
8419 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), 8460 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
8420 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), 8461 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
8462 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
8463 ALC888_ACER_ASPIRE_4930G),
8421 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ 8464 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
8422 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), 8465 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
8423 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), 8466 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
@@ -8426,6 +8469,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8426 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), 8469 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
8427 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), 8470 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
8428 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), 8471 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
8472 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
8429 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), 8473 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
8430 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), 8474 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
8431 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), 8475 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
@@ -8452,6 +8496,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8452 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), 8496 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
8453 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), 8497 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
8454 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), 8498 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
8499 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
8455 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), 8500 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
8456 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), 8501 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
8457 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), 8502 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
@@ -8463,6 +8508,8 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
8463 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch), 8508 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
8464 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), 8509 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
8465 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515), 8510 SND_PCI_QUIRK(0x1734, 0x1108, "Fujitsu AMILO Pi2515", ALC883_FUJITSU_PI2515),
8511 SND_PCI_QUIRK(0x1734, 0x113d, "Fujitsu AMILO Xa3530",
8512 ALC888_FUJITSU_XA3530),
8466 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), 8513 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
8467 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8514 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
8468 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), 8515 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
@@ -8553,6 +8600,8 @@ static struct alc_config_preset alc883_presets[] = {
8553 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, 8600 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
8554 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8601 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8555 .dac_nids = alc883_dac_nids, 8602 .dac_nids = alc883_dac_nids,
8603 .adc_nids = alc883_adc_nids_alt,
8604 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8556 .dig_out_nid = ALC883_DIGOUT_NID, 8605 .dig_out_nid = ALC883_DIGOUT_NID,
8557 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8606 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8558 .channel_mode = alc883_3ST_2ch_modes, 8607 .channel_mode = alc883_3ST_2ch_modes,
@@ -8586,6 +8635,26 @@ static struct alc_config_preset alc883_presets[] = {
8586 .unsol_event = alc883_acer_aspire_unsol_event, 8635 .unsol_event = alc883_acer_aspire_unsol_event,
8587 .init_hook = alc883_acer_aspire_automute, 8636 .init_hook = alc883_acer_aspire_automute,
8588 }, 8637 },
8638 [ALC888_ACER_ASPIRE_4930G] = {
8639 .mixers = { alc888_base_mixer,
8640 alc883_chmode_mixer },
8641 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
8642 alc888_acer_aspire_4930g_verbs },
8643 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8644 .dac_nids = alc883_dac_nids,
8645 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8646 .adc_nids = alc883_adc_nids_rev,
8647 .capsrc_nids = alc883_capsrc_nids_rev,
8648 .dig_out_nid = ALC883_DIGOUT_NID,
8649 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
8650 .channel_mode = alc883_3ST_6ch_modes,
8651 .need_dac_fix = 1,
8652 .num_mux_defs =
8653 ARRAY_SIZE(alc888_2_capture_sources),
8654 .input_mux = alc888_2_capture_sources,
8655 .unsol_event = alc888_acer_aspire_4930g_unsol_event,
8656 .init_hook = alc888_acer_aspire_4930g_automute,
8657 },
8589 [ALC883_MEDION] = { 8658 [ALC883_MEDION] = {
8590 .mixers = { alc883_fivestack_mixer, 8659 .mixers = { alc883_fivestack_mixer,
8591 alc883_chmode_mixer }, 8660 alc883_chmode_mixer },
@@ -8593,6 +8662,8 @@ static struct alc_config_preset alc883_presets[] = {
8593 alc883_medion_eapd_verbs }, 8662 alc883_medion_eapd_verbs },
8594 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8663 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8595 .dac_nids = alc883_dac_nids, 8664 .dac_nids = alc883_dac_nids,
8665 .adc_nids = alc883_adc_nids_alt,
8666 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8596 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 8667 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8597 .channel_mode = alc883_sixstack_modes, 8668 .channel_mode = alc883_sixstack_modes,
8598 .input_mux = &alc883_capture_source, 8669 .input_mux = &alc883_capture_source,
@@ -8635,6 +8706,8 @@ static struct alc_config_preset alc883_presets[] = {
8635 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, 8706 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
8636 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8707 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8637 .dac_nids = alc883_dac_nids, 8708 .dac_nids = alc883_dac_nids,
8709 .adc_nids = alc883_adc_nids_alt,
8710 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
8638 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), 8711 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
8639 .channel_mode = alc883_3ST_2ch_modes, 8712 .channel_mode = alc883_3ST_2ch_modes,
8640 .input_mux = &alc883_lenovo_101e_capture_source, 8713 .input_mux = &alc883_lenovo_101e_capture_source,
@@ -8725,14 +8798,30 @@ static struct alc_config_preset alc883_presets[] = {
8725 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, 8798 .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event,
8726 .init_hook = alc883_2ch_fujitsu_pi2515_automute, 8799 .init_hook = alc883_2ch_fujitsu_pi2515_automute,
8727 }, 8800 },
8801 [ALC888_FUJITSU_XA3530] = {
8802 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
8803 .init_verbs = { alc883_init_verbs,
8804 alc888_fujitsu_xa3530_verbs },
8805 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8806 .dac_nids = alc883_dac_nids,
8807 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
8808 .adc_nids = alc883_adc_nids_rev,
8809 .capsrc_nids = alc883_capsrc_nids_rev,
8810 .dig_out_nid = ALC883_DIGOUT_NID,
8811 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
8812 .channel_mode = alc888_4ST_8ch_intel_modes,
8813 .num_mux_defs =
8814 ARRAY_SIZE(alc888_2_capture_sources),
8815 .input_mux = alc888_2_capture_sources,
8816 .unsol_event = alc888_fujitsu_xa3530_unsol_event,
8817 .init_hook = alc888_fujitsu_xa3530_automute,
8818 },
8728 [ALC888_LENOVO_SKY] = { 8819 [ALC888_LENOVO_SKY] = {
8729 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, 8820 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
8730 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, 8821 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
8731 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8822 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8732 .dac_nids = alc883_dac_nids, 8823 .dac_nids = alc883_dac_nids,
8733 .dig_out_nid = ALC883_DIGOUT_NID, 8824 .dig_out_nid = ALC883_DIGOUT_NID,
8734 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
8735 .adc_nids = alc883_adc_nids,
8736 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), 8825 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8737 .channel_mode = alc883_sixstack_modes, 8826 .channel_mode = alc883_sixstack_modes,
8738 .need_dac_fix = 1, 8827 .need_dac_fix = 1,
@@ -8756,6 +8845,7 @@ static struct alc_config_preset alc883_presets[] = {
8756 }, 8845 },
8757 [ALC888_ASUS_EEE1601] = { 8846 [ALC888_ASUS_EEE1601] = {
8758 .mixers = { alc883_asus_eee1601_mixer }, 8847 .mixers = { alc883_asus_eee1601_mixer },
8848 .cap_mixer = alc883_asus_eee1601_cap_mixer,
8759 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, 8849 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
8760 .num_dacs = ARRAY_SIZE(alc883_dac_nids), 8850 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8761 .dac_nids = alc883_dac_nids, 8851 .dac_nids = alc883_dac_nids,
@@ -8768,6 +8858,17 @@ static struct alc_config_preset alc883_presets[] = {
8768 .unsol_event = alc883_eee1601_unsol_event, 8858 .unsol_event = alc883_eee1601_unsol_event,
8769 .init_hook = alc883_eee1601_inithook, 8859 .init_hook = alc883_eee1601_inithook,
8770 }, 8860 },
8861 [ALC1200_ASUS_P5Q] = {
8862 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
8863 .init_verbs = { alc883_init_verbs },
8864 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
8865 .dac_nids = alc883_dac_nids,
8866 .dig_out_nid = ALC1200_DIGOUT_NID,
8867 .dig_in_nid = ALC883_DIGIN_NID,
8868 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
8869 .channel_mode = alc883_sixstack_modes,
8870 .input_mux = &alc883_capture_source,
8871 },
8771}; 8872};
8772 8873
8773 8874
@@ -8862,8 +8963,6 @@ static int alc883_parse_auto_config(struct hda_codec *codec)
8862 8963
8863 /* hack - override the init verbs */ 8964 /* hack - override the init verbs */
8864 spec->init_verbs[0] = alc883_auto_init_verbs; 8965 spec->init_verbs[0] = alc883_auto_init_verbs;
8865 spec->mixers[spec->num_mixers] = alc883_capture_mixer;
8866 spec->num_mixers++;
8867 8966
8868 return 1; /* config found */ 8967 return 1; /* config found */
8869} 8968}
@@ -8946,9 +9045,15 @@ static int patch_alc883(struct hda_codec *codec)
8946 spec->stream_digital_playback = &alc883_pcm_digital_playback; 9045 spec->stream_digital_playback = &alc883_pcm_digital_playback;
8947 spec->stream_digital_capture = &alc883_pcm_digital_capture; 9046 spec->stream_digital_capture = &alc883_pcm_digital_capture;
8948 9047
8949 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); 9048 if (!spec->num_adc_nids) {
8950 spec->adc_nids = alc883_adc_nids; 9049 spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids);
8951 spec->capsrc_nids = alc883_capsrc_nids; 9050 spec->adc_nids = alc883_adc_nids;
9051 }
9052 if (!spec->capsrc_nids)
9053 spec->capsrc_nids = alc883_capsrc_nids;
9054 spec->is_mix_capture = 1; /* matrix-style capture */
9055 if (!spec->cap_mixer)
9056 set_capture_mixer(spec);
8952 9057
8953 spec->vmaster_nid = 0x0c; 9058 spec->vmaster_nid = 0x0c;
8954 9059
@@ -8960,6 +9065,7 @@ static int patch_alc883(struct hda_codec *codec)
8960 if (!spec->loopback.amplist) 9065 if (!spec->loopback.amplist)
8961 spec->loopback.amplist = alc883_loopbacks; 9066 spec->loopback.amplist = alc883_loopbacks;
8962#endif 9067#endif
9068 codec->proc_widget_hook = print_realtek_coef;
8963 9069
8964 return 0; 9070 return 0;
8965} 9071}
@@ -9439,20 +9545,6 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
9439 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9545 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9546 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9441 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9547 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9442 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
9443 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
9444 {
9445 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9446 /* The multiple "Capture Source" controls confuse alsamixer
9447 * So call somewhat different..
9448 */
9449 /* .name = "Capture Source", */
9450 .name = "Input Source",
9451 .count = 1,
9452 .info = alc_mux_enum_info,
9453 .get = alc_mux_enum_get,
9454 .put = alc_mux_enum_put,
9455 },
9456 { } /* end */ 9548 { } /* end */
9457}; 9549};
9458 9550
@@ -9969,7 +10061,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
9969 struct alc_spec *spec = codec->spec; 10061 struct alc_spec *spec = codec->spec;
9970 int ret; 10062 int ret;
9971 10063
9972 ret = alc882_mux_enum_put(kcontrol, ucontrol); 10064 ret = alc_mux_enum_put(kcontrol, ucontrol);
9973 if (!ret) 10065 if (!ret)
9974 return 0; 10066 return 0;
9975 /* reprogram the HP pin as mic or HP according to the input source */ 10067 /* reprogram the HP pin as mic or HP according to the input source */
@@ -9986,8 +10078,8 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
9986 { 10078 {
9987 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 10079 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9988 .name = "Capture Source", 10080 .name = "Capture Source",
9989 .info = alc882_mux_enum_info, 10081 .info = alc_mux_enum_info,
9990 .get = alc882_mux_enum_get, 10082 .get = alc_mux_enum_get,
9991 .put = alc262_ultra_mux_enum_put, 10083 .put = alc262_ultra_mux_enum_put,
9992 }, 10084 },
9993 { } /* end */ 10085 { } /* end */
@@ -10380,10 +10472,10 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
10380 if (spec->autocfg.dig_in_pin) 10472 if (spec->autocfg.dig_in_pin)
10381 spec->dig_in_nid = ALC262_DIGIN_NID; 10473 spec->dig_in_nid = ALC262_DIGIN_NID;
10382 10474
10383 if (spec->kctl_alloc) 10475 if (spec->kctls.list)
10384 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 10476 add_mixer(spec, spec->kctls.list);
10385 10477
10386 spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; 10478 add_verb(spec, alc262_volume_init_verbs);
10387 spec->num_mux_defs = 1; 10479 spec->num_mux_defs = 1;
10388 spec->input_mux = &spec->private_imux; 10480 spec->input_mux = &spec->private_imux;
10389 10481
@@ -10466,6 +10558,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
10466 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10558 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10467 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), 10559 SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD),
10468 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), 10560 SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD),
10561 SND_PCI_QUIRK(0x104d, 0x9033, "Sony VAIO VGN-SR19XN",
10562 ALC262_SONY_ASSAMD),
10469 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", 10563 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
10470 ALC262_TOSHIBA_RX1), 10564 ALC262_TOSHIBA_RX1),
10471 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06), 10565 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
@@ -10624,7 +10718,8 @@ static struct alc_config_preset alc262_presets[] = {
10624 .init_hook = alc262_hippo_automute, 10718 .init_hook = alc262_hippo_automute,
10625 }, 10719 },
10626 [ALC262_ULTRA] = { 10720 [ALC262_ULTRA] = {
10627 .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer }, 10721 .mixers = { alc262_ultra_mixer },
10722 .cap_mixer = alc262_ultra_capture_mixer,
10628 .init_verbs = { alc262_ultra_verbs }, 10723 .init_verbs = { alc262_ultra_verbs },
10629 .num_dacs = ARRAY_SIZE(alc262_dac_nids), 10724 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
10630 .dac_nids = alc262_dac_nids, 10725 .dac_nids = alc262_dac_nids,
@@ -10750,6 +10845,7 @@ static int patch_alc262(struct hda_codec *codec)
10750 spec->stream_digital_playback = &alc262_pcm_digital_playback; 10845 spec->stream_digital_playback = &alc262_pcm_digital_playback;
10751 spec->stream_digital_capture = &alc262_pcm_digital_capture; 10846 spec->stream_digital_capture = &alc262_pcm_digital_capture;
10752 10847
10848 spec->is_mix_capture = 1;
10753 if (!spec->adc_nids && spec->input_mux) { 10849 if (!spec->adc_nids && spec->input_mux) {
10754 /* check whether NID 0x07 is valid */ 10850 /* check whether NID 0x07 is valid */
10755 unsigned int wcap = get_wcaps(codec, 0x07); 10851 unsigned int wcap = get_wcaps(codec, 0x07);
@@ -10760,17 +10856,14 @@ static int patch_alc262(struct hda_codec *codec)
10760 spec->adc_nids = alc262_adc_nids_alt; 10856 spec->adc_nids = alc262_adc_nids_alt;
10761 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); 10857 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt);
10762 spec->capsrc_nids = alc262_capsrc_nids_alt; 10858 spec->capsrc_nids = alc262_capsrc_nids_alt;
10763 spec->mixers[spec->num_mixers] =
10764 alc262_capture_alt_mixer;
10765 spec->num_mixers++;
10766 } else { 10859 } else {
10767 spec->adc_nids = alc262_adc_nids; 10860 spec->adc_nids = alc262_adc_nids;
10768 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids); 10861 spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids);
10769 spec->capsrc_nids = alc262_capsrc_nids; 10862 spec->capsrc_nids = alc262_capsrc_nids;
10770 spec->mixers[spec->num_mixers] = alc262_capture_mixer;
10771 spec->num_mixers++;
10772 } 10863 }
10773 } 10864 }
10865 if (!spec->cap_mixer)
10866 set_capture_mixer(spec);
10774 10867
10775 spec->vmaster_nid = 0x0c; 10868 spec->vmaster_nid = 0x0c;
10776 10869
@@ -10781,6 +10874,7 @@ static int patch_alc262(struct hda_codec *codec)
10781 if (!spec->loopback.amplist) 10874 if (!spec->loopback.amplist)
10782 spec->loopback.amplist = alc262_loopbacks; 10875 spec->loopback.amplist = alc262_loopbacks;
10783#endif 10876#endif
10877 codec->proc_widget_hook = print_realtek_coef;
10784 10878
10785 return 0; 10879 return 0;
10786} 10880}
@@ -10942,6 +11036,22 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
10942 { } 11036 { }
10943}; 11037};
10944 11038
11039static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
11040 /* output mixer control */
11041 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
11042 {
11043 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11044 .name = "Master Playback Switch",
11045 .info = snd_hda_mixer_amp_switch_info,
11046 .get = snd_hda_mixer_amp_switch_get,
11047 .put = alc268_acer_master_sw_put,
11048 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
11049 },
11050 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11051 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT),
11052 { }
11053};
11054
10945static struct hda_verb alc268_acer_aspire_one_verbs[] = { 11055static struct hda_verb alc268_acer_aspire_one_verbs[] = {
10946 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 11056 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
10947 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 11057 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
@@ -11218,10 +11328,6 @@ static struct hda_verb alc268_volume_init_verbs[] = {
11218 { } 11328 { }
11219}; 11329};
11220 11330
11221#define alc268_mux_enum_info alc_mux_enum_info
11222#define alc268_mux_enum_get alc_mux_enum_get
11223#define alc268_mux_enum_put alc_mux_enum_put
11224
11225static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { 11331static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11226 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), 11332 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
11227 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), 11333 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
@@ -11233,9 +11339,9 @@ static struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
11233 /* .name = "Capture Source", */ 11339 /* .name = "Capture Source", */
11234 .name = "Input Source", 11340 .name = "Input Source",
11235 .count = 1, 11341 .count = 1,
11236 .info = alc268_mux_enum_info, 11342 .info = alc_mux_enum_info,
11237 .get = alc268_mux_enum_get, 11343 .get = alc_mux_enum_get,
11238 .put = alc268_mux_enum_put, 11344 .put = alc_mux_enum_put,
11239 }, 11345 },
11240 { } /* end */ 11346 { } /* end */
11241}; 11347};
@@ -11253,9 +11359,9 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = {
11253 /* .name = "Capture Source", */ 11359 /* .name = "Capture Source", */
11254 .name = "Input Source", 11360 .name = "Input Source",
11255 .count = 2, 11361 .count = 2,
11256 .info = alc268_mux_enum_info, 11362 .info = alc_mux_enum_info,
11257 .get = alc268_mux_enum_get, 11363 .get = alc_mux_enum_get,
11258 .put = alc268_mux_enum_put, 11364 .put = alc_mux_enum_put,
11259 }, 11365 },
11260 { } /* end */ 11366 { } /* end */
11261}; 11367};
@@ -11274,6 +11380,15 @@ static struct hda_input_mux alc268_acer_capture_source = {
11274 .num_items = 3, 11380 .num_items = 3,
11275 .items = { 11381 .items = {
11276 { "Mic", 0x0 }, 11382 { "Mic", 0x0 },
11383 { "Internal Mic", 0x1 },
11384 { "Line", 0x2 },
11385 },
11386};
11387
11388static struct hda_input_mux alc268_acer_dmic_capture_source = {
11389 .num_items = 3,
11390 .items = {
11391 { "Mic", 0x0 },
11277 { "Internal Mic", 0x6 }, 11392 { "Internal Mic", 0x6 },
11278 { "Line", 0x2 }, 11393 { "Line", 0x2 },
11279 }, 11394 },
@@ -11512,13 +11627,13 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
11512 if (spec->autocfg.dig_out_pin) 11627 if (spec->autocfg.dig_out_pin)
11513 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; 11628 spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
11514 11629
11515 if (spec->kctl_alloc) 11630 if (spec->kctls.list)
11516 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 11631 add_mixer(spec, spec->kctls.list);
11517 11632
11518 if (spec->autocfg.speaker_pins[0] != 0x1d) 11633 if (spec->autocfg.speaker_pins[0] != 0x1d)
11519 spec->mixers[spec->num_mixers++] = alc268_beep_mixer; 11634 add_mixer(spec, alc268_beep_mixer);
11520 11635
11521 spec->init_verbs[spec->num_init_verbs++] = alc268_volume_init_verbs; 11636 add_verb(spec, alc268_volume_init_verbs);
11522 spec->num_mux_defs = 1; 11637 spec->num_mux_defs = 1;
11523 spec->input_mux = &spec->private_imux; 11638 spec->input_mux = &spec->private_imux;
11524 11639
@@ -11554,6 +11669,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = {
11554 [ALC268_3ST] = "3stack", 11669 [ALC268_3ST] = "3stack",
11555 [ALC268_TOSHIBA] = "toshiba", 11670 [ALC268_TOSHIBA] = "toshiba",
11556 [ALC268_ACER] = "acer", 11671 [ALC268_ACER] = "acer",
11672 [ALC268_ACER_DMIC] = "acer-dmic",
11557 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", 11673 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
11558 [ALC268_DELL] = "dell", 11674 [ALC268_DELL] = "dell",
11559 [ALC268_ZEPTO] = "zepto", 11675 [ALC268_ZEPTO] = "zepto",
@@ -11649,6 +11765,23 @@ static struct alc_config_preset alc268_presets[] = {
11649 .unsol_event = alc268_acer_unsol_event, 11765 .unsol_event = alc268_acer_unsol_event,
11650 .init_hook = alc268_acer_init_hook, 11766 .init_hook = alc268_acer_init_hook,
11651 }, 11767 },
11768 [ALC268_ACER_DMIC] = {
11769 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
11770 alc268_beep_mixer },
11771 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
11772 alc268_acer_verbs },
11773 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
11774 .dac_nids = alc268_dac_nids,
11775 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
11776 .adc_nids = alc268_adc_nids_alt,
11777 .capsrc_nids = alc268_capsrc_nids,
11778 .hp_nid = 0x02,
11779 .num_channel_mode = ARRAY_SIZE(alc268_modes),
11780 .channel_mode = alc268_modes,
11781 .input_mux = &alc268_acer_dmic_capture_source,
11782 .unsol_event = alc268_acer_unsol_event,
11783 .init_hook = alc268_acer_init_hook,
11784 },
11652 [ALC268_ACER_ASPIRE_ONE] = { 11785 [ALC268_ACER_ASPIRE_ONE] = {
11653 .mixers = { alc268_acer_aspire_one_mixer, 11786 .mixers = { alc268_acer_aspire_one_mixer,
11654 alc268_capture_alt_mixer }, 11787 alc268_capture_alt_mixer },
@@ -11787,15 +11920,11 @@ static int patch_alc268(struct hda_codec *codec)
11787 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { 11920 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
11788 spec->adc_nids = alc268_adc_nids_alt; 11921 spec->adc_nids = alc268_adc_nids_alt;
11789 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); 11922 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
11790 spec->mixers[spec->num_mixers] = 11923 add_mixer(spec, alc268_capture_alt_mixer);
11791 alc268_capture_alt_mixer;
11792 spec->num_mixers++;
11793 } else { 11924 } else {
11794 spec->adc_nids = alc268_adc_nids; 11925 spec->adc_nids = alc268_adc_nids;
11795 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids); 11926 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
11796 spec->mixers[spec->num_mixers] = 11927 add_mixer(spec, alc268_capture_mixer);
11797 alc268_capture_mixer;
11798 spec->num_mixers++;
11799 } 11928 }
11800 spec->capsrc_nids = alc268_capsrc_nids; 11929 spec->capsrc_nids = alc268_capsrc_nids;
11801 /* set default input source */ 11930 /* set default input source */
@@ -11811,6 +11940,8 @@ static int patch_alc268(struct hda_codec *codec)
11811 if (board_config == ALC268_AUTO) 11940 if (board_config == ALC268_AUTO)
11812 spec->init_hook = alc268_auto_init; 11941 spec->init_hook = alc268_auto_init;
11813 11942
11943 codec->proc_widget_hook = print_realtek_coef;
11944
11814 return 0; 11945 return 0;
11815} 11946}
11816 11947
@@ -11893,6 +12024,31 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
11893 { } 12024 { }
11894}; 12025};
11895 12026
12027static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
12028 /* output mixer control */
12029 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12030 {
12031 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12032 .name = "Master Playback Switch",
12033 .info = snd_hda_mixer_amp_switch_info,
12034 .get = snd_hda_mixer_amp_switch_get,
12035 .put = alc268_acer_master_sw_put,
12036 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
12037 },
12038 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12039 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12040 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
12041 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12042 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12043 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT),
12044 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
12045 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
12046 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT),
12047 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT),
12048 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT),
12049 { }
12050};
12051
11896/* bind volumes of both NID 0x0c and 0x0d */ 12052/* bind volumes of both NID 0x0c and 0x0d */
11897static struct hda_bind_ctls alc269_epc_bind_vol = { 12053static struct hda_bind_ctls alc269_epc_bind_vol = {
11898 .ops = &snd_hda_bind_vol, 12054 .ops = &snd_hda_bind_vol,
@@ -11911,28 +12067,18 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = {
11911}; 12067};
11912 12068
11913/* capture mixer elements */ 12069/* capture mixer elements */
11914static struct snd_kcontrol_new alc269_capture_mixer[] = { 12070static struct snd_kcontrol_new alc269_epc_capture_mixer[] = {
11915 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 12071 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
11916 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 12072 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
11917 { 12073 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
11918 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11919 /* The multiple "Capture Source" controls confuse alsamixer
11920 * So call somewhat different..
11921 */
11922 /* .name = "Capture Source", */
11923 .name = "Input Source",
11924 .count = 1,
11925 .info = alc_mux_enum_info,
11926 .get = alc_mux_enum_get,
11927 .put = alc_mux_enum_put,
11928 },
11929 { } /* end */ 12074 { } /* end */
11930}; 12075};
11931 12076
11932/* capture mixer elements */ 12077/* FSC amilo */
11933static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { 12078static struct snd_kcontrol_new alc269_fujitsu_mixer[] = {
11934 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 12079 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11935 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 12080 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12081 HDA_BIND_VOL("PCM Playback Volume", &alc269_epc_bind_vol),
11936 { } /* end */ 12082 { } /* end */
11937}; 12083};
11938 12084
@@ -11953,6 +12099,20 @@ static struct hda_verb alc269_quanta_fl1_verbs[] = {
11953 { } 12099 { }
11954}; 12100};
11955 12101
12102static struct hda_verb alc269_lifebook_verbs[] = {
12103 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12104 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
12105 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12106 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12107 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12108 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12109 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12110 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12111 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12112 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12113 { }
12114};
12115
11956/* toggle speaker-output according to the hp-jack state */ 12116/* toggle speaker-output according to the hp-jack state */
11957static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) 12117static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11958{ 12118{
@@ -11978,6 +12138,37 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
11978 AC_VERB_SET_PROC_COEF, 0x480); 12138 AC_VERB_SET_PROC_COEF, 0x480);
11979} 12139}
11980 12140
12141/* toggle speaker-output according to the hp-jacks state */
12142static void alc269_lifebook_speaker_automute(struct hda_codec *codec)
12143{
12144 unsigned int present;
12145 unsigned char bits;
12146
12147 /* Check laptop headphone socket */
12148 present = snd_hda_codec_read(codec, 0x15, 0,
12149 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12150
12151 /* Check port replicator headphone socket */
12152 present |= snd_hda_codec_read(codec, 0x1a, 0,
12153 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12154
12155 bits = present ? AMP_IN_MUTE(0) : 0;
12156 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0,
12157 AMP_IN_MUTE(0), bits);
12158 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1,
12159 AMP_IN_MUTE(0), bits);
12160
12161 snd_hda_codec_write(codec, 0x20, 0,
12162 AC_VERB_SET_COEF_INDEX, 0x0c);
12163 snd_hda_codec_write(codec, 0x20, 0,
12164 AC_VERB_SET_PROC_COEF, 0x680);
12165
12166 snd_hda_codec_write(codec, 0x20, 0,
12167 AC_VERB_SET_COEF_INDEX, 0x0c);
12168 snd_hda_codec_write(codec, 0x20, 0,
12169 AC_VERB_SET_PROC_COEF, 0x480);
12170}
12171
11981static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec) 12172static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11982{ 12173{
11983 unsigned int present; 12174 unsigned int present;
@@ -11988,6 +12179,29 @@ static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec)
11988 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1); 12179 AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1);
11989} 12180}
11990 12181
12182static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
12183{
12184 unsigned int present_laptop;
12185 unsigned int present_dock;
12186
12187 present_laptop = snd_hda_codec_read(codec, 0x18, 0,
12188 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12189
12190 present_dock = snd_hda_codec_read(codec, 0x1b, 0,
12191 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
12192
12193 /* Laptop mic port overrides dock mic port, design decision */
12194 if (present_dock)
12195 snd_hda_codec_write(codec, 0x23, 0,
12196 AC_VERB_SET_CONNECT_SEL, 0x3);
12197 if (present_laptop)
12198 snd_hda_codec_write(codec, 0x23, 0,
12199 AC_VERB_SET_CONNECT_SEL, 0x0);
12200 if (!present_dock && !present_laptop)
12201 snd_hda_codec_write(codec, 0x23, 0,
12202 AC_VERB_SET_CONNECT_SEL, 0x1);
12203}
12204
11991static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, 12205static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11992 unsigned int res) 12206 unsigned int res)
11993{ 12207{
@@ -11997,12 +12211,27 @@ static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
11997 alc269_quanta_fl1_mic_automute(codec); 12211 alc269_quanta_fl1_mic_automute(codec);
11998} 12212}
11999 12213
12214static void alc269_lifebook_unsol_event(struct hda_codec *codec,
12215 unsigned int res)
12216{
12217 if ((res >> 26) == ALC880_HP_EVENT)
12218 alc269_lifebook_speaker_automute(codec);
12219 if ((res >> 26) == ALC880_MIC_EVENT)
12220 alc269_lifebook_mic_autoswitch(codec);
12221}
12222
12000static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) 12223static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
12001{ 12224{
12002 alc269_quanta_fl1_speaker_automute(codec); 12225 alc269_quanta_fl1_speaker_automute(codec);
12003 alc269_quanta_fl1_mic_automute(codec); 12226 alc269_quanta_fl1_mic_automute(codec);
12004} 12227}
12005 12228
12229static void alc269_lifebook_init_hook(struct hda_codec *codec)
12230{
12231 alc269_lifebook_speaker_automute(codec);
12232 alc269_lifebook_mic_autoswitch(codec);
12233}
12234
12006static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { 12235static struct hda_verb alc269_eeepc_dmic_init_verbs[] = {
12007 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, 12236 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12008 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, 12237 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
@@ -12303,17 +12532,17 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
12303 if (spec->autocfg.dig_out_pin) 12532 if (spec->autocfg.dig_out_pin)
12304 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; 12533 spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
12305 12534
12306 if (spec->kctl_alloc) 12535 if (spec->kctls.list)
12307 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 12536 add_mixer(spec, spec->kctls.list);
12308 12537
12309 /* create a beep mixer control if the pin 0x1d isn't assigned */ 12538 /* create a beep mixer control if the pin 0x1d isn't assigned */
12310 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++) 12539 for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++)
12311 if (spec->autocfg.input_pins[i] == 0x1d) 12540 if (spec->autocfg.input_pins[i] == 0x1d)
12312 break; 12541 break;
12313 if (i >= ARRAY_SIZE(spec->autocfg.input_pins)) 12542 if (i >= ARRAY_SIZE(spec->autocfg.input_pins))
12314 spec->mixers[spec->num_mixers++] = alc269_beep_mixer; 12543 add_mixer(spec, alc269_beep_mixer);
12315 12544
12316 spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs; 12545 add_verb(spec, alc269_init_verbs);
12317 spec->num_mux_defs = 1; 12546 spec->num_mux_defs = 1;
12318 spec->input_mux = &spec->private_imux; 12547 spec->input_mux = &spec->private_imux;
12319 /* set default input source */ 12548 /* set default input source */
@@ -12325,8 +12554,8 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
12325 if (err < 0) 12554 if (err < 0)
12326 return err; 12555 return err;
12327 12556
12328 spec->mixers[spec->num_mixers] = alc269_capture_mixer; 12557 if (!spec->cap_mixer)
12329 spec->num_mixers++; 12558 set_capture_mixer(spec);
12330 12559
12331 store_pin_configs(codec); 12560 store_pin_configs(codec);
12332 return 1; 12561 return 1;
@@ -12355,7 +12584,9 @@ static const char *alc269_models[ALC269_MODEL_LAST] = {
12355 [ALC269_BASIC] = "basic", 12584 [ALC269_BASIC] = "basic",
12356 [ALC269_QUANTA_FL1] = "quanta", 12585 [ALC269_QUANTA_FL1] = "quanta",
12357 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", 12586 [ALC269_ASUS_EEEPC_P703] = "eeepc-p703",
12358 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901" 12587 [ALC269_ASUS_EEEPC_P901] = "eeepc-p901",
12588 [ALC269_FUJITSU] = "fujitsu",
12589 [ALC269_LIFEBOOK] = "lifebook"
12359}; 12590};
12360 12591
12361static struct snd_pci_quirk alc269_cfg_tbl[] = { 12592static struct snd_pci_quirk alc269_cfg_tbl[] = {
@@ -12366,12 +12597,14 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = {
12366 ALC269_ASUS_EEEPC_P901), 12597 ALC269_ASUS_EEEPC_P901),
12367 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", 12598 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
12368 ALC269_ASUS_EEEPC_P901), 12599 ALC269_ASUS_EEEPC_P901),
12600 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
12601 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
12369 {} 12602 {}
12370}; 12603};
12371 12604
12372static struct alc_config_preset alc269_presets[] = { 12605static struct alc_config_preset alc269_presets[] = {
12373 [ALC269_BASIC] = { 12606 [ALC269_BASIC] = {
12374 .mixers = { alc269_base_mixer, alc269_capture_mixer }, 12607 .mixers = { alc269_base_mixer },
12375 .init_verbs = { alc269_init_verbs }, 12608 .init_verbs = { alc269_init_verbs },
12376 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12609 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12377 .dac_nids = alc269_dac_nids, 12610 .dac_nids = alc269_dac_nids,
@@ -12393,7 +12626,8 @@ static struct alc_config_preset alc269_presets[] = {
12393 .init_hook = alc269_quanta_fl1_init_hook, 12626 .init_hook = alc269_quanta_fl1_init_hook,
12394 }, 12627 },
12395 [ALC269_ASUS_EEEPC_P703] = { 12628 [ALC269_ASUS_EEEPC_P703] = {
12396 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer }, 12629 .mixers = { alc269_eeepc_mixer },
12630 .cap_mixer = alc269_epc_capture_mixer,
12397 .init_verbs = { alc269_init_verbs, 12631 .init_verbs = { alc269_init_verbs,
12398 alc269_eeepc_amic_init_verbs }, 12632 alc269_eeepc_amic_init_verbs },
12399 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12633 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
@@ -12406,7 +12640,8 @@ static struct alc_config_preset alc269_presets[] = {
12406 .init_hook = alc269_eeepc_amic_inithook, 12640 .init_hook = alc269_eeepc_amic_inithook,
12407 }, 12641 },
12408 [ALC269_ASUS_EEEPC_P901] = { 12642 [ALC269_ASUS_EEEPC_P901] = {
12409 .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer}, 12643 .mixers = { alc269_eeepc_mixer },
12644 .cap_mixer = alc269_epc_capture_mixer,
12410 .init_verbs = { alc269_init_verbs, 12645 .init_verbs = { alc269_init_verbs,
12411 alc269_eeepc_dmic_init_verbs }, 12646 alc269_eeepc_dmic_init_verbs },
12412 .num_dacs = ARRAY_SIZE(alc269_dac_nids), 12647 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
@@ -12418,6 +12653,32 @@ static struct alc_config_preset alc269_presets[] = {
12418 .unsol_event = alc269_eeepc_dmic_unsol_event, 12653 .unsol_event = alc269_eeepc_dmic_unsol_event,
12419 .init_hook = alc269_eeepc_dmic_inithook, 12654 .init_hook = alc269_eeepc_dmic_inithook,
12420 }, 12655 },
12656 [ALC269_FUJITSU] = {
12657 .mixers = { alc269_fujitsu_mixer, alc269_beep_mixer },
12658 .cap_mixer = alc269_epc_capture_mixer,
12659 .init_verbs = { alc269_init_verbs,
12660 alc269_eeepc_dmic_init_verbs },
12661 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12662 .dac_nids = alc269_dac_nids,
12663 .hp_nid = 0x03,
12664 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12665 .channel_mode = alc269_modes,
12666 .input_mux = &alc269_eeepc_dmic_capture_source,
12667 .unsol_event = alc269_eeepc_dmic_unsol_event,
12668 .init_hook = alc269_eeepc_dmic_inithook,
12669 },
12670 [ALC269_LIFEBOOK] = {
12671 .mixers = { alc269_lifebook_mixer },
12672 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
12673 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
12674 .dac_nids = alc269_dac_nids,
12675 .hp_nid = 0x03,
12676 .num_channel_mode = ARRAY_SIZE(alc269_modes),
12677 .channel_mode = alc269_modes,
12678 .input_mux = &alc269_capture_source,
12679 .unsol_event = alc269_lifebook_unsol_event,
12680 .init_hook = alc269_lifebook_init_hook,
12681 },
12421}; 12682};
12422 12683
12423static int patch_alc269(struct hda_codec *codec) 12684static int patch_alc269(struct hda_codec *codec)
@@ -12472,6 +12733,8 @@ static int patch_alc269(struct hda_codec *codec)
12472 spec->adc_nids = alc269_adc_nids; 12733 spec->adc_nids = alc269_adc_nids;
12473 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); 12734 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
12474 spec->capsrc_nids = alc269_capsrc_nids; 12735 spec->capsrc_nids = alc269_capsrc_nids;
12736 if (!spec->cap_mixer)
12737 set_capture_mixer(spec);
12475 12738
12476 codec->patch_ops = alc_patch_ops; 12739 codec->patch_ops = alc_patch_ops;
12477 if (board_config == ALC269_AUTO) 12740 if (board_config == ALC269_AUTO)
@@ -12480,6 +12743,7 @@ static int patch_alc269(struct hda_codec *codec)
12480 if (!spec->loopback.amplist) 12743 if (!spec->loopback.amplist)
12481 spec->loopback.amplist = alc269_loopbacks; 12744 spec->loopback.amplist = alc269_loopbacks;
12482#endif 12745#endif
12746 codec->proc_widget_hook = print_realtek_coef;
12483 12747
12484 return 0; 12748 return 0;
12485} 12749}
@@ -12612,17 +12876,6 @@ static struct snd_kcontrol_new alc861_base_mixer[] = {
12612 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12876 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12613 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 12877 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12614 12878
12615 /* Capture mixer control */
12616 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12617 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12618 {
12619 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12620 .name = "Capture Source",
12621 .count = 1,
12622 .info = alc_mux_enum_info,
12623 .get = alc_mux_enum_get,
12624 .put = alc_mux_enum_put,
12625 },
12626 { } /* end */ 12879 { } /* end */
12627}; 12880};
12628 12881
@@ -12646,17 +12899,6 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {
12646 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12899 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12647 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 12900 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12648 12901
12649 /* Capture mixer control */
12650 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12651 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12652 {
12653 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12654 .name = "Capture Source",
12655 .count = 1,
12656 .info = alc_mux_enum_info,
12657 .get = alc_mux_enum_get,
12658 .put = alc_mux_enum_put,
12659 },
12660 { 12902 {
12661 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12662 .name = "Channel Mode", 12904 .name = "Channel Mode",
@@ -12674,18 +12916,6 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
12674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), 12916 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
12675 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), 12917 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
12676 12918
12677 /*Capture mixer control */
12678 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12679 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12680 {
12681 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12682 .name = "Capture Source",
12683 .count = 1,
12684 .info = alc_mux_enum_info,
12685 .get = alc_mux_enum_get,
12686 .put = alc_mux_enum_put,
12687 },
12688
12689 { } /* end */ 12919 { } /* end */
12690}; 12920};
12691 12921
@@ -12709,17 +12939,6 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
12709 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12939 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12710 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), 12940 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
12711 12941
12712 /* Capture mixer control */
12713 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12714 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12715 {
12716 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12717 .name = "Capture Source",
12718 .count = 1,
12719 .info = alc_mux_enum_info,
12720 .get = alc_mux_enum_get,
12721 .put = alc_mux_enum_put,
12722 },
12723 { 12942 {
12724 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12943 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12725 .name = "Channel Mode", 12944 .name = "Channel Mode",
@@ -12751,17 +12970,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = {
12751 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), 12970 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
12752 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), 12971 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
12753 12972
12754 /* Capture mixer control */
12755 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
12756 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
12757 {
12758 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12759 .name = "Capture Source",
12760 .count = 1,
12761 .info = alc_mux_enum_info,
12762 .get = alc_mux_enum_get,
12763 .put = alc_mux_enum_put,
12764 },
12765 { 12973 {
12766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12974 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12767 .name = "Channel Mode", 12975 .name = "Channel Mode",
@@ -13293,25 +13501,6 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec,
13293 return 0; 13501 return 0;
13294} 13502}
13295 13503
13296static struct snd_kcontrol_new alc861_capture_mixer[] = {
13297 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13298 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13299
13300 {
13301 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13302 /* The multiple "Capture Source" controls confuse alsamixer
13303 * So call somewhat different..
13304 */
13305 /* .name = "Capture Source", */
13306 .name = "Input Source",
13307 .count = 1,
13308 .info = alc_mux_enum_info,
13309 .get = alc_mux_enum_get,
13310 .put = alc_mux_enum_put,
13311 },
13312 { } /* end */
13313};
13314
13315static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, 13504static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
13316 hda_nid_t nid, 13505 hda_nid_t nid,
13317 int pin_type, int dac_idx) 13506 int pin_type, int dac_idx)
@@ -13402,18 +13591,17 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
13402 if (spec->autocfg.dig_out_pin) 13591 if (spec->autocfg.dig_out_pin)
13403 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; 13592 spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
13404 13593
13405 if (spec->kctl_alloc) 13594 if (spec->kctls.list)
13406 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 13595 add_mixer(spec, spec->kctls.list);
13407 13596
13408 spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; 13597 add_verb(spec, alc861_auto_init_verbs);
13409 13598
13410 spec->num_mux_defs = 1; 13599 spec->num_mux_defs = 1;
13411 spec->input_mux = &spec->private_imux; 13600 spec->input_mux = &spec->private_imux;
13412 13601
13413 spec->adc_nids = alc861_adc_nids; 13602 spec->adc_nids = alc861_adc_nids;
13414 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 13603 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
13415 spec->mixers[spec->num_mixers] = alc861_capture_mixer; 13604 set_capture_mixer(spec);
13416 spec->num_mixers++;
13417 13605
13418 store_pin_configs(codec); 13606 store_pin_configs(codec);
13419 return 1; 13607 return 1;
@@ -13644,6 +13832,7 @@ static int patch_alc861(struct hda_codec *codec)
13644 if (!spec->loopback.amplist) 13832 if (!spec->loopback.amplist)
13645 spec->loopback.amplist = alc861_loopbacks; 13833 spec->loopback.amplist = alc861_loopbacks;
13646#endif 13834#endif
13835 codec->proc_widget_hook = print_realtek_coef;
13647 13836
13648 return 0; 13837 return 0;
13649} 13838}
@@ -13709,11 +13898,6 @@ static struct hda_input_mux alc861vd_hp_capture_source = {
13709 }, 13898 },
13710}; 13899};
13711 13900
13712#define alc861vd_mux_enum_info alc_mux_enum_info
13713#define alc861vd_mux_enum_get alc_mux_enum_get
13714/* ALC861VD has the ALC882-type input selection (but has only one ADC) */
13715#define alc861vd_mux_enum_put alc882_mux_enum_put
13716
13717/* 13901/*
13718 * 2ch mode 13902 * 2ch mode
13719 */ 13903 */
@@ -13759,25 +13943,6 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
13759 { } /* end */ 13943 { } /* end */
13760}; 13944};
13761 13945
13762static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
13763 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13764 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13765
13766 {
13767 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13768 /* The multiple "Capture Source" controls confuse alsamixer
13769 * So call somewhat different..
13770 */
13771 /* .name = "Capture Source", */
13772 .name = "Input Source",
13773 .count = 1,
13774 .info = alc861vd_mux_enum_info,
13775 .get = alc861vd_mux_enum_get,
13776 .put = alc861vd_mux_enum_put,
13777 },
13778 { } /* end */
13779};
13780
13781/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 13946/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
13782 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 13947 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
13783 */ 13948 */
@@ -14169,6 +14334,7 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re
14169static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 14334static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
14170 [ALC660VD_3ST] = "3stack-660", 14335 [ALC660VD_3ST] = "3stack-660",
14171 [ALC660VD_3ST_DIG] = "3stack-660-digout", 14336 [ALC660VD_3ST_DIG] = "3stack-660-digout",
14337 [ALC660VD_ASUS_V1S] = "asus-v1s",
14172 [ALC861VD_3ST] = "3stack", 14338 [ALC861VD_3ST] = "3stack",
14173 [ALC861VD_3ST_DIG] = "3stack-digout", 14339 [ALC861VD_3ST_DIG] = "3stack-digout",
14174 [ALC861VD_6ST_DIG] = "6stack-digout", 14340 [ALC861VD_6ST_DIG] = "6stack-digout",
@@ -14183,7 +14349,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
14183 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), 14349 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
14184 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), 14350 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
14185 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), 14351 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
14186 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC861VD_LENOVO), 14352 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
14187 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), 14353 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
14188 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), 14354 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
14189 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), 14355 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
@@ -14290,6 +14456,21 @@ static struct alc_config_preset alc861vd_presets[] = {
14290 .unsol_event = alc861vd_dallas_unsol_event, 14456 .unsol_event = alc861vd_dallas_unsol_event,
14291 .init_hook = alc861vd_dallas_automute, 14457 .init_hook = alc861vd_dallas_automute,
14292 }, 14458 },
14459 [ALC660VD_ASUS_V1S] = {
14460 .mixers = { alc861vd_lenovo_mixer },
14461 .init_verbs = { alc861vd_volume_init_verbs,
14462 alc861vd_3stack_init_verbs,
14463 alc861vd_eapd_verbs,
14464 alc861vd_lenovo_unsol_verbs },
14465 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
14466 .dac_nids = alc660vd_dac_nids,
14467 .dig_out_nid = ALC861VD_DIGOUT_NID,
14468 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
14469 .channel_mode = alc861vd_3stack_2ch_modes,
14470 .input_mux = &alc861vd_capture_source,
14471 .unsol_event = alc861vd_lenovo_unsol_event,
14472 .init_hook = alc861vd_lenovo_automute,
14473 },
14293}; 14474};
14294 14475
14295/* 14476/*
@@ -14514,11 +14695,10 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
14514 if (spec->autocfg.dig_out_pin) 14695 if (spec->autocfg.dig_out_pin)
14515 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; 14696 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
14516 14697
14517 if (spec->kctl_alloc) 14698 if (spec->kctls.list)
14518 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 14699 add_mixer(spec, spec->kctls.list);
14519 14700
14520 spec->init_verbs[spec->num_init_verbs++] 14701 add_verb(spec, alc861vd_volume_init_verbs);
14521 = alc861vd_volume_init_verbs;
14522 14702
14523 spec->num_mux_defs = 1; 14703 spec->num_mux_defs = 1;
14524 spec->input_mux = &spec->private_imux; 14704 spec->input_mux = &spec->private_imux;
@@ -14585,7 +14765,7 @@ static int patch_alc861vd(struct hda_codec *codec)
14585 spec->stream_name_analog = "ALC660-VD Analog"; 14765 spec->stream_name_analog = "ALC660-VD Analog";
14586 spec->stream_name_digital = "ALC660-VD Digital"; 14766 spec->stream_name_digital = "ALC660-VD Digital";
14587 /* always turn on EAPD */ 14767 /* always turn on EAPD */
14588 spec->init_verbs[spec->num_init_verbs++] = alc660vd_eapd_verbs; 14768 add_verb(spec, alc660vd_eapd_verbs);
14589 } else { 14769 } else {
14590 spec->stream_name_analog = "ALC861VD Analog"; 14770 spec->stream_name_analog = "ALC861VD Analog";
14591 spec->stream_name_digital = "ALC861VD Digital"; 14771 spec->stream_name_digital = "ALC861VD Digital";
@@ -14600,9 +14780,9 @@ static int patch_alc861vd(struct hda_codec *codec)
14600 spec->adc_nids = alc861vd_adc_nids; 14780 spec->adc_nids = alc861vd_adc_nids;
14601 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); 14781 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
14602 spec->capsrc_nids = alc861vd_capsrc_nids; 14782 spec->capsrc_nids = alc861vd_capsrc_nids;
14783 spec->is_mix_capture = 1;
14603 14784
14604 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer; 14785 set_capture_mixer(spec);
14605 spec->num_mixers++;
14606 14786
14607 spec->vmaster_nid = 0x02; 14787 spec->vmaster_nid = 0x02;
14608 14788
@@ -14614,6 +14794,7 @@ static int patch_alc861vd(struct hda_codec *codec)
14614 if (!spec->loopback.amplist) 14794 if (!spec->loopback.amplist)
14615 spec->loopback.amplist = alc861vd_loopbacks; 14795 spec->loopback.amplist = alc861vd_loopbacks;
14616#endif 14796#endif
14797 codec->proc_widget_hook = print_realtek_coef;
14617 14798
14618 return 0; 14799 return 0;
14619} 14800}
@@ -14689,10 +14870,6 @@ static struct hda_input_mux alc663_m51va_capture_source = {
14689 }, 14870 },
14690}; 14871};
14691 14872
14692#define alc662_mux_enum_info alc_mux_enum_info
14693#define alc662_mux_enum_get alc_mux_enum_get
14694#define alc662_mux_enum_put alc882_mux_enum_put
14695
14696/* 14873/*
14697 * 2ch mode 14874 * 2ch mode
14698 */ 14875 */
@@ -15278,25 +15455,6 @@ static struct hda_verb alc662_ecs_init_verbs[] = {
15278 {} 15455 {}
15279}; 15456};
15280 15457
15281/* capture mixer elements */
15282static struct snd_kcontrol_new alc662_capture_mixer[] = {
15283 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15284 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
15285 {
15286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15287 /* The multiple "Capture Source" controls confuse alsamixer
15288 * So call somewhat different..
15289 */
15290 /* .name = "Capture Source", */
15291 .name = "Input Source",
15292 .count = 1,
15293 .info = alc662_mux_enum_info,
15294 .get = alc662_mux_enum_get,
15295 .put = alc662_mux_enum_put,
15296 },
15297 { } /* end */
15298};
15299
15300static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { 15458static struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
15301 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 15459 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
15302 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 15460 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
@@ -15868,7 +16026,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = {
15868 16026
15869static struct alc_config_preset alc662_presets[] = { 16027static struct alc_config_preset alc662_presets[] = {
15870 [ALC662_3ST_2ch_DIG] = { 16028 [ALC662_3ST_2ch_DIG] = {
15871 .mixers = { alc662_3ST_2ch_mixer, alc662_capture_mixer }, 16029 .mixers = { alc662_3ST_2ch_mixer },
15872 .init_verbs = { alc662_init_verbs }, 16030 .init_verbs = { alc662_init_verbs },
15873 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16031 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15874 .dac_nids = alc662_dac_nids, 16032 .dac_nids = alc662_dac_nids,
@@ -15879,8 +16037,7 @@ static struct alc_config_preset alc662_presets[] = {
15879 .input_mux = &alc662_capture_source, 16037 .input_mux = &alc662_capture_source,
15880 }, 16038 },
15881 [ALC662_3ST_6ch_DIG] = { 16039 [ALC662_3ST_6ch_DIG] = {
15882 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer, 16040 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15883 alc662_capture_mixer },
15884 .init_verbs = { alc662_init_verbs }, 16041 .init_verbs = { alc662_init_verbs },
15885 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16042 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15886 .dac_nids = alc662_dac_nids, 16043 .dac_nids = alc662_dac_nids,
@@ -15892,8 +16049,7 @@ static struct alc_config_preset alc662_presets[] = {
15892 .input_mux = &alc662_capture_source, 16049 .input_mux = &alc662_capture_source,
15893 }, 16050 },
15894 [ALC662_3ST_6ch] = { 16051 [ALC662_3ST_6ch] = {
15895 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer, 16052 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
15896 alc662_capture_mixer },
15897 .init_verbs = { alc662_init_verbs }, 16053 .init_verbs = { alc662_init_verbs },
15898 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16054 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15899 .dac_nids = alc662_dac_nids, 16055 .dac_nids = alc662_dac_nids,
@@ -15903,8 +16059,7 @@ static struct alc_config_preset alc662_presets[] = {
15903 .input_mux = &alc662_capture_source, 16059 .input_mux = &alc662_capture_source,
15904 }, 16060 },
15905 [ALC662_5ST_DIG] = { 16061 [ALC662_5ST_DIG] = {
15906 .mixers = { alc662_base_mixer, alc662_chmode_mixer, 16062 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
15907 alc662_capture_mixer },
15908 .init_verbs = { alc662_init_verbs }, 16063 .init_verbs = { alc662_init_verbs },
15909 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16064 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15910 .dac_nids = alc662_dac_nids, 16065 .dac_nids = alc662_dac_nids,
@@ -15915,7 +16070,7 @@ static struct alc_config_preset alc662_presets[] = {
15915 .input_mux = &alc662_capture_source, 16070 .input_mux = &alc662_capture_source,
15916 }, 16071 },
15917 [ALC662_LENOVO_101E] = { 16072 [ALC662_LENOVO_101E] = {
15918 .mixers = { alc662_lenovo_101e_mixer, alc662_capture_mixer }, 16073 .mixers = { alc662_lenovo_101e_mixer },
15919 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, 16074 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs },
15920 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16075 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15921 .dac_nids = alc662_dac_nids, 16076 .dac_nids = alc662_dac_nids,
@@ -15926,7 +16081,7 @@ static struct alc_config_preset alc662_presets[] = {
15926 .init_hook = alc662_lenovo_101e_all_automute, 16081 .init_hook = alc662_lenovo_101e_all_automute,
15927 }, 16082 },
15928 [ALC662_ASUS_EEEPC_P701] = { 16083 [ALC662_ASUS_EEEPC_P701] = {
15929 .mixers = { alc662_eeepc_p701_mixer, alc662_capture_mixer }, 16084 .mixers = { alc662_eeepc_p701_mixer },
15930 .init_verbs = { alc662_init_verbs, 16085 .init_verbs = { alc662_init_verbs,
15931 alc662_eeepc_sue_init_verbs }, 16086 alc662_eeepc_sue_init_verbs },
15932 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16087 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -15938,7 +16093,7 @@ static struct alc_config_preset alc662_presets[] = {
15938 .init_hook = alc662_eeepc_inithook, 16093 .init_hook = alc662_eeepc_inithook,
15939 }, 16094 },
15940 [ALC662_ASUS_EEEPC_EP20] = { 16095 [ALC662_ASUS_EEEPC_EP20] = {
15941 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer, 16096 .mixers = { alc662_eeepc_ep20_mixer,
15942 alc662_chmode_mixer }, 16097 alc662_chmode_mixer },
15943 .init_verbs = { alc662_init_verbs, 16098 .init_verbs = { alc662_init_verbs,
15944 alc662_eeepc_ep20_sue_init_verbs }, 16099 alc662_eeepc_ep20_sue_init_verbs },
@@ -15951,7 +16106,7 @@ static struct alc_config_preset alc662_presets[] = {
15951 .init_hook = alc662_eeepc_ep20_inithook, 16106 .init_hook = alc662_eeepc_ep20_inithook,
15952 }, 16107 },
15953 [ALC662_ECS] = { 16108 [ALC662_ECS] = {
15954 .mixers = { alc662_ecs_mixer, alc662_capture_mixer }, 16109 .mixers = { alc662_ecs_mixer },
15955 .init_verbs = { alc662_init_verbs, 16110 .init_verbs = { alc662_init_verbs,
15956 alc662_ecs_init_verbs }, 16111 alc662_ecs_init_verbs },
15957 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16112 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -15963,7 +16118,7 @@ static struct alc_config_preset alc662_presets[] = {
15963 .init_hook = alc662_eeepc_inithook, 16118 .init_hook = alc662_eeepc_inithook,
15964 }, 16119 },
15965 [ALC663_ASUS_M51VA] = { 16120 [ALC663_ASUS_M51VA] = {
15966 .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, 16121 .mixers = { alc663_m51va_mixer },
15967 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 16122 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15968 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16123 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15969 .dac_nids = alc662_dac_nids, 16124 .dac_nids = alc662_dac_nids,
@@ -15975,7 +16130,7 @@ static struct alc_config_preset alc662_presets[] = {
15975 .init_hook = alc663_m51va_inithook, 16130 .init_hook = alc663_m51va_inithook,
15976 }, 16131 },
15977 [ALC663_ASUS_G71V] = { 16132 [ALC663_ASUS_G71V] = {
15978 .mixers = { alc663_g71v_mixer, alc662_capture_mixer}, 16133 .mixers = { alc663_g71v_mixer },
15979 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, 16134 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs },
15980 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16135 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15981 .dac_nids = alc662_dac_nids, 16136 .dac_nids = alc662_dac_nids,
@@ -15987,7 +16142,7 @@ static struct alc_config_preset alc662_presets[] = {
15987 .init_hook = alc663_g71v_inithook, 16142 .init_hook = alc663_g71v_inithook,
15988 }, 16143 },
15989 [ALC663_ASUS_H13] = { 16144 [ALC663_ASUS_H13] = {
15990 .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, 16145 .mixers = { alc663_m51va_mixer },
15991 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, 16146 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs },
15992 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16147 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
15993 .dac_nids = alc662_dac_nids, 16148 .dac_nids = alc662_dac_nids,
@@ -15998,7 +16153,7 @@ static struct alc_config_preset alc662_presets[] = {
15998 .init_hook = alc663_m51va_inithook, 16153 .init_hook = alc663_m51va_inithook,
15999 }, 16154 },
16000 [ALC663_ASUS_G50V] = { 16155 [ALC663_ASUS_G50V] = {
16001 .mixers = { alc663_g50v_mixer, alc662_capture_mixer}, 16156 .mixers = { alc663_g50v_mixer },
16002 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, 16157 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs },
16003 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16158 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
16004 .dac_nids = alc662_dac_nids, 16159 .dac_nids = alc662_dac_nids,
@@ -16010,7 +16165,8 @@ static struct alc_config_preset alc662_presets[] = {
16010 .init_hook = alc663_g50v_inithook, 16165 .init_hook = alc663_g50v_inithook,
16011 }, 16166 },
16012 [ALC663_ASUS_MODE1] = { 16167 [ALC663_ASUS_MODE1] = {
16013 .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer }, 16168 .mixers = { alc663_m51va_mixer },
16169 .cap_mixer = alc662_auto_capture_mixer,
16014 .init_verbs = { alc662_init_verbs, 16170 .init_verbs = { alc662_init_verbs,
16015 alc663_21jd_amic_init_verbs }, 16171 alc663_21jd_amic_init_verbs },
16016 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16172 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16024,7 +16180,8 @@ static struct alc_config_preset alc662_presets[] = {
16024 .init_hook = alc663_mode1_inithook, 16180 .init_hook = alc663_mode1_inithook,
16025 }, 16181 },
16026 [ALC662_ASUS_MODE2] = { 16182 [ALC662_ASUS_MODE2] = {
16027 .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer }, 16183 .mixers = { alc662_1bjd_mixer },
16184 .cap_mixer = alc662_auto_capture_mixer,
16028 .init_verbs = { alc662_init_verbs, 16185 .init_verbs = { alc662_init_verbs,
16029 alc662_1bjd_amic_init_verbs }, 16186 alc662_1bjd_amic_init_verbs },
16030 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16187 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16037,7 +16194,8 @@ static struct alc_config_preset alc662_presets[] = {
16037 .init_hook = alc662_mode2_inithook, 16194 .init_hook = alc662_mode2_inithook,
16038 }, 16195 },
16039 [ALC663_ASUS_MODE3] = { 16196 [ALC663_ASUS_MODE3] = {
16040 .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer }, 16197 .mixers = { alc663_two_hp_m1_mixer },
16198 .cap_mixer = alc662_auto_capture_mixer,
16041 .init_verbs = { alc662_init_verbs, 16199 .init_verbs = { alc662_init_verbs,
16042 alc663_two_hp_amic_m1_init_verbs }, 16200 alc663_two_hp_amic_m1_init_verbs },
16043 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16201 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16051,8 +16209,8 @@ static struct alc_config_preset alc662_presets[] = {
16051 .init_hook = alc663_mode3_inithook, 16209 .init_hook = alc663_mode3_inithook,
16052 }, 16210 },
16053 [ALC663_ASUS_MODE4] = { 16211 [ALC663_ASUS_MODE4] = {
16054 .mixers = { alc663_asus_21jd_clfe_mixer, 16212 .mixers = { alc663_asus_21jd_clfe_mixer },
16055 alc662_auto_capture_mixer}, 16213 .cap_mixer = alc662_auto_capture_mixer,
16056 .init_verbs = { alc662_init_verbs, 16214 .init_verbs = { alc662_init_verbs,
16057 alc663_21jd_amic_init_verbs}, 16215 alc663_21jd_amic_init_verbs},
16058 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16216 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16066,8 +16224,8 @@ static struct alc_config_preset alc662_presets[] = {
16066 .init_hook = alc663_mode4_inithook, 16224 .init_hook = alc663_mode4_inithook,
16067 }, 16225 },
16068 [ALC663_ASUS_MODE5] = { 16226 [ALC663_ASUS_MODE5] = {
16069 .mixers = { alc663_asus_15jd_clfe_mixer, 16227 .mixers = { alc663_asus_15jd_clfe_mixer },
16070 alc662_auto_capture_mixer }, 16228 .cap_mixer = alc662_auto_capture_mixer,
16071 .init_verbs = { alc662_init_verbs, 16229 .init_verbs = { alc662_init_verbs,
16072 alc663_15jd_amic_init_verbs }, 16230 alc663_15jd_amic_init_verbs },
16073 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16231 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16081,7 +16239,8 @@ static struct alc_config_preset alc662_presets[] = {
16081 .init_hook = alc663_mode5_inithook, 16239 .init_hook = alc663_mode5_inithook,
16082 }, 16240 },
16083 [ALC663_ASUS_MODE6] = { 16241 [ALC663_ASUS_MODE6] = {
16084 .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer }, 16242 .mixers = { alc663_two_hp_m2_mixer },
16243 .cap_mixer = alc662_auto_capture_mixer,
16085 .init_verbs = { alc662_init_verbs, 16244 .init_verbs = { alc662_init_verbs,
16086 alc663_two_hp_amic_m2_init_verbs }, 16245 alc663_two_hp_amic_m2_init_verbs },
16087 .num_dacs = ARRAY_SIZE(alc662_dac_nids), 16246 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
@@ -16342,24 +16501,20 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
16342 if (spec->autocfg.dig_out_pin) 16501 if (spec->autocfg.dig_out_pin)
16343 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; 16502 spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
16344 16503
16345 if (spec->kctl_alloc) 16504 if (spec->kctls.list)
16346 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 16505 add_mixer(spec, spec->kctls.list);
16347 16506
16348 spec->num_mux_defs = 1; 16507 spec->num_mux_defs = 1;
16349 spec->input_mux = &spec->private_imux; 16508 spec->input_mux = &spec->private_imux;
16350 16509
16351 spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; 16510 add_verb(spec, alc662_auto_init_verbs);
16352 if (codec->vendor_id == 0x10ec0663) 16511 if (codec->vendor_id == 0x10ec0663)
16353 spec->init_verbs[spec->num_init_verbs++] = 16512 add_verb(spec, alc663_auto_init_verbs);
16354 alc663_auto_init_verbs;
16355 16513
16356 err = alc_auto_add_mic_boost(codec); 16514 err = alc_auto_add_mic_boost(codec);
16357 if (err < 0) 16515 if (err < 0)
16358 return err; 16516 return err;
16359 16517
16360 spec->mixers[spec->num_mixers] = alc662_capture_mixer;
16361 spec->num_mixers++;
16362
16363 store_pin_configs(codec); 16518 store_pin_configs(codec);
16364 return 1; 16519 return 1;
16365} 16520}
@@ -16435,6 +16590,10 @@ static int patch_alc662(struct hda_codec *codec)
16435 spec->adc_nids = alc662_adc_nids; 16590 spec->adc_nids = alc662_adc_nids;
16436 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); 16591 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
16437 spec->capsrc_nids = alc662_capsrc_nids; 16592 spec->capsrc_nids = alc662_capsrc_nids;
16593 spec->is_mix_capture = 1;
16594
16595 if (!spec->cap_mixer)
16596 set_capture_mixer(spec);
16438 16597
16439 spec->vmaster_nid = 0x02; 16598 spec->vmaster_nid = 0x02;
16440 16599
@@ -16445,6 +16604,7 @@ static int patch_alc662(struct hda_codec *codec)
16445 if (!spec->loopback.amplist) 16604 if (!spec->loopback.amplist)
16446 spec->loopback.amplist = alc662_loopbacks; 16605 spec->loopback.amplist = alc662_loopbacks;
16447#endif 16606#endif
16607 codec->proc_widget_hook = print_realtek_coef;
16448 16608
16449 return 0; 16609 return 0;
16450} 16610}
@@ -16452,7 +16612,7 @@ static int patch_alc662(struct hda_codec *codec)
16452/* 16612/*
16453 * patch entries 16613 * patch entries
16454 */ 16614 */
16455struct hda_codec_preset snd_hda_preset_realtek[] = { 16615static struct hda_codec_preset snd_hda_preset_realtek[] = {
16456 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 16616 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
16457 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 16617 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
16458 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, 16618 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
@@ -16484,3 +16644,26 @@ struct hda_codec_preset snd_hda_preset_realtek[] = {
16484 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 }, 16644 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc883 },
16485 {} /* terminator */ 16645 {} /* terminator */
16486}; 16646};
16647
16648MODULE_ALIAS("snd-hda-codec-id:10ec*");
16649
16650MODULE_LICENSE("GPL");
16651MODULE_DESCRIPTION("Realtek HD-audio codec");
16652
16653static struct hda_codec_preset_list realtek_list = {
16654 .preset = snd_hda_preset_realtek,
16655 .owner = THIS_MODULE,
16656};
16657
16658static int __init patch_realtek_init(void)
16659{
16660 return snd_hda_add_codec_preset(&realtek_list);
16661}
16662
16663static void __exit patch_realtek_exit(void)
16664{
16665 snd_hda_delete_codec_preset(&realtek_list);
16666}
16667
16668module_init(patch_realtek_init)
16669module_exit(patch_realtek_exit)
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 9332b63e406c..43b436c5d01b 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -28,7 +28,6 @@
28#include <sound/core.h> 28#include <sound/core.h>
29#include "hda_codec.h" 29#include "hda_codec.h"
30#include "hda_local.h" 30#include "hda_local.h"
31#include "hda_patch.h"
32 31
33/* si3054 verbs */ 32/* si3054 verbs */
34#define SI3054_VERB_READ_NODE 0x900 33#define SI3054_VERB_READ_NODE 0x900
@@ -283,7 +282,7 @@ static int patch_si3054(struct hda_codec *codec)
283/* 282/*
284 * patch entries 283 * patch entries
285 */ 284 */
286struct hda_codec_preset snd_hda_preset_si3054[] = { 285static struct hda_codec_preset snd_hda_preset_si3054[] = {
287 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, 286 { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 },
288 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, 287 { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 },
289 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, 288 { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 },
@@ -301,3 +300,35 @@ struct hda_codec_preset snd_hda_preset_si3054[] = {
301 {} 300 {}
302}; 301};
303 302
303MODULE_ALIAS("snd-hda-codec-id:163c3055");
304MODULE_ALIAS("snd-hda-codec-id:163c3155");
305MODULE_ALIAS("snd-hda-codec-id:11c13026");
306MODULE_ALIAS("snd-hda-codec-id:11c13055");
307MODULE_ALIAS("snd-hda-codec-id:11c13155");
308MODULE_ALIAS("snd-hda-codec-id:10573055");
309MODULE_ALIAS("snd-hda-codec-id:10573057");
310MODULE_ALIAS("snd-hda-codec-id:10573155");
311MODULE_ALIAS("snd-hda-codec-id:11063288");
312MODULE_ALIAS("snd-hda-codec-id:15433155");
313MODULE_ALIAS("snd-hda-codec-id:18540018");
314
315MODULE_LICENSE("GPL");
316MODULE_DESCRIPTION("Si3054 HD-audio modem codec");
317
318static struct hda_codec_preset_list si3054_list = {
319 .preset = snd_hda_preset_si3054,
320 .owner = THIS_MODULE,
321};
322
323static int __init patch_si3054_init(void)
324{
325 return snd_hda_add_codec_preset(&si3054_list);
326}
327
328static void __exit patch_si3054_exit(void)
329{
330 snd_hda_delete_codec_preset(&si3054_list);
331}
332
333module_init(patch_si3054_init)
334module_exit(patch_si3054_exit)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 5dd3e89f620a..35b83dc6e19e 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -30,17 +30,17 @@
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <sound/core.h> 31#include <sound/core.h>
32#include <sound/asoundef.h> 32#include <sound/asoundef.h>
33#include <sound/jack.h>
33#include "hda_codec.h" 34#include "hda_codec.h"
34#include "hda_local.h" 35#include "hda_local.h"
35#include "hda_patch.h"
36#include "hda_beep.h" 36#include "hda_beep.h"
37 37
38#define NUM_CONTROL_ALLOC 32 38enum {
39 39 STAC_VREF_EVENT = 1,
40#define STAC_VREF_EVENT 0x00 40 STAC_INSERT_EVENT,
41#define STAC_INSERT_EVENT 0x10 41 STAC_PWR_EVENT,
42#define STAC_PWR_EVENT 0x20 42 STAC_HP_EVENT,
43#define STAC_HP_EVENT 0x30 43};
44 44
45enum { 45enum {
46 STAC_REF, 46 STAC_REF,
@@ -69,6 +69,7 @@ enum {
69}; 69};
70 70
71enum { 71enum {
72 STAC_92HD73XX_NO_JD, /* no jack-detection */
72 STAC_92HD73XX_REF, 73 STAC_92HD73XX_REF,
73 STAC_DELL_M6_AMIC, 74 STAC_DELL_M6_AMIC,
74 STAC_DELL_M6_DMIC, 75 STAC_DELL_M6_DMIC,
@@ -127,6 +128,7 @@ enum {
127}; 128};
128 129
129enum { 130enum {
131 STAC_D965_REF_NO_JD, /* no jack-detection */
130 STAC_D965_REF, 132 STAC_D965_REF,
131 STAC_D965_3ST, 133 STAC_D965_3ST,
132 STAC_D965_5ST, 134 STAC_D965_5ST,
@@ -135,6 +137,19 @@ enum {
135 STAC_927X_MODELS 137 STAC_927X_MODELS
136}; 138};
137 139
140struct sigmatel_event {
141 hda_nid_t nid;
142 unsigned char type;
143 unsigned char tag;
144 int data;
145};
146
147struct sigmatel_jack {
148 hda_nid_t nid;
149 int type;
150 struct snd_jack *jack;
151};
152
138struct sigmatel_spec { 153struct sigmatel_spec {
139 struct snd_kcontrol_new *mixers[4]; 154 struct snd_kcontrol_new *mixers[4];
140 unsigned int num_mixers; 155 unsigned int num_mixers;
@@ -142,8 +157,6 @@ struct sigmatel_spec {
142 int board_config; 157 int board_config;
143 unsigned int eapd_switch: 1; 158 unsigned int eapd_switch: 1;
144 unsigned int surr_switch: 1; 159 unsigned int surr_switch: 1;
145 unsigned int line_switch: 1;
146 unsigned int mic_switch: 1;
147 unsigned int alt_switch: 1; 160 unsigned int alt_switch: 1;
148 unsigned int hp_detect: 1; 161 unsigned int hp_detect: 1;
149 unsigned int spdif_mute: 1; 162 unsigned int spdif_mute: 1;
@@ -168,12 +181,20 @@ struct sigmatel_spec {
168 hda_nid_t *pwr_nids; 181 hda_nid_t *pwr_nids;
169 hda_nid_t *dac_list; 182 hda_nid_t *dac_list;
170 183
184 /* jack detection */
185 struct snd_array jacks;
186
187 /* events */
188 struct snd_array events;
189
171 /* playback */ 190 /* playback */
172 struct hda_input_mux *mono_mux; 191 struct hda_input_mux *mono_mux;
173 struct hda_input_mux *amp_mux; 192 struct hda_input_mux *amp_mux;
174 unsigned int cur_mmux; 193 unsigned int cur_mmux;
175 struct hda_multi_out multiout; 194 struct hda_multi_out multiout;
176 hda_nid_t dac_nids[5]; 195 hda_nid_t dac_nids[5];
196 hda_nid_t hp_dacs[5];
197 hda_nid_t speaker_dacs[5];
177 198
178 /* capture */ 199 /* capture */
179 hda_nid_t *adc_nids; 200 hda_nid_t *adc_nids;
@@ -197,7 +218,6 @@ struct sigmatel_spec {
197 hda_nid_t *pin_nids; 218 hda_nid_t *pin_nids;
198 unsigned int num_pins; 219 unsigned int num_pins;
199 unsigned int *pin_configs; 220 unsigned int *pin_configs;
200 unsigned int *bios_pin_configs;
201 221
202 /* codec specific stuff */ 222 /* codec specific stuff */
203 struct hda_verb *init; 223 struct hda_verb *init;
@@ -218,15 +238,16 @@ struct sigmatel_spec {
218 /* i/o switches */ 238 /* i/o switches */
219 unsigned int io_switch[2]; 239 unsigned int io_switch[2];
220 unsigned int clfe_swap; 240 unsigned int clfe_swap;
221 unsigned int hp_switch; /* NID of HP as line-out */ 241 hda_nid_t line_switch; /* shared line-in for input and output */
242 hda_nid_t mic_switch; /* shared mic-in for input and output */
243 hda_nid_t hp_switch; /* NID of HP as line-out */
222 unsigned int aloopback; 244 unsigned int aloopback;
223 245
224 struct hda_pcm pcm_rec[2]; /* PCM information */ 246 struct hda_pcm pcm_rec[2]; /* PCM information */
225 247
226 /* dynamic controls and input_mux */ 248 /* dynamic controls and input_mux */
227 struct auto_pin_cfg autocfg; 249 struct auto_pin_cfg autocfg;
228 unsigned int num_kctl_alloc, num_kctl_used; 250 struct snd_array kctls;
229 struct snd_kcontrol_new *kctl_alloc;
230 struct hda_input_mux private_dimux; 251 struct hda_input_mux private_dimux;
231 struct hda_input_mux private_imux; 252 struct hda_input_mux private_imux;
232 struct hda_input_mux private_smux; 253 struct hda_input_mux private_smux;
@@ -270,9 +291,6 @@ static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = {
270}; 291};
271 292
272#define STAC92HD73_DAC_COUNT 5 293#define STAC92HD73_DAC_COUNT 5
273static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = {
274 0x15, 0x16, 0x17, 0x18, 0x19,
275};
276 294
277static hda_nid_t stac92hd73xx_mux_nids[4] = { 295static hda_nid_t stac92hd73xx_mux_nids[4] = {
278 0x28, 0x29, 0x2a, 0x2b, 296 0x28, 0x29, 0x2a, 0x2b,
@@ -291,11 +309,7 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
291 0x11, 0x12, 0 309 0x11, 0x12, 0
292}; 310};
293 311
294#define STAC92HD81_DAC_COUNT 2
295#define STAC92HD83_DAC_COUNT 3 312#define STAC92HD83_DAC_COUNT 3
296static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = {
297 0x13, 0x14, 0x22,
298};
299 313
300static hda_nid_t stac92hd83xxx_dmux_nids[2] = { 314static hda_nid_t stac92hd83xxx_dmux_nids[2] = {
301 0x17, 0x18, 315 0x17, 0x18,
@@ -337,10 +351,6 @@ static hda_nid_t stac92hd71bxx_smux_nids[2] = {
337 0x24, 0x25, 351 0x24, 0x25,
338}; 352};
339 353
340static hda_nid_t stac92hd71bxx_dac_nids[1] = {
341 0x10, /*0x11, */
342};
343
344#define STAC92HD71BXX_NUM_DMICS 2 354#define STAC92HD71BXX_NUM_DMICS 2
345static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { 355static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = {
346 0x18, 0x19, 0 356 0x18, 0x19, 0
@@ -572,12 +582,12 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol,
572 else 582 else
573 nid = codec->slave_dig_outs[smux_idx - 1]; 583 nid = codec->slave_dig_outs[smux_idx - 1];
574 if (spec->cur_smux[smux_idx] == smux->num_items - 1) 584 if (spec->cur_smux[smux_idx] == smux->num_items - 1)
575 val = AMP_OUT_MUTE; 585 val = HDA_AMP_MUTE;
576 else 586 else
577 val = AMP_OUT_UNMUTE; 587 val = 0;
578 /* un/mute SPDIF out */ 588 /* un/mute SPDIF out */
579 snd_hda_codec_write_cache(codec, nid, 0, 589 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
580 AC_VERB_SET_AMP_GAIN_MUTE, val); 590 HDA_AMP_MUTE, val);
581 } 591 }
582 return 0; 592 return 0;
583} 593}
@@ -742,10 +752,6 @@ static struct hda_verb stac9200_eapd_init[] = {
742static struct hda_verb stac92hd73xx_6ch_core_init[] = { 752static struct hda_verb stac92hd73xx_6ch_core_init[] = {
743 /* set master volume and direct control */ 753 /* set master volume and direct control */
744 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 754 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
745 /* setup audio connections */
746 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
747 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
748 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
749 /* setup adcs to point to mixer */ 755 /* setup adcs to point to mixer */
750 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 756 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
751 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 757 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -764,10 +770,6 @@ static struct hda_verb dell_eq_core_init[] = {
764 /* set master volume to max value without distortion 770 /* set master volume to max value without distortion
765 * and direct control */ 771 * and direct control */
766 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, 772 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec},
767 /* setup audio connections */
768 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
769 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02},
770 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01},
771 /* setup adcs to point to mixer */ 773 /* setup adcs to point to mixer */
772 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 774 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
773 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 775 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -781,10 +783,6 @@ static struct hda_verb dell_eq_core_init[] = {
781 783
782static struct hda_verb dell_m6_core_init[] = { 784static struct hda_verb dell_m6_core_init[] = {
783 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 785 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
784 /* setup audio connections */
785 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
786 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
787 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02},
788 /* setup adcs to point to mixer */ 786 /* setup adcs to point to mixer */
789 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 787 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
790 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 788 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -799,13 +797,6 @@ static struct hda_verb dell_m6_core_init[] = {
799static struct hda_verb stac92hd73xx_8ch_core_init[] = { 797static struct hda_verb stac92hd73xx_8ch_core_init[] = {
800 /* set master volume and direct control */ 798 /* set master volume and direct control */
801 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 799 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
802 /* setup audio connections */
803 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00},
804 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01},
805 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02},
806 /* connect hp ports to dac3 */
807 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03},
808 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03},
809 /* setup adcs to point to mixer */ 800 /* setup adcs to point to mixer */
810 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 801 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
811 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 802 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -823,15 +814,8 @@ static struct hda_verb stac92hd73xx_8ch_core_init[] = {
823static struct hda_verb stac92hd73xx_10ch_core_init[] = { 814static struct hda_verb stac92hd73xx_10ch_core_init[] = {
824 /* set master volume and direct control */ 815 /* set master volume and direct control */
825 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 816 { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
826 /* setup audio connections */
827 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
828 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 },
829 { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 },
830 /* dac3 is connected to import3 mux */ 817 /* dac3 is connected to import3 mux */
831 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f}, 818 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f},
832 /* connect hp ports to dac4 */
833 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04},
834 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04},
835 /* setup adcs to point to mixer */ 819 /* setup adcs to point to mixer */
836 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, 820 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b},
837 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, 821 { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b},
@@ -857,17 +841,17 @@ static struct hda_verb stac92hd83xxx_core_init[] = {
857 841
858 /* power state controls amps */ 842 /* power state controls amps */
859 { 0x01, AC_VERB_SET_EAPD, 1 << 2}, 843 { 0x01, AC_VERB_SET_EAPD, 1 << 2},
844 {}
860}; 845};
861 846
862static struct hda_verb stac92hd71bxx_core_init[] = { 847static struct hda_verb stac92hd71bxx_core_init[] = {
863 /* set master volume and direct control */ 848 /* set master volume and direct control */
864 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 849 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
865 /* connect headphone jack to dac1 */
866 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
867 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ 850 /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */
868 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 851 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
869 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 852 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
870 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 853 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
854 {}
871}; 855};
872 856
873#define HD_DISABLE_PORTF 2 857#define HD_DISABLE_PORTF 2
@@ -882,8 +866,6 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = {
882 866
883 /* set master volume and direct control */ 867 /* set master volume and direct control */
884 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 868 { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
885 /* connect headphone jack to dac1 */
886 { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01},
887 /* unmute right and left channels for nodes 0x0a, 0xd */ 869 /* unmute right and left channels for nodes 0x0a, 0xd */
888 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 870 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
889 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 871 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
@@ -1083,21 +1065,21 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = {
1083 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT), 1065 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT),
1084 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT), 1066 HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT),
1085 1067
1086 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT), 1068 HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT),
1087 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT), 1069 HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, HDA_INPUT),
1088 1070
1089 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT), 1071 HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT),
1090 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT), 1072 HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, HDA_INPUT),
1091 1073
1092 HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT), 1074 HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT),
1093 HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT), 1075 HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, HDA_INPUT),
1094 1076
1095 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT), 1077 HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT),
1096 HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT), 1078 HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT),
1097 1079
1098 /* 1080 /*
1099 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT), 1081 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT),
1100 HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT), 1082 HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT),
1101 */ 1083 */
1102 { } /* end */ 1084 { } /* end */
1103}; 1085};
@@ -1236,9 +1218,14 @@ static const char *slave_sws[] = {
1236 NULL 1218 NULL
1237}; 1219};
1238 1220
1221static void stac92xx_free_kctls(struct hda_codec *codec);
1222static int stac92xx_add_jack(struct hda_codec *codec, hda_nid_t nid, int type);
1223
1239static int stac92xx_build_controls(struct hda_codec *codec) 1224static int stac92xx_build_controls(struct hda_codec *codec)
1240{ 1225{
1241 struct sigmatel_spec *spec = codec->spec; 1226 struct sigmatel_spec *spec = codec->spec;
1227 struct auto_pin_cfg *cfg = &spec->autocfg;
1228 hda_nid_t nid;
1242 int err; 1229 int err;
1243 int i; 1230 int i;
1244 1231
@@ -1253,7 +1240,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1253 } 1240 }
1254 if (spec->num_dmuxes > 0) { 1241 if (spec->num_dmuxes > 0) {
1255 stac_dmux_mixer.count = spec->num_dmuxes; 1242 stac_dmux_mixer.count = spec->num_dmuxes;
1256 err = snd_ctl_add(codec->bus->card, 1243 err = snd_hda_ctl_add(codec,
1257 snd_ctl_new1(&stac_dmux_mixer, codec)); 1244 snd_ctl_new1(&stac_dmux_mixer, codec));
1258 if (err < 0) 1245 if (err < 0)
1259 return err; 1246 return err;
@@ -1269,7 +1256,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1269 spec->spdif_mute = 1; 1256 spec->spdif_mute = 1;
1270 } 1257 }
1271 stac_smux_mixer.count = spec->num_smuxes; 1258 stac_smux_mixer.count = spec->num_smuxes;
1272 err = snd_ctl_add(codec->bus->card, 1259 err = snd_hda_ctl_add(codec,
1273 snd_ctl_new1(&stac_smux_mixer, codec)); 1260 snd_ctl_new1(&stac_smux_mixer, codec));
1274 if (err < 0) 1261 if (err < 0)
1275 return err; 1262 return err;
@@ -1308,6 +1295,37 @@ static int stac92xx_build_controls(struct hda_codec *codec)
1308 return err; 1295 return err;
1309 } 1296 }
1310 1297
1298 stac92xx_free_kctls(codec); /* no longer needed */
1299
1300 /* create jack input elements */
1301 if (spec->hp_detect) {
1302 for (i = 0; i < cfg->hp_outs; i++) {
1303 int type = SND_JACK_HEADPHONE;
1304 nid = cfg->hp_pins[i];
1305 /* jack detection */
1306 if (cfg->hp_outs == i)
1307 type |= SND_JACK_LINEOUT;
1308 err = stac92xx_add_jack(codec, nid, type);
1309 if (err < 0)
1310 return err;
1311 }
1312 }
1313 for (i = 0; i < cfg->line_outs; i++) {
1314 err = stac92xx_add_jack(codec, cfg->line_out_pins[i],
1315 SND_JACK_LINEOUT);
1316 if (err < 0)
1317 return err;
1318 }
1319 for (i = 0; i < AUTO_PIN_LAST; i++) {
1320 nid = cfg->input_pins[i];
1321 if (nid) {
1322 err = stac92xx_add_jack(codec, nid,
1323 SND_JACK_MICROPHONE);
1324 if (err < 0)
1325 return err;
1326 }
1327 }
1328
1311 return 0; 1329 return 0;
1312} 1330}
1313 1331
@@ -1611,6 +1629,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1611}; 1629};
1612 1630
1613static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { 1631static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1632 [STAC_92HD73XX_NO_JD] = "no-jd",
1614 [STAC_92HD73XX_REF] = "ref", 1633 [STAC_92HD73XX_REF] = "ref",
1615 [STAC_DELL_M6_AMIC] = "dell-m6-amic", 1634 [STAC_DELL_M6_AMIC] = "dell-m6-amic",
1616 [STAC_DELL_M6_DMIC] = "dell-m6-dmic", 1635 [STAC_DELL_M6_DMIC] = "dell-m6-dmic",
@@ -1640,6 +1659,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = {
1640 "unknown Dell", STAC_DELL_M6_DMIC), 1659 "unknown Dell", STAC_DELL_M6_DMIC),
1641 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f, 1660 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x029f,
1642 "Dell Studio 1537", STAC_DELL_M6_DMIC), 1661 "Dell Studio 1537", STAC_DELL_M6_DMIC),
1662 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a0,
1663 "Dell Studio 17", STAC_DELL_M6_DMIC),
1643 {} /* terminator */ 1664 {} /* terminator */
1644}; 1665};
1645 1666
@@ -1662,6 +1683,7 @@ static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = {
1662 /* SigmaTel reference board */ 1683 /* SigmaTel reference board */
1663 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, 1684 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
1664 "DFI LanParty", STAC_92HD71BXX_REF), 1685 "DFI LanParty", STAC_92HD71BXX_REF),
1686 {} /* terminator */
1665}; 1687};
1666 1688
1667static unsigned int ref92hd71bxx_pin_configs[11] = { 1689static unsigned int ref92hd71bxx_pin_configs[11] = {
@@ -1712,6 +1734,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = {
1712 "HP dv5", STAC_HP_M4), 1734 "HP dv5", STAC_HP_M4),
1713 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, 1735 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4,
1714 "HP dv7", STAC_HP_M4), 1736 "HP dv7", STAC_HP_M4),
1737 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc,
1738 "HP dv7", STAC_HP_M4),
1715 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, 1739 SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a,
1716 "unknown HP", STAC_HP_M4), 1740 "unknown HP", STAC_HP_M4),
1717 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, 1741 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233,
@@ -2027,6 +2051,7 @@ static unsigned int dell_3st_pin_configs[14] = {
2027}; 2051};
2028 2052
2029static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { 2053static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
2054 [STAC_D965_REF_NO_JD] = ref927x_pin_configs,
2030 [STAC_D965_REF] = ref927x_pin_configs, 2055 [STAC_D965_REF] = ref927x_pin_configs,
2031 [STAC_D965_3ST] = d965_3st_pin_configs, 2056 [STAC_D965_3ST] = d965_3st_pin_configs,
2032 [STAC_D965_5ST] = d965_5st_pin_configs, 2057 [STAC_D965_5ST] = d965_5st_pin_configs,
@@ -2035,6 +2060,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
2035}; 2060};
2036 2061
2037static const char *stac927x_models[STAC_927X_MODELS] = { 2062static const char *stac927x_models[STAC_927X_MODELS] = {
2063 [STAC_D965_REF_NO_JD] = "ref-no-jd",
2038 [STAC_D965_REF] = "ref", 2064 [STAC_D965_REF] = "ref",
2039 [STAC_D965_3ST] = "3stack", 2065 [STAC_D965_3ST] = "3stack",
2040 [STAC_D965_5ST] = "5stack", 2066 [STAC_D965_5ST] = "5stack",
@@ -2193,12 +2219,11 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
2193 int i; 2219 int i;
2194 struct sigmatel_spec *spec = codec->spec; 2220 struct sigmatel_spec *spec = codec->spec;
2195 2221
2196 if (! spec->bios_pin_configs) { 2222 kfree(spec->pin_configs);
2197 spec->bios_pin_configs = kcalloc(spec->num_pins, 2223 spec->pin_configs = kcalloc(spec->num_pins, sizeof(*spec->pin_configs),
2198 sizeof(*spec->bios_pin_configs), GFP_KERNEL); 2224 GFP_KERNEL);
2199 if (! spec->bios_pin_configs) 2225 if (!spec->pin_configs)
2200 return -ENOMEM; 2226 return -ENOMEM;
2201 }
2202 2227
2203 for (i = 0; i < spec->num_pins; i++) { 2228 for (i = 0; i < spec->num_pins; i++) {
2204 hda_nid_t nid = spec->pin_nids[i]; 2229 hda_nid_t nid = spec->pin_nids[i];
@@ -2208,7 +2233,7 @@ static int stac92xx_save_bios_config_regs(struct hda_codec *codec)
2208 AC_VERB_GET_CONFIG_DEFAULT, 0x00); 2233 AC_VERB_GET_CONFIG_DEFAULT, 0x00);
2209 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n", 2234 snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n",
2210 nid, pin_cfg); 2235 nid, pin_cfg);
2211 spec->bios_pin_configs[i] = pin_cfg; 2236 spec->pin_configs[i] = pin_cfg;
2212 } 2237 }
2213 2238
2214 return 0; 2239 return 0;
@@ -2250,6 +2275,39 @@ static void stac92xx_set_config_regs(struct hda_codec *codec)
2250 spec->pin_configs[i]); 2275 spec->pin_configs[i]);
2251} 2276}
2252 2277
2278static int stac_save_pin_cfgs(struct hda_codec *codec, unsigned int *pins)
2279{
2280 struct sigmatel_spec *spec = codec->spec;
2281
2282 if (!pins)
2283 return stac92xx_save_bios_config_regs(codec);
2284
2285 kfree(spec->pin_configs);
2286 spec->pin_configs = kmemdup(pins,
2287 spec->num_pins * sizeof(*pins),
2288 GFP_KERNEL);
2289 if (!spec->pin_configs)
2290 return -ENOMEM;
2291
2292 stac92xx_set_config_regs(codec);
2293 return 0;
2294}
2295
2296static void stac_change_pin_config(struct hda_codec *codec, hda_nid_t nid,
2297 unsigned int cfg)
2298{
2299 struct sigmatel_spec *spec = codec->spec;
2300 int i;
2301
2302 for (i = 0; i < spec->num_pins; i++) {
2303 if (spec->pin_nids[i] == nid) {
2304 spec->pin_configs[i] = cfg;
2305 stac92xx_set_config_reg(codec, nid, cfg);
2306 break;
2307 }
2308 }
2309}
2310
2253/* 2311/*
2254 * Analog playback callbacks 2312 * Analog playback callbacks
2255 */ 2313 */
@@ -2327,7 +2385,7 @@ static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
2327 2385
2328 if (spec->powerdown_adcs) { 2386 if (spec->powerdown_adcs) {
2329 msleep(40); 2387 msleep(40);
2330 snd_hda_codec_write_cache(codec, nid, 0, 2388 snd_hda_codec_write(codec, nid, 0,
2331 AC_VERB_SET_POWER_STATE, AC_PWRST_D0); 2389 AC_VERB_SET_POWER_STATE, AC_PWRST_D0);
2332 } 2390 }
2333 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); 2391 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
@@ -2343,7 +2401,7 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
2343 2401
2344 snd_hda_codec_cleanup_stream(codec, nid); 2402 snd_hda_codec_cleanup_stream(codec, nid);
2345 if (spec->powerdown_adcs) 2403 if (spec->powerdown_adcs)
2346 snd_hda_codec_write_cache(codec, nid, 0, 2404 snd_hda_codec_write(codec, nid, 0,
2347 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 2405 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
2348 return 0; 2406 return 0;
2349} 2407}
@@ -2475,6 +2533,9 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol,
2475 return 0; 2533 return 0;
2476} 2534}
2477 2535
2536static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid,
2537 unsigned char type);
2538
2478static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, 2539static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2479 struct snd_ctl_elem_value *ucontrol) 2540 struct snd_ctl_elem_value *ucontrol)
2480{ 2541{
@@ -2487,7 +2548,7 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol,
2487 /* check to be sure that the ports are upto date with 2548 /* check to be sure that the ports are upto date with
2488 * switch changes 2549 * switch changes
2489 */ 2550 */
2490 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); 2551 stac_issue_unsol_event(codec, nid, STAC_HP_EVENT);
2491 2552
2492 return 1; 2553 return 1;
2493} 2554}
@@ -2527,7 +2588,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_
2527 * appropriately according to the pin direction 2588 * appropriately according to the pin direction
2528 */ 2589 */
2529 if (spec->hp_detect) 2590 if (spec->hp_detect)
2530 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); 2591 stac_issue_unsol_event(codec, nid, STAC_HP_EVENT);
2531 2592
2532 return 1; 2593 return 1;
2533} 2594}
@@ -2622,28 +2683,16 @@ static int stac92xx_add_control_temp(struct sigmatel_spec *spec,
2622{ 2683{
2623 struct snd_kcontrol_new *knew; 2684 struct snd_kcontrol_new *knew;
2624 2685
2625 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 2686 snd_array_init(&spec->kctls, sizeof(*knew), 32);
2626 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 2687 knew = snd_array_new(&spec->kctls);
2627 2688 if (!knew)
2628 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ 2689 return -ENOMEM;
2629 if (! knew)
2630 return -ENOMEM;
2631 if (spec->kctl_alloc) {
2632 memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc);
2633 kfree(spec->kctl_alloc);
2634 }
2635 spec->kctl_alloc = knew;
2636 spec->num_kctl_alloc = num;
2637 }
2638
2639 knew = &spec->kctl_alloc[spec->num_kctl_used];
2640 *knew = *ktemp; 2690 *knew = *ktemp;
2641 knew->index = idx; 2691 knew->index = idx;
2642 knew->name = kstrdup(name, GFP_KERNEL); 2692 knew->name = kstrdup(name, GFP_KERNEL);
2643 if (!knew->name) 2693 if (!knew->name)
2644 return -ENOMEM; 2694 return -ENOMEM;
2645 knew->private_value = val; 2695 knew->private_value = val;
2646 spec->num_kctl_used++;
2647 return 0; 2696 return 0;
2648} 2697}
2649 2698
@@ -2664,70 +2713,53 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type,
2664 return stac92xx_add_control_idx(spec, type, 0, name, val); 2713 return stac92xx_add_control_idx(spec, type, 0, name, val);
2665} 2714}
2666 2715
2667/* flag inputs as additional dynamic lineouts */ 2716/* check whether the line-input can be used as line-out */
2668static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) 2717static hda_nid_t check_line_out_switch(struct hda_codec *codec)
2669{ 2718{
2670 struct sigmatel_spec *spec = codec->spec; 2719 struct sigmatel_spec *spec = codec->spec;
2671 unsigned int wcaps, wtype; 2720 struct auto_pin_cfg *cfg = &spec->autocfg;
2672 int i, num_dacs = 0; 2721 hda_nid_t nid;
2673 2722 unsigned int pincap;
2674 /* use the wcaps cache to count all DACs available for line-outs */
2675 for (i = 0; i < codec->num_nodes; i++) {
2676 wcaps = codec->wcaps[i];
2677 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2678 2723
2679 if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) 2724 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2680 num_dacs++; 2725 return 0;
2681 } 2726 nid = cfg->input_pins[AUTO_PIN_LINE];
2727 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
2728 if (pincap & AC_PINCAP_OUT)
2729 return nid;
2730 return 0;
2731}
2682 2732
2683 snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); 2733/* check whether the mic-input can be used as line-out */
2684 2734static hda_nid_t check_mic_out_switch(struct hda_codec *codec)
2685 switch (cfg->line_outs) { 2735{
2686 case 3: 2736 struct sigmatel_spec *spec = codec->spec;
2687 /* add line-in as side */ 2737 struct auto_pin_cfg *cfg = &spec->autocfg;
2688 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { 2738 unsigned int def_conf, pincap;
2689 cfg->line_out_pins[cfg->line_outs] = 2739 unsigned int mic_pin;
2690 cfg->input_pins[AUTO_PIN_LINE]; 2740
2691 spec->line_switch = 1; 2741 if (cfg->line_out_type != AUTO_PIN_LINE_OUT)
2692 cfg->line_outs++; 2742 return 0;
2693 } 2743 mic_pin = AUTO_PIN_MIC;
2694 break; 2744 for (;;) {
2695 case 2: 2745 hda_nid_t nid = cfg->input_pins[mic_pin];
2696 /* add line-in as clfe and mic as side */ 2746 def_conf = snd_hda_codec_read(codec, nid, 0,
2697 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { 2747 AC_VERB_GET_CONFIG_DEFAULT, 0);
2698 cfg->line_out_pins[cfg->line_outs] = 2748 /* some laptops have an internal analog microphone
2699 cfg->input_pins[AUTO_PIN_LINE]; 2749 * which can't be used as a output */
2700 spec->line_switch = 1; 2750 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
2701 cfg->line_outs++; 2751 pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
2702 } 2752 if (pincap & AC_PINCAP_OUT)
2703 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { 2753 return nid;
2704 cfg->line_out_pins[cfg->line_outs] =
2705 cfg->input_pins[AUTO_PIN_MIC];
2706 spec->mic_switch = 1;
2707 cfg->line_outs++;
2708 }
2709 break;
2710 case 1:
2711 /* add line-in as surr and mic as clfe */
2712 if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) {
2713 cfg->line_out_pins[cfg->line_outs] =
2714 cfg->input_pins[AUTO_PIN_LINE];
2715 spec->line_switch = 1;
2716 cfg->line_outs++;
2717 }
2718 if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) {
2719 cfg->line_out_pins[cfg->line_outs] =
2720 cfg->input_pins[AUTO_PIN_MIC];
2721 spec->mic_switch = 1;
2722 cfg->line_outs++;
2723 } 2754 }
2724 break; 2755 if (mic_pin == AUTO_PIN_MIC)
2756 mic_pin = AUTO_PIN_FRONT_MIC;
2757 else
2758 break;
2725 } 2759 }
2726
2727 return 0; 2760 return 0;
2728} 2761}
2729 2762
2730
2731static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) 2763static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2732{ 2764{
2733 int i; 2765 int i;
@@ -2740,6 +2772,52 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2740 return 0; 2772 return 0;
2741} 2773}
2742 2774
2775static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2776{
2777 int i;
2778 if (is_in_dac_nids(spec, nid))
2779 return 1;
2780 for (i = 0; i < spec->autocfg.hp_outs; i++)
2781 if (spec->hp_dacs[i] == nid)
2782 return 1;
2783 for (i = 0; i < spec->autocfg.speaker_outs; i++)
2784 if (spec->speaker_dacs[i] == nid)
2785 return 1;
2786 return 0;
2787}
2788
2789static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid)
2790{
2791 struct sigmatel_spec *spec = codec->spec;
2792 int j, conn_len;
2793 hda_nid_t conn[HDA_MAX_CONNECTIONS];
2794 unsigned int wcaps, wtype;
2795
2796 conn_len = snd_hda_get_connections(codec, nid, conn,
2797 HDA_MAX_CONNECTIONS);
2798 for (j = 0; j < conn_len; j++) {
2799 wcaps = snd_hda_param_read(codec, conn[j],
2800 AC_PAR_AUDIO_WIDGET_CAP);
2801 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2802 /* we check only analog outputs */
2803 if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL))
2804 continue;
2805 /* if this route has a free DAC, assign it */
2806 if (!check_all_dac_nids(spec, conn[j])) {
2807 if (conn_len > 1) {
2808 /* select this DAC in the pin's input mux */
2809 snd_hda_codec_write_cache(codec, nid, 0,
2810 AC_VERB_SET_CONNECT_SEL, j);
2811 }
2812 return conn[j];
2813 }
2814 }
2815 return 0;
2816}
2817
2818static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
2819static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid);
2820
2743/* 2821/*
2744 * Fill in the dac_nids table from the parsed pin configuration 2822 * Fill in the dac_nids table from the parsed pin configuration
2745 * This function only works when every pin in line_out_pins[] 2823 * This function only works when every pin in line_out_pins[]
@@ -2747,31 +2825,17 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid)
2747 * codecs are not connected directly to a DAC, such as the 9200 2825 * codecs are not connected directly to a DAC, such as the 9200
2748 * and 9202/925x. For those, dac_nids[] must be hard-coded. 2826 * and 9202/925x. For those, dac_nids[] must be hard-coded.
2749 */ 2827 */
2750static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, 2828static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec)
2751 struct auto_pin_cfg *cfg)
2752{ 2829{
2753 struct sigmatel_spec *spec = codec->spec; 2830 struct sigmatel_spec *spec = codec->spec;
2754 int i, j, conn_len = 0; 2831 struct auto_pin_cfg *cfg = &spec->autocfg;
2755 hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; 2832 int i;
2756 unsigned int wcaps, wtype; 2833 hda_nid_t nid, dac;
2757 2834
2758 for (i = 0; i < cfg->line_outs; i++) { 2835 for (i = 0; i < cfg->line_outs; i++) {
2759 nid = cfg->line_out_pins[i]; 2836 nid = cfg->line_out_pins[i];
2760 conn_len = snd_hda_get_connections(codec, nid, conn, 2837 dac = get_unassigned_dac(codec, nid);
2761 HDA_MAX_CONNECTIONS); 2838 if (!dac) {
2762 for (j = 0; j < conn_len; j++) {
2763 wcaps = snd_hda_param_read(codec, conn[j],
2764 AC_PAR_AUDIO_WIDGET_CAP);
2765 wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT;
2766 if (wtype != AC_WID_AUD_OUT ||
2767 (wcaps & AC_WCAP_DIGITAL))
2768 continue;
2769 /* conn[j] is a DAC routed to this line-out */
2770 if (!is_in_dac_nids(spec, conn[j]))
2771 break;
2772 }
2773
2774 if (j == conn_len) {
2775 if (spec->multiout.num_dacs > 0) { 2839 if (spec->multiout.num_dacs > 0) {
2776 /* we have already working output pins, 2840 /* we have already working output pins,
2777 * so let's drop the broken ones again 2841 * so let's drop the broken ones again
@@ -2785,24 +2849,64 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec,
2785 __func__, nid); 2849 __func__, nid);
2786 return -ENODEV; 2850 return -ENODEV;
2787 } 2851 }
2852 add_spec_dacs(spec, dac);
2853 }
2788 2854
2789 spec->multiout.dac_nids[i] = conn[j]; 2855 /* add line-in as output */
2790 spec->multiout.num_dacs++; 2856 nid = check_line_out_switch(codec);
2791 if (conn_len > 1) { 2857 if (nid) {
2792 /* select this DAC in the pin's input mux */ 2858 dac = get_unassigned_dac(codec, nid);
2793 snd_hda_codec_write_cache(codec, nid, 0, 2859 if (dac) {
2794 AC_VERB_SET_CONNECT_SEL, j); 2860 snd_printdd("STAC: Add line-in 0x%x as output %d\n",
2861 nid, cfg->line_outs);
2862 cfg->line_out_pins[cfg->line_outs] = nid;
2863 cfg->line_outs++;
2864 spec->line_switch = nid;
2865 add_spec_dacs(spec, dac);
2866 }
2867 }
2868 /* add mic as output */
2869 nid = check_mic_out_switch(codec);
2870 if (nid) {
2871 dac = get_unassigned_dac(codec, nid);
2872 if (dac) {
2873 snd_printdd("STAC: Add mic-in 0x%x as output %d\n",
2874 nid, cfg->line_outs);
2875 cfg->line_out_pins[cfg->line_outs] = nid;
2876 cfg->line_outs++;
2877 spec->mic_switch = nid;
2878 add_spec_dacs(spec, dac);
2879 }
2880 }
2795 2881
2882 for (i = 0; i < cfg->hp_outs; i++) {
2883 nid = cfg->hp_pins[i];
2884 dac = get_unassigned_dac(codec, nid);
2885 if (dac) {
2886 if (!spec->multiout.hp_nid)
2887 spec->multiout.hp_nid = dac;
2888 else
2889 add_spec_extra_dacs(spec, dac);
2796 } 2890 }
2891 spec->hp_dacs[i] = dac;
2892 }
2893
2894 for (i = 0; i < cfg->speaker_outs; i++) {
2895 nid = cfg->speaker_pins[i];
2896 dac = get_unassigned_dac(codec, nid);
2897 if (dac)
2898 add_spec_extra_dacs(spec, dac);
2899 spec->speaker_dacs[i] = dac;
2797 } 2900 }
2798 2901
2799 snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", 2902 snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
2800 spec->multiout.num_dacs, 2903 spec->multiout.num_dacs,
2801 spec->multiout.dac_nids[0], 2904 spec->multiout.dac_nids[0],
2802 spec->multiout.dac_nids[1], 2905 spec->multiout.dac_nids[1],
2803 spec->multiout.dac_nids[2], 2906 spec->multiout.dac_nids[2],
2804 spec->multiout.dac_nids[3], 2907 spec->multiout.dac_nids[3],
2805 spec->multiout.dac_nids[4]); 2908 spec->multiout.dac_nids[4]);
2909
2806 return 0; 2910 return 0;
2807} 2911}
2808 2912
@@ -2827,9 +2931,7 @@ static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_
2827 2931
2828static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) 2932static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2829{ 2933{
2830 if (!spec->multiout.hp_nid) 2934 if (spec->multiout.num_dacs > 4) {
2831 spec->multiout.hp_nid = nid;
2832 else if (spec->multiout.num_dacs > 4) {
2833 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); 2935 printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid);
2834 return 1; 2936 return 1;
2835 } else { 2937 } else {
@@ -2839,35 +2941,47 @@ static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2839 return 0; 2941 return 0;
2840} 2942}
2841 2943
2842static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) 2944static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid)
2843{ 2945{
2844 if (is_in_dac_nids(spec, nid)) 2946 int i;
2845 return 1; 2947 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) {
2948 if (!spec->multiout.extra_out_nid[i]) {
2949 spec->multiout.extra_out_nid[i] = nid;
2950 return 0;
2951 }
2952 }
2953 printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid);
2954 return 1;
2955}
2956
2957static int is_unique_dac(struct sigmatel_spec *spec, hda_nid_t nid)
2958{
2959 int i;
2960
2961 if (spec->autocfg.line_outs != 1)
2962 return 0;
2846 if (spec->multiout.hp_nid == nid) 2963 if (spec->multiout.hp_nid == nid)
2847 return 1; 2964 return 0;
2848 return 0; 2965 for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++)
2966 if (spec->multiout.extra_out_nid[i] == nid)
2967 return 0;
2968 return 1;
2849} 2969}
2850 2970
2851/* add playback controls from the parsed DAC table */ 2971/* add playback controls from the parsed DAC table */
2852static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, 2972static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2853 const struct auto_pin_cfg *cfg) 2973 const struct auto_pin_cfg *cfg)
2854{ 2974{
2975 struct sigmatel_spec *spec = codec->spec;
2855 static const char *chname[4] = { 2976 static const char *chname[4] = {
2856 "Front", "Surround", NULL /*CLFE*/, "Side" 2977 "Front", "Surround", NULL /*CLFE*/, "Side"
2857 }; 2978 };
2858 hda_nid_t nid = 0; 2979 hda_nid_t nid = 0;
2859 int i, err; 2980 int i, err;
2981 unsigned int wid_caps;
2860 2982
2861 struct sigmatel_spec *spec = codec->spec; 2983 for (i = 0; i < cfg->line_outs && spec->multiout.dac_nids[i]; i++) {
2862 unsigned int wid_caps, pincap;
2863
2864
2865 for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) {
2866 if (!spec->multiout.dac_nids[i])
2867 continue;
2868
2869 nid = spec->multiout.dac_nids[i]; 2984 nid = spec->multiout.dac_nids[i];
2870
2871 if (i == 2) { 2985 if (i == 2) {
2872 /* Center/LFE */ 2986 /* Center/LFE */
2873 err = create_controls(spec, "Center", nid, 1); 2987 err = create_controls(spec, "Center", nid, 1);
@@ -2889,16 +3003,24 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2889 } 3003 }
2890 3004
2891 } else { 3005 } else {
2892 err = create_controls(spec, chname[i], nid, 3); 3006 const char *name = chname[i];
3007 /* if it's a single DAC, assign a better name */
3008 if (!i && is_unique_dac(spec, nid)) {
3009 switch (cfg->line_out_type) {
3010 case AUTO_PIN_HP_OUT:
3011 name = "Headphone";
3012 break;
3013 case AUTO_PIN_SPEAKER_OUT:
3014 name = "Speaker";
3015 break;
3016 }
3017 }
3018 err = create_controls(spec, name, nid, 3);
2893 if (err < 0) 3019 if (err < 0)
2894 return err; 3020 return err;
2895 } 3021 }
2896 } 3022 }
2897 3023
2898 if ((spec->multiout.num_dacs - cfg->line_outs) > 0 &&
2899 cfg->hp_outs && !spec->multiout.hp_nid)
2900 spec->multiout.hp_nid = nid;
2901
2902 if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { 3024 if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) {
2903 err = stac92xx_add_control(spec, 3025 err = stac92xx_add_control(spec,
2904 STAC_CTL_WIDGET_HP_SWITCH, 3026 STAC_CTL_WIDGET_HP_SWITCH,
@@ -2909,45 +3031,19 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec,
2909 } 3031 }
2910 3032
2911 if (spec->line_switch) { 3033 if (spec->line_switch) {
2912 nid = cfg->input_pins[AUTO_PIN_LINE]; 3034 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
2913 pincap = snd_hda_param_read(codec, nid, 3035 "Line In as Output Switch",
2914 AC_PAR_PIN_CAP); 3036 spec->line_switch << 8);
2915 if (pincap & AC_PINCAP_OUT) { 3037 if (err < 0)
2916 err = stac92xx_add_control(spec, 3038 return err;
2917 STAC_CTL_WIDGET_IO_SWITCH,
2918 "Line In as Output Switch", nid << 8);
2919 if (err < 0)
2920 return err;
2921 }
2922 } 3039 }
2923 3040
2924 if (spec->mic_switch) { 3041 if (spec->mic_switch) {
2925 unsigned int def_conf; 3042 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH,
2926 unsigned int mic_pin = AUTO_PIN_MIC; 3043 "Mic as Output Switch",
2927again: 3044 (spec->mic_switch << 8) | 1);
2928 nid = cfg->input_pins[mic_pin]; 3045 if (err < 0)
2929 def_conf = snd_hda_codec_read(codec, nid, 0, 3046 return err;
2930 AC_VERB_GET_CONFIG_DEFAULT, 0);
2931 /* some laptops have an internal analog microphone
2932 * which can't be used as a output */
2933 if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) {
2934 pincap = snd_hda_param_read(codec, nid,
2935 AC_PAR_PIN_CAP);
2936 if (pincap & AC_PINCAP_OUT) {
2937 err = stac92xx_add_control(spec,
2938 STAC_CTL_WIDGET_IO_SWITCH,
2939 "Mic as Output Switch", (nid << 8) | 1);
2940 nid = snd_hda_codec_read(codec, nid, 0,
2941 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2942 if (!check_in_dac_nids(spec, nid))
2943 add_spec_dacs(spec, nid);
2944 if (err < 0)
2945 return err;
2946 }
2947 } else if (mic_pin == AUTO_PIN_MIC) {
2948 mic_pin = AUTO_PIN_FRONT_MIC;
2949 goto again;
2950 }
2951 } 3047 }
2952 3048
2953 return 0; 3049 return 0;
@@ -2959,55 +3055,39 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
2959{ 3055{
2960 struct sigmatel_spec *spec = codec->spec; 3056 struct sigmatel_spec *spec = codec->spec;
2961 hda_nid_t nid; 3057 hda_nid_t nid;
2962 int i, old_num_dacs, err; 3058 int i, err, nums;
2963 3059
2964 old_num_dacs = spec->multiout.num_dacs; 3060 nums = 0;
2965 for (i = 0; i < cfg->hp_outs; i++) { 3061 for (i = 0; i < cfg->hp_outs; i++) {
3062 static const char *pfxs[] = {
3063 "Headphone", "Headphone2", "Headphone3",
3064 };
2966 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); 3065 unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]);
2967 if (wid_caps & AC_WCAP_UNSOL_CAP) 3066 if (wid_caps & AC_WCAP_UNSOL_CAP)
2968 spec->hp_detect = 1; 3067 spec->hp_detect = 1;
2969 nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, 3068 if (nums >= ARRAY_SIZE(pfxs))
2970 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2971 if (check_in_dac_nids(spec, nid))
2972 nid = 0;
2973 if (! nid)
2974 continue; 3069 continue;
2975 add_spec_dacs(spec, nid); 3070 nid = spec->hp_dacs[i];
2976 } 3071 if (!nid)
2977 for (i = 0; i < cfg->speaker_outs; i++) {
2978 nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0,
2979 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2980 if (check_in_dac_nids(spec, nid))
2981 nid = 0;
2982 if (! nid)
2983 continue;
2984 add_spec_dacs(spec, nid);
2985 }
2986 for (i = 0; i < cfg->line_outs; i++) {
2987 nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0,
2988 AC_VERB_GET_CONNECT_LIST, 0) & 0xff;
2989 if (check_in_dac_nids(spec, nid))
2990 nid = 0;
2991 if (! nid)
2992 continue; 3072 continue;
2993 add_spec_dacs(spec, nid); 3073 err = create_controls(spec, pfxs[nums++], nid, 3);
3074 if (err < 0)
3075 return err;
2994 } 3076 }
2995 for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { 3077 nums = 0;
3078 for (i = 0; i < cfg->speaker_outs; i++) {
2996 static const char *pfxs[] = { 3079 static const char *pfxs[] = {
2997 "Speaker", "External Speaker", "Speaker2", 3080 "Speaker", "External Speaker", "Speaker2",
2998 }; 3081 };
2999 err = create_controls(spec, pfxs[i - old_num_dacs], 3082 if (nums >= ARRAY_SIZE(pfxs))
3000 spec->multiout.dac_nids[i], 3); 3083 continue;
3001 if (err < 0) 3084 nid = spec->speaker_dacs[i];
3002 return err; 3085 if (!nid)
3003 } 3086 continue;
3004 if (spec->multiout.hp_nid) { 3087 err = create_controls(spec, pfxs[nums++], nid, 3);
3005 err = create_controls(spec, "Headphone",
3006 spec->multiout.hp_nid, 3);
3007 if (err < 0) 3088 if (err < 0)
3008 return err; 3089 return err;
3009 } 3090 }
3010
3011 return 0; 3091 return 0;
3012} 3092}
3013 3093
@@ -3345,7 +3425,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3345{ 3425{
3346 struct sigmatel_spec *spec = codec->spec; 3426 struct sigmatel_spec *spec = codec->spec;
3347 int err; 3427 int err;
3348 int hp_speaker_swap = 0;
3349 3428
3350 if ((err = snd_hda_parse_pin_def_config(codec, 3429 if ((err = snd_hda_parse_pin_def_config(codec,
3351 &spec->autocfg, 3430 &spec->autocfg,
@@ -3363,13 +3442,15 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3363 * speaker_outs so that the following routines can handle 3442 * speaker_outs so that the following routines can handle
3364 * HP pins as primary outputs. 3443 * HP pins as primary outputs.
3365 */ 3444 */
3445 snd_printdd("stac92xx: Enabling multi-HPs workaround\n");
3366 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins, 3446 memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins,
3367 sizeof(spec->autocfg.line_out_pins)); 3447 sizeof(spec->autocfg.line_out_pins));
3368 spec->autocfg.speaker_outs = spec->autocfg.line_outs; 3448 spec->autocfg.speaker_outs = spec->autocfg.line_outs;
3369 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins, 3449 memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins,
3370 sizeof(spec->autocfg.hp_pins)); 3450 sizeof(spec->autocfg.hp_pins));
3371 spec->autocfg.line_outs = spec->autocfg.hp_outs; 3451 spec->autocfg.line_outs = spec->autocfg.hp_outs;
3372 hp_speaker_swap = 1; 3452 spec->autocfg.line_out_type = AUTO_PIN_HP_OUT;
3453 spec->autocfg.hp_outs = 0;
3373 } 3454 }
3374 if (spec->autocfg.mono_out_pin) { 3455 if (spec->autocfg.mono_out_pin) {
3375 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & 3456 int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) &
@@ -3421,11 +3502,11 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3421 AC_PINCTL_OUT_EN); 3502 AC_PINCTL_OUT_EN);
3422 } 3503 }
3423 3504
3424 if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) 3505 if (!spec->multiout.num_dacs) {
3425 return err; 3506 err = stac92xx_auto_fill_dac_nids(codec);
3426 if (spec->multiout.num_dacs == 0) 3507 if (err < 0)
3427 if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0)
3428 return err; 3508 return err;
3509 }
3429 3510
3430 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg); 3511 err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg);
3431 3512
@@ -3463,19 +3544,6 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3463 } 3544 }
3464#endif 3545#endif
3465 3546
3466 if (hp_speaker_swap == 1) {
3467 /* Restore the hp_outs and line_outs */
3468 memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins,
3469 sizeof(spec->autocfg.line_out_pins));
3470 spec->autocfg.hp_outs = spec->autocfg.line_outs;
3471 memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins,
3472 sizeof(spec->autocfg.speaker_pins));
3473 spec->autocfg.line_outs = spec->autocfg.speaker_outs;
3474 memset(spec->autocfg.speaker_pins, 0,
3475 sizeof(spec->autocfg.speaker_pins));
3476 spec->autocfg.speaker_outs = 0;
3477 }
3478
3479 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); 3547 err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg);
3480 3548
3481 if (err < 0) 3549 if (err < 0)
@@ -3520,11 +3588,12 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
3520 if (dig_in && spec->autocfg.dig_in_pin) 3588 if (dig_in && spec->autocfg.dig_in_pin)
3521 spec->dig_in_nid = dig_in; 3589 spec->dig_in_nid = dig_in;
3522 3590
3523 if (spec->kctl_alloc) 3591 if (spec->kctls.list)
3524 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3592 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3525 3593
3526 spec->input_mux = &spec->private_imux; 3594 spec->input_mux = &spec->private_imux;
3527 spec->dinput_mux = &spec->private_dimux; 3595 if (!spec->dinput_mux)
3596 spec->dinput_mux = &spec->private_dimux;
3528 spec->sinput_mux = &spec->private_smux; 3597 spec->sinput_mux = &spec->private_smux;
3529 spec->mono_mux = &spec->private_mono_mux; 3598 spec->mono_mux = &spec->private_mono_mux;
3530 spec->amp_mux = &spec->private_amp_mux; 3599 spec->amp_mux = &spec->private_amp_mux;
@@ -3628,8 +3697,8 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
3628 if (spec->autocfg.dig_in_pin) 3697 if (spec->autocfg.dig_in_pin)
3629 spec->dig_in_nid = 0x04; 3698 spec->dig_in_nid = 0x04;
3630 3699
3631 if (spec->kctl_alloc) 3700 if (spec->kctls.list)
3632 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3701 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3633 3702
3634 spec->input_mux = &spec->private_imux; 3703 spec->input_mux = &spec->private_imux;
3635 spec->dinput_mux = &spec->private_dimux; 3704 spec->dinput_mux = &spec->private_dimux;
@@ -3673,13 +3742,101 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
3673 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ 3742 AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */
3674} 3743}
3675 3744
3745static int stac92xx_add_jack(struct hda_codec *codec,
3746 hda_nid_t nid, int type)
3747{
3748#ifdef CONFIG_SND_JACK
3749 struct sigmatel_spec *spec = codec->spec;
3750 struct sigmatel_jack *jack;
3751 int def_conf = snd_hda_codec_read(codec, nid,
3752 0, AC_VERB_GET_CONFIG_DEFAULT, 0);
3753 int connectivity = get_defcfg_connect(def_conf);
3754 char name[32];
3755
3756 if (connectivity && connectivity != AC_JACK_PORT_FIXED)
3757 return 0;
3758
3759 snd_array_init(&spec->jacks, sizeof(*jack), 32);
3760 jack = snd_array_new(&spec->jacks);
3761 if (!jack)
3762 return -ENOMEM;
3763 jack->nid = nid;
3764 jack->type = type;
3765
3766 sprintf(name, "%s at %s %s Jack",
3767 snd_hda_get_jack_type(def_conf),
3768 snd_hda_get_jack_connectivity(def_conf),
3769 snd_hda_get_jack_location(def_conf));
3770
3771 return snd_jack_new(codec->bus->card, name, type, &jack->jack);
3772#else
3773 return 0;
3774#endif
3775}
3776
3777static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid,
3778 unsigned char type, int data)
3779{
3780 struct sigmatel_event *event;
3781
3782 snd_array_init(&spec->events, sizeof(*event), 32);
3783 event = snd_array_new(&spec->events);
3784 if (!event)
3785 return -ENOMEM;
3786 event->nid = nid;
3787 event->type = type;
3788 event->tag = spec->events.used;
3789 event->data = data;
3790
3791 return event->tag;
3792}
3793
3794static struct sigmatel_event *stac_get_event(struct hda_codec *codec,
3795 hda_nid_t nid, unsigned char type)
3796{
3797 struct sigmatel_spec *spec = codec->spec;
3798 struct sigmatel_event *event = spec->events.list;
3799 int i;
3800
3801 for (i = 0; i < spec->events.used; i++, event++) {
3802 if (event->nid == nid && event->type == type)
3803 return event;
3804 }
3805 return NULL;
3806}
3807
3808static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec,
3809 unsigned char tag)
3810{
3811 struct sigmatel_spec *spec = codec->spec;
3812 struct sigmatel_event *event = spec->events.list;
3813 int i;
3814
3815 for (i = 0; i < spec->events.used; i++, event++) {
3816 if (event->tag == tag)
3817 return event;
3818 }
3819 return NULL;
3820}
3821
3676static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, 3822static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid,
3677 unsigned int event) 3823 unsigned int type)
3678{ 3824{
3679 if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) 3825 struct sigmatel_event *event;
3680 snd_hda_codec_write_cache(codec, nid, 0, 3826 int tag;
3681 AC_VERB_SET_UNSOLICITED_ENABLE, 3827
3682 (AC_USRSP_EN | event)); 3828 if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP))
3829 return;
3830 event = stac_get_event(codec, nid, type);
3831 if (event)
3832 tag = event->tag;
3833 else
3834 tag = stac_add_event(codec->spec, nid, type, 0);
3835 if (tag < 0)
3836 return;
3837 snd_hda_codec_write_cache(codec, nid, 0,
3838 AC_VERB_SET_UNSOLICITED_ENABLE,
3839 AC_USRSP_EN | tag);
3683} 3840}
3684 3841
3685static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) 3842static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid)
@@ -3699,9 +3856,8 @@ static void stac92xx_power_down(struct hda_codec *codec)
3699 /* power down inactive DACs */ 3856 /* power down inactive DACs */
3700 hda_nid_t *dac; 3857 hda_nid_t *dac;
3701 for (dac = spec->dac_list; *dac; dac++) 3858 for (dac = spec->dac_list; *dac; dac++)
3702 if (!is_in_dac_nids(spec, *dac) && 3859 if (!check_all_dac_nids(spec, *dac))
3703 spec->multiout.hp_nid != *dac) 3860 snd_hda_codec_write(codec, *dac, 0,
3704 snd_hda_codec_write_cache(codec, *dac, 0,
3705 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3861 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3706} 3862}
3707 3863
@@ -3720,7 +3876,7 @@ static int stac92xx_init(struct hda_codec *codec)
3720 /* power down adcs initially */ 3876 /* power down adcs initially */
3721 if (spec->powerdown_adcs) 3877 if (spec->powerdown_adcs)
3722 for (i = 0; i < spec->num_adcs; i++) 3878 for (i = 0; i < spec->num_adcs; i++)
3723 snd_hda_codec_write_cache(codec, 3879 snd_hda_codec_write(codec,
3724 spec->adc_nids[i], 0, 3880 spec->adc_nids[i], 0,
3725 AC_VERB_SET_POWER_STATE, AC_PWRST_D3); 3881 AC_VERB_SET_POWER_STATE, AC_PWRST_D3);
3726 3882
@@ -3736,37 +3892,51 @@ static int stac92xx_init(struct hda_codec *codec)
3736 /* set up pins */ 3892 /* set up pins */
3737 if (spec->hp_detect) { 3893 if (spec->hp_detect) {
3738 /* Enable unsolicited responses on the HP widget */ 3894 /* Enable unsolicited responses on the HP widget */
3739 for (i = 0; i < cfg->hp_outs; i++) 3895 for (i = 0; i < cfg->hp_outs; i++) {
3740 enable_pin_detect(codec, cfg->hp_pins[i], 3896 hda_nid_t nid = cfg->hp_pins[i];
3741 STAC_HP_EVENT); 3897 enable_pin_detect(codec, nid, STAC_HP_EVENT);
3898 }
3742 /* force to enable the first line-out; the others are set up 3899 /* force to enable the first line-out; the others are set up
3743 * in unsol_event 3900 * in unsol_event
3744 */ 3901 */
3745 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], 3902 stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0],
3746 AC_PINCTL_OUT_EN); 3903 AC_PINCTL_OUT_EN);
3747 stac92xx_auto_init_hp_out(codec);
3748 /* fake event to set up pins */ 3904 /* fake event to set up pins */
3749 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); 3905 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0],
3906 STAC_HP_EVENT);
3750 } else { 3907 } else {
3751 stac92xx_auto_init_multi_out(codec); 3908 stac92xx_auto_init_multi_out(codec);
3752 stac92xx_auto_init_hp_out(codec); 3909 stac92xx_auto_init_hp_out(codec);
3910 for (i = 0; i < cfg->hp_outs; i++)
3911 stac_toggle_power_map(codec, cfg->hp_pins[i], 1);
3753 } 3912 }
3754 for (i = 0; i < AUTO_PIN_LAST; i++) { 3913 for (i = 0; i < AUTO_PIN_LAST; i++) {
3755 hda_nid_t nid = cfg->input_pins[i]; 3914 hda_nid_t nid = cfg->input_pins[i];
3756 if (nid) { 3915 if (nid) {
3757 unsigned int pinctl; 3916 unsigned int pinctl, conf;
3758 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { 3917 if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) {
3759 /* for mic pins, force to initialize */ 3918 /* for mic pins, force to initialize */
3760 pinctl = stac92xx_get_vref(codec, nid); 3919 pinctl = stac92xx_get_vref(codec, nid);
3920 pinctl |= AC_PINCTL_IN_EN;
3921 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3761 } else { 3922 } else {
3762 pinctl = snd_hda_codec_read(codec, nid, 0, 3923 pinctl = snd_hda_codec_read(codec, nid, 0,
3763 AC_VERB_GET_PIN_WIDGET_CONTROL, 0); 3924 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3764 /* if PINCTL already set then skip */ 3925 /* if PINCTL already set then skip */
3765 if (pinctl & AC_PINCTL_IN_EN) 3926 if (!(pinctl & AC_PINCTL_IN_EN)) {
3766 continue; 3927 pinctl |= AC_PINCTL_IN_EN;
3928 stac92xx_auto_set_pinctl(codec, nid,
3929 pinctl);
3930 }
3931 }
3932 conf = snd_hda_codec_read(codec, nid, 0,
3933 AC_VERB_GET_CONFIG_DEFAULT, 0);
3934 if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) {
3935 enable_pin_detect(codec, nid,
3936 STAC_INSERT_EVENT);
3937 stac_issue_unsol_event(codec, nid,
3938 STAC_INSERT_EVENT);
3767 } 3939 }
3768 pinctl |= AC_PINCTL_IN_EN;
3769 stac92xx_auto_set_pinctl(codec, nid, pinctl);
3770 } 3940 }
3771 } 3941 }
3772 for (i = 0; i < spec->num_dmics; i++) 3942 for (i = 0; i < spec->num_dmics; i++)
@@ -3781,9 +3951,14 @@ static int stac92xx_init(struct hda_codec *codec)
3781 for (i = 0; i < spec->num_pwrs; i++) { 3951 for (i = 0; i < spec->num_pwrs; i++) {
3782 hda_nid_t nid = spec->pwr_nids[i]; 3952 hda_nid_t nid = spec->pwr_nids[i];
3783 int pinctl, def_conf; 3953 int pinctl, def_conf;
3784 int event = STAC_PWR_EVENT;
3785 3954
3786 if (is_nid_hp_pin(cfg, nid) && spec->hp_detect) 3955 /* power on when no jack detection is available */
3956 if (!spec->hp_detect) {
3957 stac_toggle_power_map(codec, nid, 1);
3958 continue;
3959 }
3960
3961 if (is_nid_hp_pin(cfg, nid))
3787 continue; /* already has an unsol event */ 3962 continue; /* already has an unsol event */
3788 3963
3789 pinctl = snd_hda_codec_read(codec, nid, 0, 3964 pinctl = snd_hda_codec_read(codec, nid, 0,
@@ -3792,8 +3967,10 @@ static int stac92xx_init(struct hda_codec *codec)
3792 * any attempts on powering down a input port cause the 3967 * any attempts on powering down a input port cause the
3793 * referenced VREF to act quirky. 3968 * referenced VREF to act quirky.
3794 */ 3969 */
3795 if (pinctl & AC_PINCTL_IN_EN) 3970 if (pinctl & AC_PINCTL_IN_EN) {
3971 stac_toggle_power_map(codec, nid, 1);
3796 continue; 3972 continue;
3973 }
3797 def_conf = snd_hda_codec_read(codec, nid, 0, 3974 def_conf = snd_hda_codec_read(codec, nid, 0,
3798 AC_VERB_GET_CONFIG_DEFAULT, 0); 3975 AC_VERB_GET_CONFIG_DEFAULT, 0);
3799 def_conf = get_defcfg_connect(def_conf); 3976 def_conf = get_defcfg_connect(def_conf);
@@ -3804,30 +3981,54 @@ static int stac92xx_init(struct hda_codec *codec)
3804 stac_toggle_power_map(codec, nid, 1); 3981 stac_toggle_power_map(codec, nid, 1);
3805 continue; 3982 continue;
3806 } 3983 }
3807 enable_pin_detect(codec, spec->pwr_nids[i], event | i); 3984 if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) {
3808 codec->patch_ops.unsol_event(codec, (event | i) << 26); 3985 enable_pin_detect(codec, nid, STAC_PWR_EVENT);
3986 stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT);
3987 }
3809 } 3988 }
3810 if (spec->dac_list) 3989 if (spec->dac_list)
3811 stac92xx_power_down(codec); 3990 stac92xx_power_down(codec);
3812 return 0; 3991 return 0;
3813} 3992}
3814 3993
3994static void stac92xx_free_jacks(struct hda_codec *codec)
3995{
3996#ifdef CONFIG_SND_JACK
3997 /* free jack instances manually when clearing/reconfiguring */
3998 struct sigmatel_spec *spec = codec->spec;
3999 if (!codec->bus->shutdown && spec->jacks.list) {
4000 struct sigmatel_jack *jacks = spec->jacks.list;
4001 int i;
4002 for (i = 0; i < spec->jacks.used; i++)
4003 snd_device_free(codec->bus->card, &jacks[i].jack);
4004 }
4005 snd_array_free(&spec->jacks);
4006#endif
4007}
4008
4009static void stac92xx_free_kctls(struct hda_codec *codec)
4010{
4011 struct sigmatel_spec *spec = codec->spec;
4012
4013 if (spec->kctls.list) {
4014 struct snd_kcontrol_new *kctl = spec->kctls.list;
4015 int i;
4016 for (i = 0; i < spec->kctls.used; i++)
4017 kfree(kctl[i].name);
4018 }
4019 snd_array_free(&spec->kctls);
4020}
4021
3815static void stac92xx_free(struct hda_codec *codec) 4022static void stac92xx_free(struct hda_codec *codec)
3816{ 4023{
3817 struct sigmatel_spec *spec = codec->spec; 4024 struct sigmatel_spec *spec = codec->spec;
3818 int i;
3819 4025
3820 if (! spec) 4026 if (! spec)
3821 return; 4027 return;
3822 4028
3823 if (spec->kctl_alloc) { 4029 kfree(spec->pin_configs);
3824 for (i = 0; i < spec->num_kctl_used; i++) 4030 stac92xx_free_jacks(codec);
3825 kfree(spec->kctl_alloc[i].name); 4031 snd_array_free(&spec->events);
3826 kfree(spec->kctl_alloc);
3827 }
3828
3829 if (spec->bios_pin_configs)
3830 kfree(spec->bios_pin_configs);
3831 4032
3832 kfree(spec); 4033 kfree(spec);
3833 snd_hda_detach_beep_device(codec); 4034 snd_hda_detach_beep_device(codec);
@@ -3846,11 +4047,7 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid,
3846 * "xxx as Output" mixer switch 4047 * "xxx as Output" mixer switch
3847 */ 4048 */
3848 struct sigmatel_spec *spec = codec->spec; 4049 struct sigmatel_spec *spec = codec->spec;
3849 struct auto_pin_cfg *cfg = &spec->autocfg; 4050 if (nid == spec->line_switch || nid == spec->mic_switch)
3850 if ((nid == cfg->input_pins[AUTO_PIN_LINE] &&
3851 spec->line_switch) ||
3852 (nid == cfg->input_pins[AUTO_PIN_MIC] &&
3853 spec->mic_switch))
3854 return; 4051 return;
3855 } 4052 }
3856 4053
@@ -3874,20 +4071,13 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid,
3874 pin_ctl & ~flag); 4071 pin_ctl & ~flag);
3875} 4072}
3876 4073
3877static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid) 4074static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid)
3878{ 4075{
3879 if (!nid) 4076 if (!nid)
3880 return 0; 4077 return 0;
3881 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) 4078 if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00)
3882 & (1 << 31)) { 4079 & (1 << 31))
3883 unsigned int pinctl; 4080 return 1;
3884 pinctl = snd_hda_codec_read(codec, nid, 0,
3885 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3886 if (pinctl & AC_PINCTL_IN_EN)
3887 return 0; /* mic- or line-input */
3888 else
3889 return 1; /* HP-output */
3890 }
3891 return 0; 4081 return 0;
3892} 4082}
3893 4083
@@ -3899,11 +4089,9 @@ static int no_hp_sensing(struct sigmatel_spec *spec, int i)
3899 struct auto_pin_cfg *cfg = &spec->autocfg; 4089 struct auto_pin_cfg *cfg = &spec->autocfg;
3900 4090
3901 /* ignore sensing of shared line and mic jacks */ 4091 /* ignore sensing of shared line and mic jacks */
3902 if (spec->line_switch && 4092 if (cfg->hp_pins[i] == spec->line_switch)
3903 cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE])
3904 return 1; 4093 return 1;
3905 if (spec->mic_switch && 4094 if (cfg->hp_pins[i] == spec->mic_switch)
3906 cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC])
3907 return 1; 4095 return 1;
3908 /* ignore if the pin is set as line-out */ 4096 /* ignore if the pin is set as line-out */
3909 if (cfg->hp_pins[i] == spec->hp_switch) 4097 if (cfg->hp_pins[i] == spec->hp_switch)
@@ -3911,7 +4099,7 @@ static int no_hp_sensing(struct sigmatel_spec *spec, int i)
3911 return 0; 4099 return 0;
3912} 4100}
3913 4101
3914static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) 4102static void stac92xx_hp_detect(struct hda_codec *codec)
3915{ 4103{
3916 struct sigmatel_spec *spec = codec->spec; 4104 struct sigmatel_spec *spec = codec->spec;
3917 struct auto_pin_cfg *cfg = &spec->autocfg; 4105 struct auto_pin_cfg *cfg = &spec->autocfg;
@@ -3927,7 +4115,14 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res)
3927 break; 4115 break;
3928 if (no_hp_sensing(spec, i)) 4116 if (no_hp_sensing(spec, i))
3929 continue; 4117 continue;
3930 presence = get_hp_pin_presence(codec, cfg->hp_pins[i]); 4118 presence = get_pin_presence(codec, cfg->hp_pins[i]);
4119 if (presence) {
4120 unsigned int pinctl;
4121 pinctl = snd_hda_codec_read(codec, cfg->hp_pins[i], 0,
4122 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4123 if (pinctl & AC_PINCTL_IN_EN)
4124 presence = 0; /* mic- or line-input */
4125 }
3931 } 4126 }
3932 4127
3933 if (presence) { 4128 if (presence) {
@@ -4004,50 +4199,145 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid,
4004 4199
4005static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) 4200static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid)
4006{ 4201{
4007 stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid)); 4202 stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid));
4203}
4204
4205static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid)
4206{
4207 struct sigmatel_spec *spec = codec->spec;
4208 struct sigmatel_jack *jacks = spec->jacks.list;
4209
4210 if (jacks) {
4211 int i;
4212 for (i = 0; i < spec->jacks.used; i++) {
4213 if (jacks->nid == nid) {
4214 unsigned int pin_ctl =
4215 snd_hda_codec_read(codec, nid,
4216 0, AC_VERB_GET_PIN_WIDGET_CONTROL,
4217 0x00);
4218 int type = jacks->type;
4219 if (type == (SND_JACK_LINEOUT
4220 | SND_JACK_HEADPHONE))
4221 type = (pin_ctl & AC_PINCTL_HP_EN)
4222 ? SND_JACK_HEADPHONE : SND_JACK_LINEOUT;
4223 snd_jack_report(jacks->jack,
4224 get_pin_presence(codec, nid)
4225 ? type : 0);
4226 }
4227 jacks++;
4228 }
4229 }
4230}
4231
4232static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid,
4233 unsigned char type)
4234{
4235 struct sigmatel_event *event = stac_get_event(codec, nid, type);
4236 if (!event)
4237 return;
4238 codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26);
4008} 4239}
4009 4240
4010static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) 4241static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res)
4011{ 4242{
4012 struct sigmatel_spec *spec = codec->spec; 4243 struct sigmatel_spec *spec = codec->spec;
4013 int idx = res >> 26 & 0x0f; 4244 struct sigmatel_event *event;
4245 int tag, data;
4014 4246
4015 switch ((res >> 26) & 0x70) { 4247 tag = (res >> 26) & 0x7f;
4248 event = stac_get_event_from_tag(codec, tag);
4249 if (!event)
4250 return;
4251
4252 switch (event->type) {
4016 case STAC_HP_EVENT: 4253 case STAC_HP_EVENT:
4017 stac92xx_hp_detect(codec, res); 4254 stac92xx_hp_detect(codec);
4018 /* fallthru */ 4255 /* fallthru */
4256 case STAC_INSERT_EVENT:
4019 case STAC_PWR_EVENT: 4257 case STAC_PWR_EVENT:
4020 if (spec->num_pwrs > 0) 4258 if (spec->num_pwrs > 0)
4021 stac92xx_pin_sense(codec, idx); 4259 stac92xx_pin_sense(codec, event->nid);
4260 stac92xx_report_jack(codec, event->nid);
4022 break; 4261 break;
4023 case STAC_VREF_EVENT: { 4262 case STAC_VREF_EVENT:
4024 int data = snd_hda_codec_read(codec, codec->afg, 0, 4263 data = snd_hda_codec_read(codec, codec->afg, 0,
4025 AC_VERB_GET_GPIO_DATA, 0); 4264 AC_VERB_GET_GPIO_DATA, 0);
4026 /* toggle VREF state based on GPIOx status */ 4265 /* toggle VREF state based on GPIOx status */
4027 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, 4266 snd_hda_codec_write(codec, codec->afg, 0, 0x7e0,
4028 !!(data & (1 << idx))); 4267 !!(data & (1 << event->data)));
4029 break; 4268 break;
4030 }
4031 } 4269 }
4032} 4270}
4033 4271
4272#ifdef CONFIG_PROC_FS
4273static void stac92hd_proc_hook(struct snd_info_buffer *buffer,
4274 struct hda_codec *codec, hda_nid_t nid)
4275{
4276 if (nid == codec->afg)
4277 snd_iprintf(buffer, "Power-Map: 0x%02x\n",
4278 snd_hda_codec_read(codec, nid, 0, 0x0fec, 0x0));
4279}
4280
4281static void analog_loop_proc_hook(struct snd_info_buffer *buffer,
4282 struct hda_codec *codec,
4283 unsigned int verb)
4284{
4285 snd_iprintf(buffer, "Analog Loopback: 0x%02x\n",
4286 snd_hda_codec_read(codec, codec->afg, 0, verb, 0));
4287}
4288
4289/* stac92hd71bxx, stac92hd73xx */
4290static void stac92hd7x_proc_hook(struct snd_info_buffer *buffer,
4291 struct hda_codec *codec, hda_nid_t nid)
4292{
4293 stac92hd_proc_hook(buffer, codec, nid);
4294 if (nid == codec->afg)
4295 analog_loop_proc_hook(buffer, codec, 0xfa0);
4296}
4297
4298static void stac9205_proc_hook(struct snd_info_buffer *buffer,
4299 struct hda_codec *codec, hda_nid_t nid)
4300{
4301 if (nid == codec->afg)
4302 analog_loop_proc_hook(buffer, codec, 0xfe0);
4303}
4304
4305static void stac927x_proc_hook(struct snd_info_buffer *buffer,
4306 struct hda_codec *codec, hda_nid_t nid)
4307{
4308 if (nid == codec->afg)
4309 analog_loop_proc_hook(buffer, codec, 0xfeb);
4310}
4311#else
4312#define stac92hd_proc_hook NULL
4313#define stac92hd7x_proc_hook NULL
4314#define stac9205_proc_hook NULL
4315#define stac927x_proc_hook NULL
4316#endif
4317
4034#ifdef SND_HDA_NEEDS_RESUME 4318#ifdef SND_HDA_NEEDS_RESUME
4035static int stac92xx_resume(struct hda_codec *codec) 4319static int stac92xx_resume(struct hda_codec *codec)
4036{ 4320{
4037 struct sigmatel_spec *spec = codec->spec; 4321 struct sigmatel_spec *spec = codec->spec;
4038 4322
4039 stac92xx_set_config_regs(codec); 4323 stac92xx_set_config_regs(codec);
4040 snd_hda_sequence_write(codec, spec->init); 4324 stac92xx_init(codec);
4041 stac_gpio_set(codec, spec->gpio_mask,
4042 spec->gpio_dir, spec->gpio_data);
4043 snd_hda_codec_resume_amp(codec); 4325 snd_hda_codec_resume_amp(codec);
4044 snd_hda_codec_resume_cache(codec); 4326 snd_hda_codec_resume_cache(codec);
4045 /* power down inactive DACs */ 4327 /* fake event to set up pins again to override cached values */
4046 if (spec->dac_list)
4047 stac92xx_power_down(codec);
4048 /* invoke unsolicited event to reset the HP state */
4049 if (spec->hp_detect) 4328 if (spec->hp_detect)
4050 codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); 4329 stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0],
4330 STAC_HP_EVENT);
4331 return 0;
4332}
4333
4334static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state)
4335{
4336 struct sigmatel_spec *spec = codec->spec;
4337 if (spec->eapd_mask)
4338 stac_gpio_set(codec, spec->gpio_mask,
4339 spec->gpio_dir, spec->gpio_data &
4340 ~spec->eapd_mask);
4051 return 0; 4341 return 0;
4052} 4342}
4053#endif 4343#endif
@@ -4059,6 +4349,7 @@ static struct hda_codec_ops stac92xx_patch_ops = {
4059 .free = stac92xx_free, 4349 .free = stac92xx_free,
4060 .unsol_event = stac92xx_unsol_event, 4350 .unsol_event = stac92xx_unsol_event,
4061#ifdef SND_HDA_NEEDS_RESUME 4351#ifdef SND_HDA_NEEDS_RESUME
4352 .suspend = stac92xx_suspend,
4062 .resume = stac92xx_resume, 4353 .resume = stac92xx_resume,
4063#endif 4354#endif
4064}; 4355};
@@ -4081,14 +4372,12 @@ static int patch_stac9200(struct hda_codec *codec)
4081 if (spec->board_config < 0) { 4372 if (spec->board_config < 0) {
4082 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); 4373 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
4083 err = stac92xx_save_bios_config_regs(codec); 4374 err = stac92xx_save_bios_config_regs(codec);
4084 if (err < 0) { 4375 } else
4085 stac92xx_free(codec); 4376 err = stac_save_pin_cfgs(codec,
4086 return err; 4377 stac9200_brd_tbl[spec->board_config]);
4087 } 4378 if (err < 0) {
4088 spec->pin_configs = spec->bios_pin_configs; 4379 stac92xx_free(codec);
4089 } else { 4380 return err;
4090 spec->pin_configs = stac9200_brd_tbl[spec->board_config];
4091 stac92xx_set_config_regs(codec);
4092 } 4381 }
4093 4382
4094 spec->multiout.max_channels = 2; 4383 spec->multiout.max_channels = 2;
@@ -4144,14 +4433,12 @@ static int patch_stac925x(struct hda_codec *codec)
4144 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," 4433 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x,"
4145 "using BIOS defaults\n"); 4434 "using BIOS defaults\n");
4146 err = stac92xx_save_bios_config_regs(codec); 4435 err = stac92xx_save_bios_config_regs(codec);
4147 if (err < 0) { 4436 } else
4148 stac92xx_free(codec); 4437 err = stac_save_pin_cfgs(codec,
4149 return err; 4438 stac925x_brd_tbl[spec->board_config]);
4150 } 4439 if (err < 0) {
4151 spec->pin_configs = spec->bios_pin_configs; 4440 stac92xx_free(codec);
4152 } else if (stac925x_brd_tbl[spec->board_config] != NULL){ 4441 return err;
4153 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
4154 stac92xx_set_config_regs(codec);
4155 } 4442 }
4156 4443
4157 spec->multiout.max_channels = 2; 4444 spec->multiout.max_channels = 2;
@@ -4215,6 +4502,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec)
4215 struct sigmatel_spec *spec; 4502 struct sigmatel_spec *spec;
4216 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2]; 4503 hda_nid_t conn[STAC92HD73_DAC_COUNT + 2];
4217 int err = 0; 4504 int err = 0;
4505 int num_dacs;
4218 4506
4219 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 4507 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
4220 if (spec == NULL) 4508 if (spec == NULL)
@@ -4233,26 +4521,23 @@ again:
4233 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 4521 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4234 " STAC92HD73XX, using BIOS defaults\n"); 4522 " STAC92HD73XX, using BIOS defaults\n");
4235 err = stac92xx_save_bios_config_regs(codec); 4523 err = stac92xx_save_bios_config_regs(codec);
4236 if (err < 0) { 4524 } else
4237 stac92xx_free(codec); 4525 err = stac_save_pin_cfgs(codec,
4238 return err; 4526 stac92hd73xx_brd_tbl[spec->board_config]);
4239 } 4527 if (err < 0) {
4240 spec->pin_configs = spec->bios_pin_configs; 4528 stac92xx_free(codec);
4241 } else { 4529 return err;
4242 spec->pin_configs = stac92hd73xx_brd_tbl[spec->board_config];
4243 stac92xx_set_config_regs(codec);
4244 } 4530 }
4245 4531
4246 spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a, 4532 num_dacs = snd_hda_get_connections(codec, 0x0a,
4247 conn, STAC92HD73_DAC_COUNT + 2) - 1; 4533 conn, STAC92HD73_DAC_COUNT + 2) - 1;
4248 4534
4249 if (spec->multiout.num_dacs < 0) { 4535 if (num_dacs < 3 || num_dacs > 5) {
4250 printk(KERN_WARNING "hda_codec: Could not determine " 4536 printk(KERN_WARNING "hda_codec: Could not determine "
4251 "number of channels defaulting to DAC count\n"); 4537 "number of channels defaulting to DAC count\n");
4252 spec->multiout.num_dacs = STAC92HD73_DAC_COUNT; 4538 num_dacs = STAC92HD73_DAC_COUNT;
4253 } 4539 }
4254 4540 switch (num_dacs) {
4255 switch (spec->multiout.num_dacs) {
4256 case 0x3: /* 6 Channel */ 4541 case 0x3: /* 6 Channel */
4257 spec->mixer = stac92hd73xx_6ch_mixer; 4542 spec->mixer = stac92hd73xx_6ch_mixer;
4258 spec->init = stac92hd73xx_6ch_core_init; 4543 spec->init = stac92hd73xx_6ch_core_init;
@@ -4264,9 +4549,9 @@ again:
4264 case 0x5: /* 10 Channel */ 4549 case 0x5: /* 10 Channel */
4265 spec->mixer = stac92hd73xx_10ch_mixer; 4550 spec->mixer = stac92hd73xx_10ch_mixer;
4266 spec->init = stac92hd73xx_10ch_core_init; 4551 spec->init = stac92hd73xx_10ch_core_init;
4267 }; 4552 }
4553 spec->multiout.dac_nids = spec->dac_nids;
4268 4554
4269 spec->multiout.dac_nids = stac92hd73xx_dac_nids;
4270 spec->aloopback_mask = 0x01; 4555 spec->aloopback_mask = 0x01;
4271 spec->aloopback_shift = 8; 4556 spec->aloopback_shift = 8;
4272 4557
@@ -4298,7 +4583,7 @@ again:
4298 spec->eapd_switch = 0; 4583 spec->eapd_switch = 0;
4299 spec->num_amps = 1; 4584 spec->num_amps = 1;
4300 4585
4301 if (!spec->init) 4586 if (spec->board_config != STAC_DELL_EQ)
4302 spec->init = dell_m6_core_init; 4587 spec->init = dell_m6_core_init;
4303 switch (spec->board_config) { 4588 switch (spec->board_config) {
4304 case STAC_DELL_M6_AMIC: /* Analog Mics */ 4589 case STAC_DELL_M6_AMIC: /* Analog Mics */
@@ -4351,8 +4636,13 @@ again:
4351 return err; 4636 return err;
4352 } 4637 }
4353 4638
4639 if (spec->board_config == STAC_92HD73XX_NO_JD)
4640 spec->hp_detect = 0;
4641
4354 codec->patch_ops = stac92xx_patch_ops; 4642 codec->patch_ops = stac92xx_patch_ops;
4355 4643
4644 codec->proc_widget_hook = stac92hd7x_proc_hook;
4645
4356 return 0; 4646 return 0;
4357} 4647}
4358 4648
@@ -4384,17 +4674,15 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
4384 spec->pwr_nids = stac92hd83xxx_pwr_nids; 4674 spec->pwr_nids = stac92hd83xxx_pwr_nids;
4385 spec->pwr_mapping = stac92hd83xxx_pwr_mapping; 4675 spec->pwr_mapping = stac92hd83xxx_pwr_mapping;
4386 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); 4676 spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids);
4387 spec->multiout.dac_nids = stac92hd83xxx_dac_nids; 4677 spec->multiout.dac_nids = spec->dac_nids;
4388 4678
4389 spec->init = stac92hd83xxx_core_init; 4679 spec->init = stac92hd83xxx_core_init;
4390 switch (codec->vendor_id) { 4680 switch (codec->vendor_id) {
4391 case 0x111d7605: 4681 case 0x111d7605:
4392 spec->multiout.num_dacs = STAC92HD81_DAC_COUNT;
4393 break; 4682 break;
4394 default: 4683 default:
4395 spec->num_pwrs--; 4684 spec->num_pwrs--;
4396 spec->init++; /* switch to config #2 */ 4685 spec->init++; /* switch to config #2 */
4397 spec->multiout.num_dacs = STAC92HD83_DAC_COUNT;
4398 } 4686 }
4399 4687
4400 spec->mixer = stac92hd83xxx_mixer; 4688 spec->mixer = stac92hd83xxx_mixer;
@@ -4413,14 +4701,12 @@ again:
4413 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 4701 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4414 " STAC92HD83XXX, using BIOS defaults\n"); 4702 " STAC92HD83XXX, using BIOS defaults\n");
4415 err = stac92xx_save_bios_config_regs(codec); 4703 err = stac92xx_save_bios_config_regs(codec);
4416 if (err < 0) { 4704 } else
4417 stac92xx_free(codec); 4705 err = stac_save_pin_cfgs(codec,
4418 return err; 4706 stac92hd83xxx_brd_tbl[spec->board_config]);
4419 } 4707 if (err < 0) {
4420 spec->pin_configs = spec->bios_pin_configs; 4708 stac92xx_free(codec);
4421 } else { 4709 return err;
4422 spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config];
4423 stac92xx_set_config_regs(codec);
4424 } 4710 }
4425 4711
4426 err = stac92xx_parse_auto_config(codec, 0x1d, 0); 4712 err = stac92xx_parse_auto_config(codec, 0x1d, 0);
@@ -4441,56 +4727,10 @@ again:
4441 4727
4442 codec->patch_ops = stac92xx_patch_ops; 4728 codec->patch_ops = stac92xx_patch_ops;
4443 4729
4444 return 0; 4730 codec->proc_widget_hook = stac92hd_proc_hook;
4445}
4446
4447#ifdef SND_HDA_NEEDS_RESUME
4448static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr)
4449{
4450 struct sigmatel_spec *spec = codec->spec;
4451 int i;
4452 snd_hda_codec_write_cache(codec, codec->afg, 0,
4453 AC_VERB_SET_POWER_STATE, pwr);
4454
4455 msleep(1);
4456 for (i = 0; i < spec->num_adcs; i++) {
4457 snd_hda_codec_write_cache(codec,
4458 spec->adc_nids[i], 0,
4459 AC_VERB_SET_POWER_STATE, pwr);
4460 }
4461};
4462 4731
4463static int stac92hd71xx_resume(struct hda_codec *codec)
4464{
4465 stac92hd71xx_set_power_state(codec, AC_PWRST_D0);
4466 return stac92xx_resume(codec);
4467}
4468
4469static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state)
4470{
4471 struct sigmatel_spec *spec = codec->spec;
4472
4473 stac92hd71xx_set_power_state(codec, AC_PWRST_D3);
4474 if (spec->eapd_mask)
4475 stac_gpio_set(codec, spec->gpio_mask,
4476 spec->gpio_dir, spec->gpio_data &
4477 ~spec->eapd_mask);
4478 return 0; 4732 return 0;
4479}; 4733}
4480
4481#endif
4482
4483static struct hda_codec_ops stac92hd71bxx_patch_ops = {
4484 .build_controls = stac92xx_build_controls,
4485 .build_pcms = stac92xx_build_pcms,
4486 .init = stac92xx_init,
4487 .free = stac92xx_free,
4488 .unsol_event = stac92xx_unsol_event,
4489#ifdef SND_HDA_NEEDS_RESUME
4490 .resume = stac92hd71xx_resume,
4491 .suspend = stac92hd71xx_suspend,
4492#endif
4493};
4494 4734
4495static struct hda_input_mux stac92hd71bxx_dmux = { 4735static struct hda_input_mux stac92hd71bxx_dmux = {
4496 .num_items = 4, 4736 .num_items = 4,
@@ -4527,14 +4767,12 @@ again:
4527 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 4767 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4528 " STAC92HD71BXX, using BIOS defaults\n"); 4768 " STAC92HD71BXX, using BIOS defaults\n");
4529 err = stac92xx_save_bios_config_regs(codec); 4769 err = stac92xx_save_bios_config_regs(codec);
4530 if (err < 0) { 4770 } else
4531 stac92xx_free(codec); 4771 err = stac_save_pin_cfgs(codec,
4532 return err; 4772 stac92hd71bxx_brd_tbl[spec->board_config]);
4533 } 4773 if (err < 0) {
4534 spec->pin_configs = spec->bios_pin_configs; 4774 stac92xx_free(codec);
4535 } else { 4775 return err;
4536 spec->pin_configs = stac92hd71bxx_brd_tbl[spec->board_config];
4537 stac92xx_set_config_regs(codec);
4538 } 4776 }
4539 4777
4540 if (spec->board_config > STAC_92HD71BXX_REF) { 4778 if (spec->board_config > STAC_92HD71BXX_REF) {
@@ -4557,21 +4795,21 @@ again:
4557 switch (spec->board_config) { 4795 switch (spec->board_config) {
4558 case STAC_HP_M4: 4796 case STAC_HP_M4:
4559 /* Enable VREF power saving on GPIO1 detect */ 4797 /* Enable VREF power saving on GPIO1 detect */
4798 err = stac_add_event(spec, codec->afg,
4799 STAC_VREF_EVENT, 0x02);
4800 if (err < 0)
4801 return err;
4560 snd_hda_codec_write_cache(codec, codec->afg, 0, 4802 snd_hda_codec_write_cache(codec, codec->afg, 0,
4561 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); 4803 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02);
4562 snd_hda_codec_write_cache(codec, codec->afg, 0, 4804 snd_hda_codec_write_cache(codec, codec->afg, 0,
4563 AC_VERB_SET_UNSOLICITED_ENABLE, 4805 AC_VERB_SET_UNSOLICITED_ENABLE,
4564 (AC_USRSP_EN | STAC_VREF_EVENT | 0x01)); 4806 AC_USRSP_EN | err);
4565 spec->gpio_mask |= 0x02; 4807 spec->gpio_mask |= 0x02;
4566 break; 4808 break;
4567 } 4809 }
4568 if ((codec->revision_id & 0xf) == 0 || 4810 if ((codec->revision_id & 0xf) == 0 ||
4569 (codec->revision_id & 0xf) == 1) { 4811 (codec->revision_id & 0xf) == 1)
4570#ifdef SND_HDA_NEEDS_RESUME
4571 codec->patch_ops = stac92hd71bxx_patch_ops;
4572#endif
4573 spec->stream_delay = 40; /* 40 milliseconds */ 4812 spec->stream_delay = 40; /* 40 milliseconds */
4574 }
4575 4813
4576 /* no output amps */ 4814 /* no output amps */
4577 spec->num_pwrs = 0; 4815 spec->num_pwrs = 0;
@@ -4580,15 +4818,11 @@ again:
4580 4818
4581 /* disable VSW */ 4819 /* disable VSW */
4582 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; 4820 spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF];
4583 stac92xx_set_config_reg(codec, 0xf, 0x40f000f0); 4821 stac_change_pin_config(codec, 0xf, 0x40f000f0);
4584 break; 4822 break;
4585 case 0x111d7603: /* 6 Port with Analog Mixer */ 4823 case 0x111d7603: /* 6 Port with Analog Mixer */
4586 if ((codec->revision_id & 0xf) == 1) { 4824 if ((codec->revision_id & 0xf) == 1)
4587#ifdef SND_HDA_NEEDS_RESUME
4588 codec->patch_ops = stac92hd71bxx_patch_ops;
4589#endif
4590 spec->stream_delay = 40; /* 40 milliseconds */ 4825 spec->stream_delay = 40; /* 40 milliseconds */
4591 }
4592 4826
4593 /* no output amps */ 4827 /* no output amps */
4594 spec->num_pwrs = 0; 4828 spec->num_pwrs = 0;
@@ -4618,7 +4852,7 @@ again:
4618 switch (spec->board_config) { 4852 switch (spec->board_config) {
4619 case STAC_HP_M4: 4853 case STAC_HP_M4:
4620 /* enable internal microphone */ 4854 /* enable internal microphone */
4621 stac92xx_set_config_reg(codec, 0x0e, 0x01813040); 4855 stac_change_pin_config(codec, 0x0e, 0x01813040);
4622 stac92xx_auto_set_pinctl(codec, 0x0e, 4856 stac92xx_auto_set_pinctl(codec, 0x0e,
4623 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); 4857 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80);
4624 /* fallthru */ 4858 /* fallthru */
@@ -4639,9 +4873,7 @@ again:
4639 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); 4873 spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids);
4640 }; 4874 };
4641 4875
4642 spec->multiout.num_dacs = 1; 4876 spec->multiout.dac_nids = spec->dac_nids;
4643 spec->multiout.hp_nid = 0x11;
4644 spec->multiout.dac_nids = stac92hd71bxx_dac_nids;
4645 if (spec->dinput_mux) 4877 if (spec->dinput_mux)
4646 spec->private_dimux.num_items += 4878 spec->private_dimux.num_items +=
4647 spec->num_dmics - 4879 spec->num_dmics -
@@ -4663,6 +4895,8 @@ again:
4663 return err; 4895 return err;
4664 } 4896 }
4665 4897
4898 codec->proc_widget_hook = stac92hd7x_proc_hook;
4899
4666 return 0; 4900 return 0;
4667}; 4901};
4668 4902
@@ -4724,14 +4958,12 @@ static int patch_stac922x(struct hda_codec *codec)
4724 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " 4958 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
4725 "using BIOS defaults\n"); 4959 "using BIOS defaults\n");
4726 err = stac92xx_save_bios_config_regs(codec); 4960 err = stac92xx_save_bios_config_regs(codec);
4727 if (err < 0) { 4961 } else
4728 stac92xx_free(codec); 4962 err = stac_save_pin_cfgs(codec,
4729 return err; 4963 stac922x_brd_tbl[spec->board_config]);
4730 } 4964 if (err < 0) {
4731 spec->pin_configs = spec->bios_pin_configs; 4965 stac92xx_free(codec);
4732 } else if (stac922x_brd_tbl[spec->board_config] != NULL) { 4966 return err;
4733 spec->pin_configs = stac922x_brd_tbl[spec->board_config];
4734 stac92xx_set_config_regs(codec);
4735 } 4967 }
4736 4968
4737 spec->adc_nids = stac922x_adc_nids; 4969 spec->adc_nids = stac922x_adc_nids;
@@ -4794,14 +5026,12 @@ static int patch_stac927x(struct hda_codec *codec)
4794 snd_printdd(KERN_INFO "hda_codec: Unknown model for" 5026 snd_printdd(KERN_INFO "hda_codec: Unknown model for"
4795 "STAC927x, using BIOS defaults\n"); 5027 "STAC927x, using BIOS defaults\n");
4796 err = stac92xx_save_bios_config_regs(codec); 5028 err = stac92xx_save_bios_config_regs(codec);
4797 if (err < 0) { 5029 } else
4798 stac92xx_free(codec); 5030 err = stac_save_pin_cfgs(codec,
4799 return err; 5031 stac927x_brd_tbl[spec->board_config]);
4800 } 5032 if (err < 0) {
4801 spec->pin_configs = spec->bios_pin_configs; 5033 stac92xx_free(codec);
4802 } else { 5034 return err;
4803 spec->pin_configs = stac927x_brd_tbl[spec->board_config];
4804 stac92xx_set_config_regs(codec);
4805 } 5035 }
4806 5036
4807 spec->digbeep_nid = 0x23; 5037 spec->digbeep_nid = 0x23;
@@ -4831,15 +5061,15 @@ static int patch_stac927x(struct hda_codec *codec)
4831 case 0x10280209: 5061 case 0x10280209:
4832 case 0x1028022e: 5062 case 0x1028022e:
4833 /* correct the device field to SPDIF out */ 5063 /* correct the device field to SPDIF out */
4834 stac92xx_set_config_reg(codec, 0x21, 0x01442070); 5064 stac_change_pin_config(codec, 0x21, 0x01442070);
4835 break; 5065 break;
4836 }; 5066 };
4837 /* configure the analog microphone on some laptops */ 5067 /* configure the analog microphone on some laptops */
4838 stac92xx_set_config_reg(codec, 0x0c, 0x90a79130); 5068 stac_change_pin_config(codec, 0x0c, 0x90a79130);
4839 /* correct the front output jack as a hp out */ 5069 /* correct the front output jack as a hp out */
4840 stac92xx_set_config_reg(codec, 0x0f, 0x0227011f); 5070 stac_change_pin_config(codec, 0x0f, 0x0227011f);
4841 /* correct the front input jack as a mic */ 5071 /* correct the front input jack as a mic */
4842 stac92xx_set_config_reg(codec, 0x0e, 0x02a79130); 5072 stac_change_pin_config(codec, 0x0e, 0x02a79130);
4843 /* fallthru */ 5073 /* fallthru */
4844 case STAC_DELL_3ST: 5074 case STAC_DELL_3ST:
4845 /* GPIO2 High = Enable EAPD */ 5075 /* GPIO2 High = Enable EAPD */
@@ -4887,6 +5117,8 @@ static int patch_stac927x(struct hda_codec *codec)
4887 5117
4888 codec->patch_ops = stac92xx_patch_ops; 5118 codec->patch_ops = stac92xx_patch_ops;
4889 5119
5120 codec->proc_widget_hook = stac927x_proc_hook;
5121
4890 /* 5122 /*
4891 * !!FIXME!! 5123 * !!FIXME!!
4892 * The STAC927x seem to require fairly long delays for certain 5124 * The STAC927x seem to require fairly long delays for certain
@@ -4899,6 +5131,10 @@ static int patch_stac927x(struct hda_codec *codec)
4899 */ 5131 */
4900 codec->bus->needs_damn_long_delay = 1; 5132 codec->bus->needs_damn_long_delay = 1;
4901 5133
5134 /* no jack detecion for ref-no-jd model */
5135 if (spec->board_config == STAC_D965_REF_NO_JD)
5136 spec->hp_detect = 0;
5137
4902 return 0; 5138 return 0;
4903} 5139}
4904 5140
@@ -4921,14 +5157,12 @@ static int patch_stac9205(struct hda_codec *codec)
4921 if (spec->board_config < 0) { 5157 if (spec->board_config < 0) {
4922 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); 5158 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
4923 err = stac92xx_save_bios_config_regs(codec); 5159 err = stac92xx_save_bios_config_regs(codec);
4924 if (err < 0) { 5160 } else
4925 stac92xx_free(codec); 5161 err = stac_save_pin_cfgs(codec,
4926 return err; 5162 stac9205_brd_tbl[spec->board_config]);
4927 } 5163 if (err < 0) {
4928 spec->pin_configs = spec->bios_pin_configs; 5164 stac92xx_free(codec);
4929 } else { 5165 return err;
4930 spec->pin_configs = stac9205_brd_tbl[spec->board_config];
4931 stac92xx_set_config_regs(codec);
4932 } 5166 }
4933 5167
4934 spec->digbeep_nid = 0x23; 5168 spec->digbeep_nid = 0x23;
@@ -4955,15 +5189,18 @@ static int patch_stac9205(struct hda_codec *codec)
4955 switch (spec->board_config){ 5189 switch (spec->board_config){
4956 case STAC_9205_DELL_M43: 5190 case STAC_9205_DELL_M43:
4957 /* Enable SPDIF in/out */ 5191 /* Enable SPDIF in/out */
4958 stac92xx_set_config_reg(codec, 0x1f, 0x01441030); 5192 stac_change_pin_config(codec, 0x1f, 0x01441030);
4959 stac92xx_set_config_reg(codec, 0x20, 0x1c410030); 5193 stac_change_pin_config(codec, 0x20, 0x1c410030);
4960 5194
4961 /* Enable unsol response for GPIO4/Dock HP connection */ 5195 /* Enable unsol response for GPIO4/Dock HP connection */
5196 err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01);
5197 if (err < 0)
5198 return err;
4962 snd_hda_codec_write_cache(codec, codec->afg, 0, 5199 snd_hda_codec_write_cache(codec, codec->afg, 0,
4963 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); 5200 AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10);
4964 snd_hda_codec_write_cache(codec, codec->afg, 0, 5201 snd_hda_codec_write_cache(codec, codec->afg, 0,
4965 AC_VERB_SET_UNSOLICITED_ENABLE, 5202 AC_VERB_SET_UNSOLICITED_ENABLE,
4966 (AC_USRSP_EN | STAC_HP_EVENT)); 5203 AC_USRSP_EN | err);
4967 5204
4968 spec->gpio_dir = 0x0b; 5205 spec->gpio_dir = 0x0b;
4969 spec->eapd_mask = 0x01; 5206 spec->eapd_mask = 0x01;
@@ -5001,6 +5238,8 @@ static int patch_stac9205(struct hda_codec *codec)
5001 5238
5002 codec->patch_ops = stac92xx_patch_ops; 5239 codec->patch_ops = stac92xx_patch_ops;
5003 5240
5241 codec->proc_widget_hook = stac9205_proc_hook;
5242
5004 return 0; 5243 return 0;
5005} 5244}
5006 5245
@@ -5057,29 +5296,11 @@ static struct hda_verb vaio_ar_init[] = {
5057 {} 5296 {}
5058}; 5297};
5059 5298
5060/* bind volumes of both NID 0x02 and 0x05 */
5061static struct hda_bind_ctls vaio_bind_master_vol = {
5062 .ops = &snd_hda_bind_vol,
5063 .values = {
5064 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
5065 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
5066 0
5067 },
5068};
5069
5070/* bind volumes of both NID 0x02 and 0x05 */
5071static struct hda_bind_ctls vaio_bind_master_sw = {
5072 .ops = &snd_hda_bind_sw,
5073 .values = {
5074 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
5075 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
5076 0,
5077 },
5078};
5079
5080static struct snd_kcontrol_new vaio_mixer[] = { 5299static struct snd_kcontrol_new vaio_mixer[] = {
5081 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol), 5300 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT),
5082 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw), 5301 HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT),
5302 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT),
5303 HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT),
5083 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ 5304 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
5084 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), 5305 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
5085 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), 5306 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
@@ -5095,8 +5316,10 @@ static struct snd_kcontrol_new vaio_mixer[] = {
5095}; 5316};
5096 5317
5097static struct snd_kcontrol_new vaio_ar_mixer[] = { 5318static struct snd_kcontrol_new vaio_ar_mixer[] = {
5098 HDA_BIND_VOL("Master Playback Volume", &vaio_bind_master_vol), 5319 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT),
5099 HDA_BIND_SW("Master Playback Switch", &vaio_bind_master_sw), 5320 HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT),
5321 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT),
5322 HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT),
5100 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ 5323 /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */
5101 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), 5324 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT),
5102 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), 5325 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT),
@@ -5137,7 +5360,7 @@ static int stac9872_vaio_init(struct hda_codec *codec)
5137 5360
5138static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) 5361static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res)
5139{ 5362{
5140 if (get_hp_pin_presence(codec, 0x0a)) { 5363 if (get_pin_presence(codec, 0x0a)) {
5141 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); 5364 stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN);
5142 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); 5365 stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN);
5143 } else { 5366 } else {
@@ -5248,7 +5471,7 @@ static int patch_stac9872(struct hda_codec *codec)
5248/* 5471/*
5249 * patch entries 5472 * patch entries
5250 */ 5473 */
5251struct hda_codec_preset snd_hda_preset_sigmatel[] = { 5474static struct hda_codec_preset snd_hda_preset_sigmatel[] = {
5252 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, 5475 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 },
5253 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, 5476 { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x },
5254 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, 5477 { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x },
@@ -5312,3 +5535,27 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
5312 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, 5535 { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx },
5313 {} /* terminator */ 5536 {} /* terminator */
5314}; 5537};
5538
5539MODULE_ALIAS("snd-hda-codec-id:8384*");
5540MODULE_ALIAS("snd-hda-codec-id:111d*");
5541
5542MODULE_LICENSE("GPL");
5543MODULE_DESCRIPTION("IDT/Sigmatel HD-audio codec");
5544
5545static struct hda_codec_preset_list sigmatel_list = {
5546 .preset = snd_hda_preset_sigmatel,
5547 .owner = THIS_MODULE,
5548};
5549
5550static int __init patch_sigmatel_init(void)
5551{
5552 return snd_hda_add_codec_preset(&sigmatel_list);
5553}
5554
5555static void __exit patch_sigmatel_exit(void)
5556{
5557 snd_hda_delete_codec_preset(&sigmatel_list);
5558}
5559
5560module_init(patch_sigmatel_init)
5561module_exit(patch_sigmatel_exit)
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 63e4871e5d8f..c761394cbe84 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -47,15 +47,11 @@
47#include <sound/asoundef.h> 47#include <sound/asoundef.h>
48#include "hda_codec.h" 48#include "hda_codec.h"
49#include "hda_local.h" 49#include "hda_local.h"
50#include "hda_patch.h"
51 50
52/* amp values */ 51/* amp values */
53#define AMP_VAL_IDX_SHIFT 19 52#define AMP_VAL_IDX_SHIFT 19
54#define AMP_VAL_IDX_MASK (0x0f<<19) 53#define AMP_VAL_IDX_MASK (0x0f<<19)
55 54
56#define NUM_CONTROL_ALLOC 32
57#define NUM_VERB_ALLOC 32
58
59/* Pin Widget NID */ 55/* Pin Widget NID */
60#define VT1708_HP_NID 0x13 56#define VT1708_HP_NID 0x13
61#define VT1708_DIGOUT_NID 0x14 57#define VT1708_DIGOUT_NID 0x14
@@ -145,8 +141,6 @@ enum {
145 AUTO_SEQ_SIDE 141 AUTO_SEQ_SIDE
146}; 142};
147 143
148#define get_amp_nid(kc) ((kc)->private_value & 0xffff)
149
150/* Some VT1708S based boards gets the micboost setting wrong, so we have 144/* Some VT1708S based boards gets the micboost setting wrong, so we have
151 * to apply some brute-force and re-write the TLV's by software. */ 145 * to apply some brute-force and re-write the TLV's by software. */
152static int mic_boost_tlv(struct snd_kcontrol *kcontrol, int op_flag, 146static int mic_boost_tlv(struct snd_kcontrol *kcontrol, int op_flag,
@@ -227,8 +221,7 @@ struct via_spec {
227 221
228 /* dynamic controls, init_verbs and input_mux */ 222 /* dynamic controls, init_verbs and input_mux */
229 struct auto_pin_cfg autocfg; 223 struct auto_pin_cfg autocfg;
230 unsigned int num_kctl_alloc, num_kctl_used; 224 struct snd_array kctls;
231 struct snd_kcontrol_new *kctl_alloc;
232 struct hda_input_mux private_imux[2]; 225 struct hda_input_mux private_imux[2];
233 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 226 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
234 227
@@ -272,33 +265,31 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
272{ 265{
273 struct snd_kcontrol_new *knew; 266 struct snd_kcontrol_new *knew;
274 267
275 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 268 snd_array_init(&spec->kctls, sizeof(*knew), 32);
276 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 269 knew = snd_array_new(&spec->kctls);
277 270 if (!knew)
278 /* array + terminator */ 271 return -ENOMEM;
279 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
280 if (!knew)
281 return -ENOMEM;
282 if (spec->kctl_alloc) {
283 memcpy(knew, spec->kctl_alloc,
284 sizeof(*knew) * spec->num_kctl_alloc);
285 kfree(spec->kctl_alloc);
286 }
287 spec->kctl_alloc = knew;
288 spec->num_kctl_alloc = num;
289 }
290
291 knew = &spec->kctl_alloc[spec->num_kctl_used];
292 *knew = vt1708_control_templates[type]; 272 *knew = vt1708_control_templates[type];
293 knew->name = kstrdup(name, GFP_KERNEL); 273 knew->name = kstrdup(name, GFP_KERNEL);
294
295 if (!knew->name) 274 if (!knew->name)
296 return -ENOMEM; 275 return -ENOMEM;
297 knew->private_value = val; 276 knew->private_value = val;
298 spec->num_kctl_used++;
299 return 0; 277 return 0;
300} 278}
301 279
280static void via_free_kctls(struct hda_codec *codec)
281{
282 struct via_spec *spec = codec->spec;
283
284 if (spec->kctls.list) {
285 struct snd_kcontrol_new *kctl = spec->kctls.list;
286 int i;
287 for (i = 0; i < spec->kctls.used; i++)
288 kfree(kctl[i].name);
289 }
290 snd_array_free(&spec->kctls);
291}
292
302/* create input playback/capture controls for the given pin */ 293/* create input playback/capture controls for the given pin */
303static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin, 294static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
304 const char *ctlname, int idx, int mix_nid) 295 const char *ctlname, int idx, int mix_nid)
@@ -896,6 +887,7 @@ static int via_build_controls(struct hda_codec *codec)
896 if (err < 0) 887 if (err < 0)
897 return err; 888 return err;
898 } 889 }
890 via_free_kctls(codec); /* no longer needed */
899 return 0; 891 return 0;
900} 892}
901 893
@@ -941,17 +933,11 @@ static int via_build_pcms(struct hda_codec *codec)
941static void via_free(struct hda_codec *codec) 933static void via_free(struct hda_codec *codec)
942{ 934{
943 struct via_spec *spec = codec->spec; 935 struct via_spec *spec = codec->spec;
944 unsigned int i;
945 936
946 if (!spec) 937 if (!spec)
947 return; 938 return;
948 939
949 if (spec->kctl_alloc) { 940 via_free_kctls(codec);
950 for (i = 0; i < spec->num_kctl_used; i++)
951 kfree(spec->kctl_alloc[i].name);
952 kfree(spec->kctl_alloc);
953 }
954
955 kfree(codec->spec); 941 kfree(codec->spec);
956} 942}
957 943
@@ -1373,8 +1359,8 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
1373 if (spec->autocfg.dig_in_pin) 1359 if (spec->autocfg.dig_in_pin)
1374 spec->dig_in_nid = VT1708_DIGIN_NID; 1360 spec->dig_in_nid = VT1708_DIGIN_NID;
1375 1361
1376 if (spec->kctl_alloc) 1362 if (spec->kctls.list)
1377 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1363 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1378 1364
1379 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs; 1365 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
1380 1366
@@ -1846,8 +1832,8 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
1846 if (spec->autocfg.dig_in_pin) 1832 if (spec->autocfg.dig_in_pin)
1847 spec->dig_in_nid = VT1709_DIGIN_NID; 1833 spec->dig_in_nid = VT1709_DIGIN_NID;
1848 1834
1849 if (spec->kctl_alloc) 1835 if (spec->kctls.list)
1850 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1836 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1851 1837
1852 spec->input_mux = &spec->private_imux[0]; 1838 spec->input_mux = &spec->private_imux[0];
1853 1839
@@ -2390,8 +2376,8 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
2390 if (spec->autocfg.dig_in_pin) 2376 if (spec->autocfg.dig_in_pin)
2391 spec->dig_in_nid = VT1708B_DIGIN_NID; 2377 spec->dig_in_nid = VT1708B_DIGIN_NID;
2392 2378
2393 if (spec->kctl_alloc) 2379 if (spec->kctls.list)
2394 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2380 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2395 2381
2396 spec->input_mux = &spec->private_imux[0]; 2382 spec->input_mux = &spec->private_imux[0];
2397 2383
@@ -2855,8 +2841,8 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
2855 2841
2856 spec->extra_dig_out_nid = 0x15; 2842 spec->extra_dig_out_nid = 0x15;
2857 2843
2858 if (spec->kctl_alloc) 2844 if (spec->kctls.list)
2859 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2845 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2860 2846
2861 spec->input_mux = &spec->private_imux[0]; 2847 spec->input_mux = &spec->private_imux[0];
2862 2848
@@ -3174,8 +3160,8 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
3174 3160
3175 spec->extra_dig_out_nid = 0x1B; 3161 spec->extra_dig_out_nid = 0x1B;
3176 3162
3177 if (spec->kctl_alloc) 3163 if (spec->kctls.list)
3178 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3164 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3179 3165
3180 spec->input_mux = &spec->private_imux[0]; 3166 spec->input_mux = &spec->private_imux[0];
3181 3167
@@ -3262,74 +3248,97 @@ static int patch_vt1702(struct hda_codec *codec)
3262/* 3248/*
3263 * patch entries 3249 * patch entries
3264 */ 3250 */
3265struct hda_codec_preset snd_hda_preset_via[] = { 3251static struct hda_codec_preset snd_hda_preset_via[] = {
3266 { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708}, 3252 { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708},
3267 { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708}, 3253 { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708},
3268 { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708}, 3254 { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708},
3269 { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708}, 3255 { .id = 0x1106170b, .name = "VT1708", .patch = patch_vt1708},
3270 { .id = 0x1106E710, .name = "VIA VT1709 10-Ch", 3256 { .id = 0x1106e710, .name = "VT1709 10-Ch",
3271 .patch = patch_vt1709_10ch}, 3257 .patch = patch_vt1709_10ch},
3272 { .id = 0x1106E711, .name = "VIA VT1709 10-Ch", 3258 { .id = 0x1106e711, .name = "VT1709 10-Ch",
3273 .patch = patch_vt1709_10ch}, 3259 .patch = patch_vt1709_10ch},
3274 { .id = 0x1106E712, .name = "VIA VT1709 10-Ch", 3260 { .id = 0x1106e712, .name = "VT1709 10-Ch",
3275 .patch = patch_vt1709_10ch}, 3261 .patch = patch_vt1709_10ch},
3276 { .id = 0x1106E713, .name = "VIA VT1709 10-Ch", 3262 { .id = 0x1106e713, .name = "VT1709 10-Ch",
3277 .patch = patch_vt1709_10ch}, 3263 .patch = patch_vt1709_10ch},
3278 { .id = 0x1106E714, .name = "VIA VT1709 6-Ch", 3264 { .id = 0x1106e714, .name = "VT1709 6-Ch",
3279 .patch = patch_vt1709_6ch}, 3265 .patch = patch_vt1709_6ch},
3280 { .id = 0x1106E715, .name = "VIA VT1709 6-Ch", 3266 { .id = 0x1106e715, .name = "VT1709 6-Ch",
3281 .patch = patch_vt1709_6ch}, 3267 .patch = patch_vt1709_6ch},
3282 { .id = 0x1106E716, .name = "VIA VT1709 6-Ch", 3268 { .id = 0x1106e716, .name = "VT1709 6-Ch",
3283 .patch = patch_vt1709_6ch}, 3269 .patch = patch_vt1709_6ch},
3284 { .id = 0x1106E717, .name = "VIA VT1709 6-Ch", 3270 { .id = 0x1106e717, .name = "VT1709 6-Ch",
3285 .patch = patch_vt1709_6ch}, 3271 .patch = patch_vt1709_6ch},
3286 { .id = 0x1106E720, .name = "VIA VT1708B 8-Ch", 3272 { .id = 0x1106e720, .name = "VT1708B 8-Ch",
3287 .patch = patch_vt1708B_8ch}, 3273 .patch = patch_vt1708B_8ch},
3288 { .id = 0x1106E721, .name = "VIA VT1708B 8-Ch", 3274 { .id = 0x1106e721, .name = "VT1708B 8-Ch",
3289 .patch = patch_vt1708B_8ch}, 3275 .patch = patch_vt1708B_8ch},
3290 { .id = 0x1106E722, .name = "VIA VT1708B 8-Ch", 3276 { .id = 0x1106e722, .name = "VT1708B 8-Ch",
3291 .patch = patch_vt1708B_8ch}, 3277 .patch = patch_vt1708B_8ch},
3292 { .id = 0x1106E723, .name = "VIA VT1708B 8-Ch", 3278 { .id = 0x1106e723, .name = "VT1708B 8-Ch",
3293 .patch = patch_vt1708B_8ch}, 3279 .patch = patch_vt1708B_8ch},
3294 { .id = 0x1106E724, .name = "VIA VT1708B 4-Ch", 3280 { .id = 0x1106e724, .name = "VT1708B 4-Ch",
3295 .patch = patch_vt1708B_4ch}, 3281 .patch = patch_vt1708B_4ch},
3296 { .id = 0x1106E725, .name = "VIA VT1708B 4-Ch", 3282 { .id = 0x1106e725, .name = "VT1708B 4-Ch",
3297 .patch = patch_vt1708B_4ch}, 3283 .patch = patch_vt1708B_4ch},
3298 { .id = 0x1106E726, .name = "VIA VT1708B 4-Ch", 3284 { .id = 0x1106e726, .name = "VT1708B 4-Ch",
3299 .patch = patch_vt1708B_4ch}, 3285 .patch = patch_vt1708B_4ch},
3300 { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch", 3286 { .id = 0x1106e727, .name = "VT1708B 4-Ch",
3301 .patch = patch_vt1708B_4ch}, 3287 .patch = patch_vt1708B_4ch},
3302 { .id = 0x11060397, .name = "VIA VT1708S", 3288 { .id = 0x11060397, .name = "VT1708S",
3303 .patch = patch_vt1708S}, 3289 .patch = patch_vt1708S},
3304 { .id = 0x11061397, .name = "VIA VT1708S", 3290 { .id = 0x11061397, .name = "VT1708S",
3305 .patch = patch_vt1708S}, 3291 .patch = patch_vt1708S},
3306 { .id = 0x11062397, .name = "VIA VT1708S", 3292 { .id = 0x11062397, .name = "VT1708S",
3307 .patch = patch_vt1708S}, 3293 .patch = patch_vt1708S},
3308 { .id = 0x11063397, .name = "VIA VT1708S", 3294 { .id = 0x11063397, .name = "VT1708S",
3309 .patch = patch_vt1708S}, 3295 .patch = patch_vt1708S},
3310 { .id = 0x11064397, .name = "VIA VT1708S", 3296 { .id = 0x11064397, .name = "VT1708S",
3311 .patch = patch_vt1708S}, 3297 .patch = patch_vt1708S},
3312 { .id = 0x11065397, .name = "VIA VT1708S", 3298 { .id = 0x11065397, .name = "VT1708S",
3313 .patch = patch_vt1708S}, 3299 .patch = patch_vt1708S},
3314 { .id = 0x11066397, .name = "VIA VT1708S", 3300 { .id = 0x11066397, .name = "VT1708S",
3315 .patch = patch_vt1708S}, 3301 .patch = patch_vt1708S},
3316 { .id = 0x11067397, .name = "VIA VT1708S", 3302 { .id = 0x11067397, .name = "VT1708S",
3317 .patch = patch_vt1708S}, 3303 .patch = patch_vt1708S},
3318 { .id = 0x11060398, .name = "VIA VT1702", 3304 { .id = 0x11060398, .name = "VT1702",
3319 .patch = patch_vt1702}, 3305 .patch = patch_vt1702},
3320 { .id = 0x11061398, .name = "VIA VT1702", 3306 { .id = 0x11061398, .name = "VT1702",
3321 .patch = patch_vt1702}, 3307 .patch = patch_vt1702},
3322 { .id = 0x11062398, .name = "VIA VT1702", 3308 { .id = 0x11062398, .name = "VT1702",
3323 .patch = patch_vt1702}, 3309 .patch = patch_vt1702},
3324 { .id = 0x11063398, .name = "VIA VT1702", 3310 { .id = 0x11063398, .name = "VT1702",
3325 .patch = patch_vt1702}, 3311 .patch = patch_vt1702},
3326 { .id = 0x11064398, .name = "VIA VT1702", 3312 { .id = 0x11064398, .name = "VT1702",
3327 .patch = patch_vt1702}, 3313 .patch = patch_vt1702},
3328 { .id = 0x11065398, .name = "VIA VT1702", 3314 { .id = 0x11065398, .name = "VT1702",
3329 .patch = patch_vt1702}, 3315 .patch = patch_vt1702},
3330 { .id = 0x11066398, .name = "VIA VT1702", 3316 { .id = 0x11066398, .name = "VT1702",
3331 .patch = patch_vt1702}, 3317 .patch = patch_vt1702},
3332 { .id = 0x11067398, .name = "VIA VT1702", 3318 { .id = 0x11067398, .name = "VT1702",
3333 .patch = patch_vt1702}, 3319 .patch = patch_vt1702},
3334 {} /* terminator */ 3320 {} /* terminator */
3335}; 3321};
3322
3323MODULE_ALIAS("snd-hda-codec-id:1106*");
3324
3325static struct hda_codec_preset_list via_list = {
3326 .preset = snd_hda_preset_via,
3327 .owner = THIS_MODULE,
3328};
3329
3330MODULE_LICENSE("GPL");
3331MODULE_DESCRIPTION("VIA HD-audio codec");
3332
3333static int __init patch_via_init(void)
3334{
3335 return snd_hda_add_codec_preset(&via_list);
3336}
3337
3338static void __exit patch_via_exit(void)
3339{
3340 snd_hda_delete_codec_preset(&via_list);
3341}
3342
3343module_init(patch_via_init)
3344module_exit(patch_via_exit)
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 1b3f11702713..0dfa0540ce2c 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -382,23 +382,25 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id)
382 unsigned char status_mask = 382 unsigned char status_mask =
383 VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM; 383 VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX | VT1724_IRQ_MTPCM;
384 int handled = 0; 384 int handled = 0;
385#ifdef CONFIG_SND_DEBUG
386 int timeout = 0; 385 int timeout = 0;
387#endif
388 386
389 while (1) { 387 while (1) {
390 status = inb(ICEREG1724(ice, IRQSTAT)); 388 status = inb(ICEREG1724(ice, IRQSTAT));
391 status &= status_mask; 389 status &= status_mask;
392 if (status == 0) 390 if (status == 0)
393 break; 391 break;
394#ifdef CONFIG_SND_DEBUG
395 if (++timeout > 10) { 392 if (++timeout > 10) {
396 printk(KERN_ERR 393 status = inb(ICEREG1724(ice, IRQSTAT));
397 "ice1724: Too long irq loop, status = 0x%x\n", 394 printk(KERN_ERR "ice1724: Too long irq loop, "
398 status); 395 "status = 0x%x\n", status);
396 if (status & VT1724_IRQ_MPU_TX) {
397 printk(KERN_ERR "ice1724: Disabling MPU_TX\n");
398 outb(inb(ICEREG1724(ice, IRQMASK)) |
399 VT1724_IRQ_MPU_TX,
400 ICEREG1724(ice, IRQMASK));
401 }
399 break; 402 break;
400 } 403 }
401#endif
402 handled = 1; 404 handled = 1;
403 if (status & VT1724_IRQ_MPU_TX) { 405 if (status & VT1724_IRQ_MPU_TX) {
404 spin_lock(&ice->reg_lock); 406 spin_lock(&ice->reg_lock);
@@ -2351,7 +2353,6 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2351{ 2353{
2352 struct snd_ice1712 *ice; 2354 struct snd_ice1712 *ice;
2353 int err; 2355 int err;
2354 unsigned char mask;
2355 static struct snd_device_ops ops = { 2356 static struct snd_device_ops ops = {
2356 .dev_free = snd_vt1724_dev_free, 2357 .dev_free = snd_vt1724_dev_free,
2357 }; 2358 };
@@ -2412,9 +2413,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
2412 return -EIO; 2413 return -EIO;
2413 } 2414 }
2414 2415
2415 /* unmask used interrupts */ 2416 /* MPU_RX and TX irq masks are cleared later dynamically */
2416 mask = VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX; 2417 outb(VT1724_IRQ_MPU_RX | VT1724_IRQ_MPU_TX , ICEREG1724(ice, IRQMASK));
2417 outb(mask, ICEREG1724(ice, IRQMASK)); 2418
2418 /* don't handle FIFO overrun/underruns (just yet), 2419 /* don't handle FIFO overrun/underruns (just yet),
2419 * since they cause machine lockups 2420 * since they cause machine lockups
2420 */ 2421 */
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 9ff3f9e34404..59bbaf8f3e5b 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -1670,7 +1670,7 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
1670 return IRQ_NONE; 1670 return IRQ_NONE;
1671 1671
1672 if (status & HV_INT_PENDING) 1672 if (status & HV_INT_PENDING)
1673 tasklet_hi_schedule(&chip->hwvol_tq); 1673 tasklet_schedule(&chip->hwvol_tq);
1674 1674
1675 /* 1675 /*
1676 * ack an assp int if its running 1676 * ack an assp int if its running
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c
index ae7601f353a7..f23a73577c22 100644
--- a/sound/pci/mixart/mixart.c
+++ b/sound/pci/mixart/mixart.c
@@ -1010,7 +1010,7 @@ static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *
1010 .dev_free = snd_mixart_chip_dev_free, 1010 .dev_free = snd_mixart_chip_dev_free,
1011 }; 1011 };
1012 1012
1013 mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1013 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1014 if (! chip) { 1014 if (! chip) {
1015 snd_printk(KERN_ERR "cannot allocate chip\n"); 1015 snd_printk(KERN_ERR "cannot allocate chip\n");
1016 return -ENOMEM; 1016 return -ENOMEM;
@@ -1025,6 +1025,7 @@ static int __devinit snd_mixart_create(struct mixart_mgr *mgr, struct snd_card *
1025 return err; 1025 return err;
1026 } 1026 }
1027 1027
1028 mgr->chip[idx] = chip;
1028 snd_card_set_dev(card, &mgr->pci->dev); 1029 snd_card_set_dev(card, &mgr->pci->dev);
1029 1030
1030 return 0; 1031 return 0;
@@ -1377,6 +1378,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
1377 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); 1378 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
1378 1379
1379 if ((err = snd_mixart_create(mgr, card, i)) < 0) { 1380 if ((err = snd_mixart_create(mgr, card, i)) < 0) {
1381 snd_card_free(card);
1380 snd_mixart_free(mgr); 1382 snd_mixart_free(mgr);
1381 return err; 1383 return err;
1382 } 1384 }
diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c
index b9a06c279397..d3350f383966 100644
--- a/sound/pci/mixart/mixart_core.c
+++ b/sound/pci/mixart/mixart_core.c
@@ -550,7 +550,7 @@ irqreturn_t snd_mixart_interrupt(int irq, void *dev_id)
550 mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg; 550 mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg;
551 mgr->msg_fifo_writeptr++; 551 mgr->msg_fifo_writeptr++;
552 mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE; 552 mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE;
553 tasklet_hi_schedule(&mgr->msg_taskq); 553 tasklet_schedule(&mgr->msg_taskq);
554 } 554 }
555 spin_unlock(&mgr->msg_lock); 555 spin_unlock(&mgr->msg_lock);
556 break; 556 break;
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index b60f6212745a..de999c6d6dd3 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -61,6 +61,7 @@ MODULE_PARM_DESC(enable, "enable card");
61enum { 61enum {
62 MODEL_CMEDIA_REF, /* C-Media's reference design */ 62 MODEL_CMEDIA_REF, /* C-Media's reference design */
63 MODEL_MERIDIAN, /* AuzenTech X-Meridian */ 63 MODEL_MERIDIAN, /* AuzenTech X-Meridian */
64 MODEL_HALO, /* HT-Omega Claro halo */
64}; 65};
65 66
66static struct pci_device_id oxygen_ids[] __devinitdata = { 67static struct pci_device_id oxygen_ids[] __devinitdata = {
@@ -74,6 +75,7 @@ static struct pci_device_id oxygen_ids[] __devinitdata = {
74 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 75 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
75 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 76 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
76 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF }, 77 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF },
78 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_HALO },
77 { } 79 { }
78}; 80};
79MODULE_DEVICE_TABLE(pci, oxygen_ids); 81MODULE_DEVICE_TABLE(pci, oxygen_ids);
@@ -301,6 +303,8 @@ static int generic_probe(struct oxygen *chip, unsigned long driver_data)
301 PLAYBACK_1_TO_SPDIF | 303 PLAYBACK_1_TO_SPDIF |
302 CAPTURE_0_FROM_I2S_2 | 304 CAPTURE_0_FROM_I2S_2 |
303 CAPTURE_1_FROM_SPDIF; 305 CAPTURE_1_FROM_SPDIF;
306 }
307 if (driver_data == MODEL_MERIDIAN || driver_data == MODEL_HALO) {
304 chip->model.misc_flags = OXYGEN_MISC_MIDI; 308 chip->model.misc_flags = OXYGEN_MISC_MIDI;
305 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; 309 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
306 } 310 }
diff --git a/sound/pci/pcxhr/Makefile b/sound/pci/pcxhr/Makefile
index 10473c05918d..b06128e918ca 100644
--- a/sound/pci/pcxhr/Makefile
+++ b/sound/pci/pcxhr/Makefile
@@ -1,2 +1,2 @@
1snd-pcxhr-objs := pcxhr.o pcxhr_hwdep.o pcxhr_mixer.o pcxhr_core.o 1snd-pcxhr-objs := pcxhr.o pcxhr_hwdep.o pcxhr_mixer.o pcxhr_core.o pcxhr_mix22.o
2obj-$(CONFIG_SND_PCXHR) += snd-pcxhr.o 2obj-$(CONFIG_SND_PCXHR) += snd-pcxhr.o
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 73de6e989b3d..27cf2c28d113 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -40,18 +40,20 @@
40#include "pcxhr_mixer.h" 40#include "pcxhr_mixer.h"
41#include "pcxhr_hwdep.h" 41#include "pcxhr_hwdep.h"
42#include "pcxhr_core.h" 42#include "pcxhr_core.h"
43#include "pcxhr_mix22.h"
43 44
44#define DRIVER_NAME "pcxhr" 45#define DRIVER_NAME "pcxhr"
45 46
46MODULE_AUTHOR("Markus Bollinger <bollinger@digigram.com>"); 47MODULE_AUTHOR("Markus Bollinger <bollinger@digigram.com>, "
48 "Marc Titinger <titinger@digigram.com>");
47MODULE_DESCRIPTION("Digigram " DRIVER_NAME " " PCXHR_DRIVER_VERSION_STRING); 49MODULE_DESCRIPTION("Digigram " DRIVER_NAME " " PCXHR_DRIVER_VERSION_STRING);
48MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
49MODULE_SUPPORTED_DEVICE("{{Digigram," DRIVER_NAME "}}"); 51MODULE_SUPPORTED_DEVICE("{{Digigram," DRIVER_NAME "}}");
50 52
51static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ 53static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
52static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ 54static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
53static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ 55static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;/* Enable this card */
54static int mono[SNDRV_CARDS]; /* capture in mono only */ 56static int mono[SNDRV_CARDS]; /* capture mono only */
55 57
56module_param_array(index, int, NULL, 0444); 58module_param_array(index, int, NULL, 0444);
57MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard"); 59MODULE_PARM_DESC(index, "Index value for Digigram " DRIVER_NAME " soundcard");
@@ -67,18 +69,58 @@ enum {
67 PCI_ID_PCX882HR, 69 PCI_ID_PCX882HR,
68 PCI_ID_VX881HR, 70 PCI_ID_VX881HR,
69 PCI_ID_PCX881HR, 71 PCI_ID_PCX881HR,
72 PCI_ID_VX882E,
73 PCI_ID_PCX882E,
74 PCI_ID_VX881E,
75 PCI_ID_PCX881E,
76 PCI_ID_VX1222HR,
70 PCI_ID_PCX1222HR, 77 PCI_ID_PCX1222HR,
78 PCI_ID_VX1221HR,
71 PCI_ID_PCX1221HR, 79 PCI_ID_PCX1221HR,
80 PCI_ID_VX1222E,
81 PCI_ID_PCX1222E,
82 PCI_ID_VX1221E,
83 PCI_ID_PCX1221E,
84 PCI_ID_VX222HR,
85 PCI_ID_VX222E,
86 PCI_ID_PCX22HR,
87 PCI_ID_PCX22E,
88 PCI_ID_VX222HRMIC,
89 PCI_ID_VX222E_MIC,
90 PCI_ID_PCX924HR,
91 PCI_ID_PCX924E,
92 PCI_ID_PCX924HRMIC,
93 PCI_ID_PCX924E_MIC,
72 PCI_ID_LAST 94 PCI_ID_LAST
73}; 95};
74 96
75static struct pci_device_id pcxhr_ids[] = { 97static struct pci_device_id pcxhr_ids[] = {
76 { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, }, /* VX882HR */ 98 { 0x10b5, 0x9656, 0x1369, 0xb001, 0, 0, PCI_ID_VX882HR, },
77 { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, }, /* PCX882HR */ 99 { 0x10b5, 0x9656, 0x1369, 0xb101, 0, 0, PCI_ID_PCX882HR, },
78 { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, }, /* VX881HR */ 100 { 0x10b5, 0x9656, 0x1369, 0xb201, 0, 0, PCI_ID_VX881HR, },
79 { 0x10b5, 0x9656, 0x1369, 0xb301, 0, 0, PCI_ID_PCX881HR, }, /* PCX881HR */ 101 { 0x10b5, 0x9656, 0x1369, 0xb301, 0, 0, PCI_ID_PCX881HR, },
80 { 0x10b5, 0x9656, 0x1369, 0xb501, 0, 0, PCI_ID_PCX1222HR, }, /* PCX1222HR */ 102 { 0x10b5, 0x9056, 0x1369, 0xb021, 0, 0, PCI_ID_VX882E, },
81 { 0x10b5, 0x9656, 0x1369, 0xb701, 0, 0, PCI_ID_PCX1221HR, }, /* PCX1221HR */ 103 { 0x10b5, 0x9056, 0x1369, 0xb121, 0, 0, PCI_ID_PCX882E, },
104 { 0x10b5, 0x9056, 0x1369, 0xb221, 0, 0, PCI_ID_VX881E, },
105 { 0x10b5, 0x9056, 0x1369, 0xb321, 0, 0, PCI_ID_PCX881E, },
106 { 0x10b5, 0x9656, 0x1369, 0xb401, 0, 0, PCI_ID_VX1222HR, },
107 { 0x10b5, 0x9656, 0x1369, 0xb501, 0, 0, PCI_ID_PCX1222HR, },
108 { 0x10b5, 0x9656, 0x1369, 0xb601, 0, 0, PCI_ID_VX1221HR, },
109 { 0x10b5, 0x9656, 0x1369, 0xb701, 0, 0, PCI_ID_PCX1221HR, },
110 { 0x10b5, 0x9056, 0x1369, 0xb421, 0, 0, PCI_ID_VX1222E, },
111 { 0x10b5, 0x9056, 0x1369, 0xb521, 0, 0, PCI_ID_PCX1222E, },
112 { 0x10b5, 0x9056, 0x1369, 0xb621, 0, 0, PCI_ID_VX1221E, },
113 { 0x10b5, 0x9056, 0x1369, 0xb721, 0, 0, PCI_ID_PCX1221E, },
114 { 0x10b5, 0x9056, 0x1369, 0xba01, 0, 0, PCI_ID_VX222HR, },
115 { 0x10b5, 0x9056, 0x1369, 0xba21, 0, 0, PCI_ID_VX222E, },
116 { 0x10b5, 0x9056, 0x1369, 0xbd01, 0, 0, PCI_ID_PCX22HR, },
117 { 0x10b5, 0x9056, 0x1369, 0xbd21, 0, 0, PCI_ID_PCX22E, },
118 { 0x10b5, 0x9056, 0x1369, 0xbc01, 0, 0, PCI_ID_VX222HRMIC, },
119 { 0x10b5, 0x9056, 0x1369, 0xbc21, 0, 0, PCI_ID_VX222E_MIC, },
120 { 0x10b5, 0x9056, 0x1369, 0xbb01, 0, 0, PCI_ID_PCX924HR, },
121 { 0x10b5, 0x9056, 0x1369, 0xbb21, 0, 0, PCI_ID_PCX924E, },
122 { 0x10b5, 0x9056, 0x1369, 0xbf01, 0, 0, PCI_ID_PCX924HRMIC, },
123 { 0x10b5, 0x9056, 0x1369, 0xbf21, 0, 0, PCI_ID_PCX924E_MIC, },
82 { 0, } 124 { 0, }
83}; 125};
84 126
@@ -88,27 +130,55 @@ struct board_parameters {
88 char* board_name; 130 char* board_name;
89 short playback_chips; 131 short playback_chips;
90 short capture_chips; 132 short capture_chips;
133 short fw_file_set;
91 short firmware_num; 134 short firmware_num;
92}; 135};
93static struct board_parameters pcxhr_board_params[] = { 136static struct board_parameters pcxhr_board_params[] = {
94[PCI_ID_VX882HR] = { "VX882HR", 4, 4, 41, }, 137[PCI_ID_VX882HR] = { "VX882HR", 4, 4, 0, 41 },
95[PCI_ID_PCX882HR] = { "PCX882HR", 4, 4, 41, }, 138[PCI_ID_PCX882HR] = { "PCX882HR", 4, 4, 0, 41 },
96[PCI_ID_VX881HR] = { "VX881HR", 4, 4, 41, }, 139[PCI_ID_VX881HR] = { "VX881HR", 4, 4, 0, 41 },
97[PCI_ID_PCX881HR] = { "PCX881HR", 4, 4, 41, }, 140[PCI_ID_PCX881HR] = { "PCX881HR", 4, 4, 0, 41 },
98[PCI_ID_PCX1222HR] = { "PCX1222HR", 6, 1, 42, }, 141[PCI_ID_VX882E] = { "VX882e", 4, 4, 1, 41 },
99[PCI_ID_PCX1221HR] = { "PCX1221HR", 6, 1, 42, }, 142[PCI_ID_PCX882E] = { "PCX882e", 4, 4, 1, 41 },
143[PCI_ID_VX881E] = { "VX881e", 4, 4, 1, 41 },
144[PCI_ID_PCX881E] = { "PCX881e", 4, 4, 1, 41 },
145[PCI_ID_VX1222HR] = { "VX1222HR", 6, 1, 2, 42 },
146[PCI_ID_PCX1222HR] = { "PCX1222HR", 6, 1, 2, 42 },
147[PCI_ID_VX1221HR] = { "VX1221HR", 6, 1, 2, 42 },
148[PCI_ID_PCX1221HR] = { "PCX1221HR", 6, 1, 2, 42 },
149[PCI_ID_VX1222E] = { "VX1222e", 6, 1, 3, 42 },
150[PCI_ID_PCX1222E] = { "PCX1222e", 6, 1, 3, 42 },
151[PCI_ID_VX1221E] = { "VX1221e", 6, 1, 3, 42 },
152[PCI_ID_PCX1221E] = { "PCX1221e", 6, 1, 3, 42 },
153[PCI_ID_VX222HR] = { "VX222HR", 1, 1, 4, 44 },
154[PCI_ID_VX222E] = { "VX222e", 1, 1, 4, 44 },
155[PCI_ID_PCX22HR] = { "PCX22HR", 1, 0, 4, 44 },
156[PCI_ID_PCX22E] = { "PCX22e", 1, 0, 4, 44 },
157[PCI_ID_VX222HRMIC] = { "VX222HR-Mic", 1, 1, 5, 44 },
158[PCI_ID_VX222E_MIC] = { "VX222e-Mic", 1, 1, 5, 44 },
159[PCI_ID_PCX924HR] = { "PCX924HR", 1, 1, 5, 44 },
160[PCI_ID_PCX924E] = { "PCX924e", 1, 1, 5, 44 },
161[PCI_ID_PCX924HRMIC] = { "PCX924HR-Mic", 1, 1, 5, 44 },
162[PCI_ID_PCX924E_MIC] = { "PCX924e-Mic", 1, 1, 5, 44 },
100}; 163};
101 164
165/* boards without hw AES1 and SRC onboard are all using fw_file_set==4 */
166/* VX222HR, VX222e, PCX22HR and PCX22e */
167#define PCXHR_BOARD_HAS_AES1(x) (x->fw_file_set != 4)
168/* some boards do not support 192kHz on digital AES input plugs */
169#define PCXHR_BOARD_AESIN_NO_192K(x) ((x->capture_chips == 0) || \
170 (x->fw_file_set == 0) || \
171 (x->fw_file_set == 2))
102 172
103static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg, 173static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
104 unsigned int* realfreq) 174 unsigned int* realfreq)
105{ 175{
106 unsigned int reg; 176 unsigned int reg;
107 177
108 if (freq < 6900 || freq > 110250) 178 if (freq < 6900 || freq > 110000)
109 return -EINVAL; 179 return -EINVAL;
110 reg = (28224000 * 10) / freq; 180 reg = (28224000 * 2) / freq;
111 reg = (reg + 5) / 10; 181 reg = (reg - 1) / 2;
112 if (reg < 0x200) 182 if (reg < 0x200)
113 *pllreg = reg + 0x800; 183 *pllreg = reg + 0x800;
114 else if (reg < 0x400) 184 else if (reg < 0x400)
@@ -121,7 +191,7 @@ static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
121 reg &= ~3; 191 reg &= ~3;
122 } 192 }
123 if (realfreq) 193 if (realfreq)
124 *realfreq = ((28224000 * 10) / reg + 5) / 10; 194 *realfreq = (28224000 / (reg + 1));
125 return 0; 195 return 0;
126} 196}
127 197
@@ -151,11 +221,6 @@ static int pcxhr_pll_freq_register(unsigned int freq, unsigned int* pllreg,
151#define PCXHR_FREQ_AES_3 0x03 221#define PCXHR_FREQ_AES_3 0x03
152#define PCXHR_FREQ_AES_4 0x0d 222#define PCXHR_FREQ_AES_4 0x0d
153 223
154#define PCXHR_MODIFY_CLOCK_S_BIT 0x04
155
156#define PCXHR_IRQ_TIMER_FREQ 92000
157#define PCXHR_IRQ_TIMER_PERIOD 48
158
159static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate, 224static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
160 unsigned int *reg, unsigned int *freq) 225 unsigned int *reg, unsigned int *freq)
161{ 226{
@@ -196,19 +261,32 @@ static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
196 err = pcxhr_send_msg(mgr, &rmh); 261 err = pcxhr_send_msg(mgr, &rmh);
197 if (err < 0) { 262 if (err < 0) {
198 snd_printk(KERN_ERR 263 snd_printk(KERN_ERR
199 "error CMD_ACCESS_IO_WRITE for PLL register : %x!\n", 264 "error CMD_ACCESS_IO_WRITE "
200 err ); 265 "for PLL register : %x!\n", err);
201 return err; 266 return err;
202 } 267 }
203 } 268 }
204 break; 269 break;
205 case PCXHR_CLOCK_TYPE_WORD_CLOCK : val = PCXHR_FREQ_WORD_CLOCK; break; 270 case PCXHR_CLOCK_TYPE_WORD_CLOCK:
206 case PCXHR_CLOCK_TYPE_AES_SYNC : val = PCXHR_FREQ_SYNC_AES; break; 271 val = PCXHR_FREQ_WORD_CLOCK;
207 case PCXHR_CLOCK_TYPE_AES_1 : val = PCXHR_FREQ_AES_1; break; 272 break;
208 case PCXHR_CLOCK_TYPE_AES_2 : val = PCXHR_FREQ_AES_2; break; 273 case PCXHR_CLOCK_TYPE_AES_SYNC:
209 case PCXHR_CLOCK_TYPE_AES_3 : val = PCXHR_FREQ_AES_3; break; 274 val = PCXHR_FREQ_SYNC_AES;
210 case PCXHR_CLOCK_TYPE_AES_4 : val = PCXHR_FREQ_AES_4; break; 275 break;
211 default : return -EINVAL; 276 case PCXHR_CLOCK_TYPE_AES_1:
277 val = PCXHR_FREQ_AES_1;
278 break;
279 case PCXHR_CLOCK_TYPE_AES_2:
280 val = PCXHR_FREQ_AES_2;
281 break;
282 case PCXHR_CLOCK_TYPE_AES_3:
283 val = PCXHR_FREQ_AES_3;
284 break;
285 case PCXHR_CLOCK_TYPE_AES_4:
286 val = PCXHR_FREQ_AES_4;
287 break;
288 default:
289 return -EINVAL;
212 } 290 }
213 *reg = val; 291 *reg = val;
214 *freq = realfreq; 292 *freq = realfreq;
@@ -216,14 +294,13 @@ static int pcxhr_get_clock_reg(struct pcxhr_mgr *mgr, unsigned int rate,
216} 294}
217 295
218 296
219int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate) 297static int pcxhr_sub_set_clock(struct pcxhr_mgr *mgr,
298 unsigned int rate,
299 int *changed)
220{ 300{
221 unsigned int val, realfreq, speed; 301 unsigned int val, realfreq, speed;
222 struct pcxhr_rmh rmh; 302 struct pcxhr_rmh rmh;
223 int err, changed; 303 int err;
224
225 if (rate == 0)
226 return 0; /* nothing to do */
227 304
228 err = pcxhr_get_clock_reg(mgr, rate, &val, &realfreq); 305 err = pcxhr_get_clock_reg(mgr, rate, &val, &realfreq);
229 if (err) 306 if (err)
@@ -237,13 +314,17 @@ int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
237 else 314 else
238 speed = 2; /* quad speed */ 315 speed = 2; /* quad speed */
239 if (mgr->codec_speed != speed) { 316 if (mgr->codec_speed != speed) {
240 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* mute outputs */ 317 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* mute outputs */
241 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 318 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
319 if (DSP_EXT_CMD_SET(mgr)) {
320 rmh.cmd[1] = 1;
321 rmh.cmd_len = 2;
322 }
242 err = pcxhr_send_msg(mgr, &rmh); 323 err = pcxhr_send_msg(mgr, &rmh);
243 if (err) 324 if (err)
244 return err; 325 return err;
245 326
246 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set speed ratio */ 327 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set speed ratio */
247 rmh.cmd[0] |= IO_NUM_SPEED_RATIO; 328 rmh.cmd[0] |= IO_NUM_SPEED_RATIO;
248 rmh.cmd[1] = speed; 329 rmh.cmd[1] = speed;
249 rmh.cmd_len = 2; 330 rmh.cmd_len = 2;
@@ -253,25 +334,57 @@ int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
253 } 334 }
254 /* set the new frequency */ 335 /* set the new frequency */
255 snd_printdd("clock register : set %x\n", val); 336 snd_printdd("clock register : set %x\n", val);
256 err = pcxhr_write_io_num_reg_cont(mgr, PCXHR_FREQ_REG_MASK, val, &changed); 337 err = pcxhr_write_io_num_reg_cont(mgr, PCXHR_FREQ_REG_MASK,
338 val, changed);
257 if (err) 339 if (err)
258 return err; 340 return err;
341
259 mgr->sample_rate_real = realfreq; 342 mgr->sample_rate_real = realfreq;
260 mgr->cur_clock_type = mgr->use_clock_type; 343 mgr->cur_clock_type = mgr->use_clock_type;
261 344
262 /* unmute after codec speed modes */ 345 /* unmute after codec speed modes */
263 if (mgr->codec_speed != speed) { 346 if (mgr->codec_speed != speed) {
264 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* unmute outputs */ 347 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* unmute outputs */
265 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 348 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
349 if (DSP_EXT_CMD_SET(mgr)) {
350 rmh.cmd[1] = 1;
351 rmh.cmd_len = 2;
352 }
266 err = pcxhr_send_msg(mgr, &rmh); 353 err = pcxhr_send_msg(mgr, &rmh);
267 if (err) 354 if (err)
268 return err; 355 return err;
269 mgr->codec_speed = speed; /* save new codec speed */ 356 mgr->codec_speed = speed; /* save new codec speed */
270 } 357 }
271 358
359 snd_printdd("pcxhr_sub_set_clock to %dHz (realfreq=%d)\n",
360 rate, realfreq);
361 return 0;
362}
363
364#define PCXHR_MODIFY_CLOCK_S_BIT 0x04
365
366#define PCXHR_IRQ_TIMER_FREQ 92000
367#define PCXHR_IRQ_TIMER_PERIOD 48
368
369int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
370{
371 struct pcxhr_rmh rmh;
372 int err, changed;
373
374 if (rate == 0)
375 return 0; /* nothing to do */
376
377 if (mgr->is_hr_stereo)
378 err = hr222_sub_set_clock(mgr, rate, &changed);
379 else
380 err = pcxhr_sub_set_clock(mgr, rate, &changed);
381
382 if (err)
383 return err;
384
272 if (changed) { 385 if (changed) {
273 pcxhr_init_rmh(&rmh, CMD_MODIFY_CLOCK); 386 pcxhr_init_rmh(&rmh, CMD_MODIFY_CLOCK);
274 rmh.cmd[0] |= PCXHR_MODIFY_CLOCK_S_BIT; /* resync fifos */ 387 rmh.cmd[0] |= PCXHR_MODIFY_CLOCK_S_BIT; /* resync fifos */
275 if (rate < PCXHR_IRQ_TIMER_FREQ) 388 if (rate < PCXHR_IRQ_TIMER_FREQ)
276 rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD; 389 rmh.cmd[1] = PCXHR_IRQ_TIMER_PERIOD;
277 else 390 else
@@ -282,26 +395,39 @@ int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate)
282 if (err) 395 if (err)
283 return err; 396 return err;
284 } 397 }
285 snd_printdd("pcxhr_set_clock to %dHz (realfreq=%d)\n", rate, realfreq);
286 return 0; 398 return 0;
287} 399}
288 400
289 401
290int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_type, 402static int pcxhr_sub_get_external_clock(struct pcxhr_mgr *mgr,
291 int *sample_rate) 403 enum pcxhr_clock_type clock_type,
404 int *sample_rate)
292{ 405{
293 struct pcxhr_rmh rmh; 406 struct pcxhr_rmh rmh;
294 unsigned char reg; 407 unsigned char reg;
295 int err, rate; 408 int err, rate;
296 409
297 switch (clock_type) { 410 switch (clock_type) {
298 case PCXHR_CLOCK_TYPE_WORD_CLOCK : reg = REG_STATUS_WORD_CLOCK; break; 411 case PCXHR_CLOCK_TYPE_WORD_CLOCK:
299 case PCXHR_CLOCK_TYPE_AES_SYNC : reg = REG_STATUS_AES_SYNC; break; 412 reg = REG_STATUS_WORD_CLOCK;
300 case PCXHR_CLOCK_TYPE_AES_1 : reg = REG_STATUS_AES_1; break; 413 break;
301 case PCXHR_CLOCK_TYPE_AES_2 : reg = REG_STATUS_AES_2; break; 414 case PCXHR_CLOCK_TYPE_AES_SYNC:
302 case PCXHR_CLOCK_TYPE_AES_3 : reg = REG_STATUS_AES_3; break; 415 reg = REG_STATUS_AES_SYNC;
303 case PCXHR_CLOCK_TYPE_AES_4 : reg = REG_STATUS_AES_4; break; 416 break;
304 default : return -EINVAL; 417 case PCXHR_CLOCK_TYPE_AES_1:
418 reg = REG_STATUS_AES_1;
419 break;
420 case PCXHR_CLOCK_TYPE_AES_2:
421 reg = REG_STATUS_AES_2;
422 break;
423 case PCXHR_CLOCK_TYPE_AES_3:
424 reg = REG_STATUS_AES_3;
425 break;
426 case PCXHR_CLOCK_TYPE_AES_4:
427 reg = REG_STATUS_AES_4;
428 break;
429 default:
430 return -EINVAL;
305 } 431 }
306 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); 432 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
307 rmh.cmd_len = 2; 433 rmh.cmd_len = 2;
@@ -311,7 +437,7 @@ int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_
311 err = pcxhr_send_msg(mgr, &rmh); 437 err = pcxhr_send_msg(mgr, &rmh);
312 if (err) 438 if (err)
313 return err; 439 return err;
314 udelay(100); /* wait minimum 2 sample_frames at 32kHz ! */ 440 udelay(100); /* wait minimum 2 sample_frames at 32kHz ! */
315 mgr->last_reg_stat = reg; 441 mgr->last_reg_stat = reg;
316 } 442 }
317 rmh.cmd[1] = REG_STATUS_CURRENT; 443 rmh.cmd[1] = REG_STATUS_CURRENT;
@@ -336,6 +462,18 @@ int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_
336} 462}
337 463
338 464
465int pcxhr_get_external_clock(struct pcxhr_mgr *mgr,
466 enum pcxhr_clock_type clock_type,
467 int *sample_rate)
468{
469 if (mgr->is_hr_stereo)
470 return hr222_get_external_clock(mgr, clock_type,
471 sample_rate);
472 else
473 return pcxhr_sub_get_external_clock(mgr, clock_type,
474 sample_rate);
475}
476
339/* 477/*
340 * start or stop playback/capture substream 478 * start or stop playback/capture substream
341 */ 479 */
@@ -350,7 +488,8 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
350 start = 1; 488 start = 1;
351 else { 489 else {
352 if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) { 490 if (stream->status != PCXHR_STREAM_STATUS_SCHEDULE_STOP) {
353 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state CANNOT be stopped\n"); 491 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state "
492 "CANNOT be stopped\n");
354 return -EINVAL; 493 return -EINVAL;
355 } 494 }
356 start = 0; 495 start = 0;
@@ -359,11 +498,12 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
359 return -EINVAL; 498 return -EINVAL;
360 499
361 stream->timer_abs_periods = 0; 500 stream->timer_abs_periods = 0;
362 stream->timer_period_frag = 0; /* reset theoretical stream pos */ 501 stream->timer_period_frag = 0; /* reset theoretical stream pos */
363 stream->timer_buf_periods = 0; 502 stream->timer_buf_periods = 0;
364 stream->timer_is_synced = 0; 503 stream->timer_is_synced = 0;
365 504
366 stream_mask = stream->pipe->is_capture ? 1 : 1<<stream->substream->number; 505 stream_mask =
506 stream->pipe->is_capture ? 1 : 1<<stream->substream->number;
367 507
368 pcxhr_init_rmh(&rmh, start ? CMD_START_STREAM : CMD_STOP_STREAM); 508 pcxhr_init_rmh(&rmh, start ? CMD_START_STREAM : CMD_STOP_STREAM);
369 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, 509 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
@@ -373,8 +513,10 @@ static int pcxhr_set_stream_state(struct pcxhr_stream *stream)
373 513
374 err = pcxhr_send_msg(chip->mgr, &rmh); 514 err = pcxhr_send_msg(chip->mgr, &rmh);
375 if (err) 515 if (err)
376 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state err=%x;\n", err); 516 snd_printk(KERN_ERR "ERROR pcxhr_set_stream_state err=%x;\n",
377 stream->status = start ? PCXHR_STREAM_STATUS_STARTED : PCXHR_STREAM_STATUS_STOPPED; 517 err);
518 stream->status =
519 start ? PCXHR_STREAM_STATUS_STARTED : PCXHR_STREAM_STATUS_STOPPED;
378 return err; 520 return err;
379} 521}
380 522
@@ -399,13 +541,15 @@ static int pcxhr_set_format(struct pcxhr_stream *stream)
399 header = HEADER_FMT_BASE_LIN; 541 header = HEADER_FMT_BASE_LIN;
400 break; 542 break;
401 case SNDRV_PCM_FORMAT_S16_LE: 543 case SNDRV_PCM_FORMAT_S16_LE:
402 header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS | HEADER_FMT_INTEL; 544 header = HEADER_FMT_BASE_LIN |
545 HEADER_FMT_16BITS | HEADER_FMT_INTEL;
403 break; 546 break;
404 case SNDRV_PCM_FORMAT_S16_BE: 547 case SNDRV_PCM_FORMAT_S16_BE:
405 header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS; 548 header = HEADER_FMT_BASE_LIN | HEADER_FMT_16BITS;
406 break; 549 break;
407 case SNDRV_PCM_FORMAT_S24_3LE: 550 case SNDRV_PCM_FORMAT_S24_3LE:
408 header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS | HEADER_FMT_INTEL; 551 header = HEADER_FMT_BASE_LIN |
552 HEADER_FMT_24BITS | HEADER_FMT_INTEL;
409 break; 553 break;
410 case SNDRV_PCM_FORMAT_S24_3BE: 554 case SNDRV_PCM_FORMAT_S24_3BE:
411 header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS; 555 header = HEADER_FMT_BASE_LIN | HEADER_FMT_24BITS;
@@ -414,7 +558,8 @@ static int pcxhr_set_format(struct pcxhr_stream *stream)
414 header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL; 558 header = HEADER_FMT_BASE_FLOAT | HEADER_FMT_INTEL;
415 break; 559 break;
416 default: 560 default:
417 snd_printk(KERN_ERR "error pcxhr_set_format() : unknown format\n"); 561 snd_printk(KERN_ERR
562 "error pcxhr_set_format() : unknown format\n");
418 return -EINVAL; 563 return -EINVAL;
419 } 564 }
420 chip = snd_pcm_substream_chip(stream->substream); 565 chip = snd_pcm_substream_chip(stream->substream);
@@ -432,14 +577,31 @@ static int pcxhr_set_format(struct pcxhr_stream *stream)
432 is_capture = stream->pipe->is_capture; 577 is_capture = stream->pipe->is_capture;
433 stream_num = is_capture ? 0 : stream->substream->number; 578 stream_num = is_capture ? 0 : stream->substream->number;
434 579
435 pcxhr_init_rmh(&rmh, is_capture ? CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT); 580 pcxhr_init_rmh(&rmh, is_capture ?
436 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0); 581 CMD_FORMAT_STREAM_IN : CMD_FORMAT_STREAM_OUT);
437 if (is_capture) 582 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,
438 rmh.cmd[0] |= 1<<12; 583 stream_num, 0);
584 if (is_capture) {
585 /* bug with old dsp versions: */
586 /* bit 12 also sets the format of the playback stream */
587 if (DSP_EXT_CMD_SET(chip->mgr))
588 rmh.cmd[0] |= 1<<10;
589 else
590 rmh.cmd[0] |= 1<<12;
591 }
439 rmh.cmd[1] = 0; 592 rmh.cmd[1] = 0;
440 rmh.cmd[2] = header >> 8; 593 rmh.cmd_len = 2;
441 rmh.cmd[3] = (header & 0xff) << 16; 594 if (DSP_EXT_CMD_SET(chip->mgr)) {
442 rmh.cmd_len = 4; 595 /* add channels and set bit 19 if channels>2 */
596 rmh.cmd[1] = stream->channels;
597 if (!is_capture) {
598 /* playback : add channel mask to command */
599 rmh.cmd[2] = (stream->channels == 1) ? 0x01 : 0x03;
600 rmh.cmd_len = 3;
601 }
602 }
603 rmh.cmd[rmh.cmd_len++] = header >> 8;
604 rmh.cmd[rmh.cmd_len++] = (header & 0xff) << 16;
443 err = pcxhr_send_msg(chip->mgr, &rmh); 605 err = pcxhr_send_msg(chip->mgr, &rmh);
444 if (err) 606 if (err)
445 snd_printk(KERN_ERR "ERROR pcxhr_set_format err=%x;\n", err); 607 snd_printk(KERN_ERR "ERROR pcxhr_set_format err=%x;\n", err);
@@ -456,30 +618,38 @@ static int pcxhr_update_r_buffer(struct pcxhr_stream *stream)
456 is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE); 618 is_capture = (subs->stream == SNDRV_PCM_STREAM_CAPTURE);
457 stream_num = is_capture ? 0 : subs->number; 619 stream_num = is_capture ? 0 : subs->number;
458 620
459 snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : addr(%p) bytes(%zx) subs(%d)\n", 621 snd_printdd("pcxhr_update_r_buffer(pcm%c%d) : "
622 "addr(%p) bytes(%zx) subs(%d)\n",
460 is_capture ? 'c' : 'p', 623 is_capture ? 'c' : 'p',
461 chip->chip_idx, (void *)(long)subs->runtime->dma_addr, 624 chip->chip_idx, (void *)(long)subs->runtime->dma_addr,
462 subs->runtime->dma_bytes, subs->number); 625 subs->runtime->dma_bytes, subs->number);
463 626
464 pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS); 627 pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS);
465 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0); 628 pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio,
629 stream_num, 0);
466 630
467 /* max buffer size is 2 MByte */ 631 /* max buffer size is 2 MByte */
468 snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000); 632 snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000);
469 rmh.cmd[1] = subs->runtime->dma_bytes * 8; /* size in bits */ 633 /* size in bits */
470 rmh.cmd[2] = subs->runtime->dma_addr >> 24; /* most significant byte */ 634 rmh.cmd[1] = subs->runtime->dma_bytes * 8;
471 rmh.cmd[2] |= 1<<19; /* this is a circular buffer */ 635 /* most significant byte */
472 rmh.cmd[3] = subs->runtime->dma_addr & MASK_DSP_WORD; /* least 3 significant bytes */ 636 rmh.cmd[2] = subs->runtime->dma_addr >> 24;
637 /* this is a circular buffer */
638 rmh.cmd[2] |= 1<<19;
639 /* least 3 significant bytes */
640 rmh.cmd[3] = subs->runtime->dma_addr & MASK_DSP_WORD;
473 rmh.cmd_len = 4; 641 rmh.cmd_len = 4;
474 err = pcxhr_send_msg(chip->mgr, &rmh); 642 err = pcxhr_send_msg(chip->mgr, &rmh);
475 if (err) 643 if (err)
476 snd_printk(KERN_ERR "ERROR CMD_UPDATE_R_BUFFERS err=%x;\n", err); 644 snd_printk(KERN_ERR
645 "ERROR CMD_UPDATE_R_BUFFERS err=%x;\n", err);
477 return err; 646 return err;
478} 647}
479 648
480 649
481#if 0 650#if 0
482static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream, snd_pcm_uframes_t *sample_count) 651static int pcxhr_pipe_sample_count(struct pcxhr_stream *stream,
652 snd_pcm_uframes_t *sample_count)
483{ 653{
484 struct pcxhr_rmh rmh; 654 struct pcxhr_rmh rmh;
485 int err; 655 int err;
@@ -533,8 +703,8 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
533 for (j = 0; j < chip->nb_streams_play; j++) { 703 for (j = 0; j < chip->nb_streams_play; j++) {
534 if (pcxhr_stream_scheduled_get_pipe(&chip->playback_stream[j], &pipe)) { 704 if (pcxhr_stream_scheduled_get_pipe(&chip->playback_stream[j], &pipe)) {
535 playback_mask |= (1 << pipe->first_audio); 705 playback_mask |= (1 << pipe->first_audio);
536 break; /* add only once, as all playback streams of 706 break; /* add only once, as all playback
537 * one chip use the same pipe 707 * streams of one chip use the same pipe
538 */ 708 */
539 } 709 }
540 } 710 }
@@ -545,19 +715,21 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
545 return; 715 return;
546 } 716 }
547 717
548 snd_printdd("pcxhr_trigger_tasklet : playback_mask=%x capture_mask=%x\n", 718 snd_printdd("pcxhr_trigger_tasklet : "
719 "playback_mask=%x capture_mask=%x\n",
549 playback_mask, capture_mask); 720 playback_mask, capture_mask);
550 721
551 /* synchronous stop of all the pipes concerned */ 722 /* synchronous stop of all the pipes concerned */
552 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0); 723 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 0);
553 if (err) { 724 if (err) {
554 mutex_unlock(&mgr->setup_mutex); 725 mutex_unlock(&mgr->setup_mutex);
555 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error stop pipes (P%x C%x)\n", 726 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : "
727 "error stop pipes (P%x C%x)\n",
556 playback_mask, capture_mask); 728 playback_mask, capture_mask);
557 return; 729 return;
558 } 730 }
559 731
560 /* unfortunately the dsp lost format and buffer info with the stop pipe */ 732 /* the dsp lost format and buffer info with the stop pipe */
561 for (i = 0; i < mgr->num_cards; i++) { 733 for (i = 0; i < mgr->num_cards; i++) {
562 struct pcxhr_stream *stream; 734 struct pcxhr_stream *stream;
563 chip = mgr->chip[i]; 735 chip = mgr->chip[i];
@@ -596,12 +768,15 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
596 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); 768 err = pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
597 if (err) { 769 if (err) {
598 mutex_unlock(&mgr->setup_mutex); 770 mutex_unlock(&mgr->setup_mutex);
599 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : error start pipes (P%x C%x)\n", 771 snd_printk(KERN_ERR "pcxhr_trigger_tasklet : "
772 "error start pipes (P%x C%x)\n",
600 playback_mask, capture_mask); 773 playback_mask, capture_mask);
601 return; 774 return;
602 } 775 }
603 776
604 /* put the streams into the running state now (increment pointer by interrupt) */ 777 /* put the streams into the running state now
778 * (increment pointer by interrupt)
779 */
605 spin_lock_irqsave(&mgr->lock, flags); 780 spin_lock_irqsave(&mgr->lock, flags);
606 for ( i =0; i < mgr->num_cards; i++) { 781 for ( i =0; i < mgr->num_cards; i++) {
607 struct pcxhr_stream *stream; 782 struct pcxhr_stream *stream;
@@ -615,7 +790,7 @@ static void pcxhr_trigger_tasklet(unsigned long arg)
615 stream = &chip->playback_stream[j]; 790 stream = &chip->playback_stream[j];
616 if (stream->status == PCXHR_STREAM_STATUS_STARTED) { 791 if (stream->status == PCXHR_STREAM_STATUS_STARTED) {
617 /* playback will already have advanced ! */ 792 /* playback will already have advanced ! */
618 stream->timer_period_frag += PCXHR_GRANULARITY; 793 stream->timer_period_frag += mgr->granularity;
619 stream->status = PCXHR_STREAM_STATUS_RUNNING; 794 stream->status = PCXHR_STREAM_STATUS_RUNNING;
620 } 795 }
621 } 796 }
@@ -653,7 +828,7 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd)
653 PCXHR_STREAM_STATUS_SCHEDULE_RUN; 828 PCXHR_STREAM_STATUS_SCHEDULE_RUN;
654 snd_pcm_trigger_done(s, subs); 829 snd_pcm_trigger_done(s, subs);
655 } 830 }
656 tasklet_hi_schedule(&chip->mgr->trigger_taskq); 831 tasklet_schedule(&chip->mgr->trigger_taskq);
657 } else { 832 } else {
658 stream = subs->runtime->private_data; 833 stream = subs->runtime->private_data;
659 snd_printdd("Only one Substream %c %d\n", 834 snd_printdd("Only one Substream %c %d\n",
@@ -697,12 +872,14 @@ static int pcxhr_hardware_timer(struct pcxhr_mgr *mgr, int start)
697 872
698 pcxhr_init_rmh(&rmh, CMD_SET_TIMER_INTERRUPT); 873 pcxhr_init_rmh(&rmh, CMD_SET_TIMER_INTERRUPT);
699 if (start) { 874 if (start) {
700 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID; /* last dsp time invalid */ 875 /* last dsp time invalid */
701 rmh.cmd[0] |= PCXHR_GRANULARITY; 876 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
877 rmh.cmd[0] |= mgr->granularity;
702 } 878 }
703 err = pcxhr_send_msg(mgr, &rmh); 879 err = pcxhr_send_msg(mgr, &rmh);
704 if (err < 0) 880 if (err < 0)
705 snd_printk(KERN_ERR "error pcxhr_hardware_timer err(%x)\n", err); 881 snd_printk(KERN_ERR "error pcxhr_hardware_timer err(%x)\n",
882 err);
706 return err; 883 return err;
707} 884}
708 885
@@ -713,38 +890,16 @@ static int pcxhr_prepare(struct snd_pcm_substream *subs)
713{ 890{
714 struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); 891 struct snd_pcxhr *chip = snd_pcm_substream_chip(subs);
715 struct pcxhr_mgr *mgr = chip->mgr; 892 struct pcxhr_mgr *mgr = chip->mgr;
716 /*
717 struct pcxhr_stream *stream = (pcxhr_stream_t*)subs->runtime->private_data;
718 */
719 int err = 0; 893 int err = 0;
720 894
721 snd_printdd("pcxhr_prepare : period_size(%lx) periods(%x) buffer_size(%lx)\n", 895 snd_printdd("pcxhr_prepare : period_size(%lx) periods(%x) buffer_size(%lx)\n",
722 subs->runtime->period_size, subs->runtime->periods, 896 subs->runtime->period_size, subs->runtime->periods,
723 subs->runtime->buffer_size); 897 subs->runtime->buffer_size);
724 898
725 /*
726 if(subs->runtime->period_size <= PCXHR_GRANULARITY) {
727 snd_printk(KERN_ERR "pcxhr_prepare : error period_size too small (%x)\n",
728 (unsigned int)subs->runtime->period_size);
729 return -EINVAL;
730 }
731 */
732
733 mutex_lock(&mgr->setup_mutex); 899 mutex_lock(&mgr->setup_mutex);
734 900
735 do { 901 do {
736 /* if the stream was stopped before, format and buffer were reset */
737 /*
738 if(stream->status == PCXHR_STREAM_STATUS_STOPPED) {
739 err = pcxhr_set_format(stream);
740 if(err) break;
741 err = pcxhr_update_r_buffer(stream);
742 if(err) break;
743 }
744 */
745
746 /* only the first stream can choose the sample rate */ 902 /* only the first stream can choose the sample rate */
747 /* the further opened streams will be limited to its frequency (see open) */
748 /* set the clock only once (first stream) */ 903 /* set the clock only once (first stream) */
749 if (mgr->sample_rate != subs->runtime->rate) { 904 if (mgr->sample_rate != subs->runtime->rate) {
750 err = pcxhr_set_clock(mgr, subs->runtime->rate); 905 err = pcxhr_set_clock(mgr, subs->runtime->rate);
@@ -787,22 +942,9 @@ static int pcxhr_hw_params(struct snd_pcm_substream *subs,
787 stream->channels = channels; 942 stream->channels = channels;
788 stream->format = format; 943 stream->format = format;
789 944
790 /* set the format to the board */
791 /*
792 err = pcxhr_set_format(stream);
793 if(err) {
794 mutex_unlock(&mgr->setup_mutex);
795 return err;
796 }
797 */
798 /* allocate buffer */ 945 /* allocate buffer */
799 err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw)); 946 err = snd_pcm_lib_malloc_pages(subs, params_buffer_bytes(hw));
800 947
801 /*
802 if (err > 0) {
803 err = pcxhr_update_r_buffer(stream);
804 }
805 */
806 mutex_unlock(&mgr->setup_mutex); 948 mutex_unlock(&mgr->setup_mutex);
807 949
808 return err; 950 return err;
@@ -820,14 +962,18 @@ static int pcxhr_hw_free(struct snd_pcm_substream *subs)
820 */ 962 */
821static struct snd_pcm_hardware pcxhr_caps = 963static struct snd_pcm_hardware pcxhr_caps =
822{ 964{
823 .info = ( SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 965 .info = (SNDRV_PCM_INFO_MMAP |
824 SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_SYNC_START | 966 SNDRV_PCM_INFO_INTERLEAVED |
825 0 /*SNDRV_PCM_INFO_PAUSE*/), 967 SNDRV_PCM_INFO_MMAP_VALID |
826 .formats = ( SNDRV_PCM_FMTBIT_U8 | 968 SNDRV_PCM_INFO_SYNC_START),
827 SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE | 969 .formats = (SNDRV_PCM_FMTBIT_U8 |
828 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE | 970 SNDRV_PCM_FMTBIT_S16_LE |
829 SNDRV_PCM_FMTBIT_FLOAT_LE ), 971 SNDRV_PCM_FMTBIT_S16_BE |
830 .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_192000, 972 SNDRV_PCM_FMTBIT_S24_3LE |
973 SNDRV_PCM_FMTBIT_S24_3BE |
974 SNDRV_PCM_FMTBIT_FLOAT_LE),
975 .rates = (SNDRV_PCM_RATE_CONTINUOUS |
976 SNDRV_PCM_RATE_8000_192000),
831 .rate_min = 8000, 977 .rate_min = 8000,
832 .rate_max = 192000, 978 .rate_max = 192000,
833 .channels_min = 1, 979 .channels_min = 1,
@@ -847,6 +993,7 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
847 struct pcxhr_mgr *mgr = chip->mgr; 993 struct pcxhr_mgr *mgr = chip->mgr;
848 struct snd_pcm_runtime *runtime = subs->runtime; 994 struct snd_pcm_runtime *runtime = subs->runtime;
849 struct pcxhr_stream *stream; 995 struct pcxhr_stream *stream;
996 int err;
850 997
851 mutex_lock(&mgr->setup_mutex); 998 mutex_lock(&mgr->setup_mutex);
852 999
@@ -874,6 +1021,18 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
874 return -EBUSY; 1021 return -EBUSY;
875 } 1022 }
876 1023
1024 /* float format support is in some cases buggy on stereo cards */
1025 if (mgr->is_hr_stereo)
1026 runtime->hw.formats &= ~SNDRV_PCM_FMTBIT_FLOAT_LE;
1027
1028 /* buffer-size should better be multiple of period-size */
1029 err = snd_pcm_hw_constraint_integer(runtime,
1030 SNDRV_PCM_HW_PARAM_PERIODS);
1031 if (err < 0) {
1032 mutex_unlock(&mgr->setup_mutex);
1033 return err;
1034 }
1035
877 /* if a sample rate is already used or fixed by external clock, 1036 /* if a sample rate is already used or fixed by external clock,
878 * the stream cannot change 1037 * the stream cannot change
879 */ 1038 */
@@ -889,7 +1048,8 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
889 mutex_unlock(&mgr->setup_mutex); 1048 mutex_unlock(&mgr->setup_mutex);
890 return -EBUSY; 1049 return -EBUSY;
891 } 1050 }
892 runtime->hw.rate_min = runtime->hw.rate_max = external_rate; 1051 runtime->hw.rate_min = external_rate;
1052 runtime->hw.rate_max = external_rate;
893 } 1053 }
894 } 1054 }
895 1055
@@ -899,9 +1059,11 @@ static int pcxhr_open(struct snd_pcm_substream *subs)
899 1059
900 runtime->private_data = stream; 1060 runtime->private_data = stream;
901 1061
902 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 4); 1062 /* better get a divisor of granularity values (96 or 192) */
903 snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 4); 1063 snd_pcm_hw_constraint_step(runtime, 0,
904 1064 SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 32);
1065 snd_pcm_hw_constraint_step(runtime, 0,
1066 SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 32);
905 snd_pcm_set_sync(subs); 1067 snd_pcm_set_sync(subs);
906 1068
907 mgr->ref_count_rate++; 1069 mgr->ref_count_rate++;
@@ -919,11 +1081,12 @@ static int pcxhr_close(struct snd_pcm_substream *subs)
919 1081
920 mutex_lock(&mgr->setup_mutex); 1082 mutex_lock(&mgr->setup_mutex);
921 1083
922 snd_printdd("pcxhr_close chip%d subs%d\n", chip->chip_idx, subs->number); 1084 snd_printdd("pcxhr_close chip%d subs%d\n",
1085 chip->chip_idx, subs->number);
923 1086
924 /* sample rate released */ 1087 /* sample rate released */
925 if (--mgr->ref_count_rate == 0) { 1088 if (--mgr->ref_count_rate == 0) {
926 mgr->sample_rate = 0; /* the sample rate is no more locked */ 1089 mgr->sample_rate = 0; /* the sample rate is no more locked */
927 pcxhr_hardware_timer(mgr, 0); /* stop the DSP-timer */ 1090 pcxhr_hardware_timer(mgr, 0); /* stop the DSP-timer */
928 } 1091 }
929 1092
@@ -1016,7 +1179,8 @@ static int pcxhr_chip_dev_free(struct snd_device *device)
1016 1179
1017/* 1180/*
1018 */ 1181 */
1019static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card, int idx) 1182static int __devinit pcxhr_create(struct pcxhr_mgr *mgr,
1183 struct snd_card *card, int idx)
1020{ 1184{
1021 int err; 1185 int err;
1022 struct snd_pcxhr *chip; 1186 struct snd_pcxhr *chip;
@@ -1024,7 +1188,7 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
1024 .dev_free = pcxhr_chip_dev_free, 1188 .dev_free = pcxhr_chip_dev_free,
1025 }; 1189 };
1026 1190
1027 mgr->chip[idx] = chip = kzalloc(sizeof(*chip), GFP_KERNEL); 1191 chip = kzalloc(sizeof(*chip), GFP_KERNEL);
1028 if (! chip) { 1192 if (! chip) {
1029 snd_printk(KERN_ERR "cannot allocate chip\n"); 1193 snd_printk(KERN_ERR "cannot allocate chip\n");
1030 return -ENOMEM; 1194 return -ENOMEM;
@@ -1040,7 +1204,7 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
1040 1204
1041 if (idx < mgr->capture_chips) { 1205 if (idx < mgr->capture_chips) {
1042 if (mgr->mono_capture) 1206 if (mgr->mono_capture)
1043 chip->nb_streams_capt = 2; /* 2 mono streams (left+right) */ 1207 chip->nb_streams_capt = 2; /* 2 mono streams */
1044 else 1208 else
1045 chip->nb_streams_capt = 1; /* or 1 stereo stream */ 1209 chip->nb_streams_capt = 1; /* or 1 stereo stream */
1046 } 1210 }
@@ -1050,13 +1214,15 @@ static int __devinit pcxhr_create(struct pcxhr_mgr *mgr, struct snd_card *card,
1050 return err; 1214 return err;
1051 } 1215 }
1052 1216
1217 mgr->chip[idx] = chip;
1053 snd_card_set_dev(card, &mgr->pci->dev); 1218 snd_card_set_dev(card, &mgr->pci->dev);
1054 1219
1055 return 0; 1220 return 0;
1056} 1221}
1057 1222
1058/* proc interface */ 1223/* proc interface */
1059static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 1224static void pcxhr_proc_info(struct snd_info_entry *entry,
1225 struct snd_info_buffer *buffer)
1060{ 1226{
1061 struct snd_pcxhr *chip = entry->private_data; 1227 struct snd_pcxhr *chip = entry->private_data;
1062 struct pcxhr_mgr *mgr = chip->mgr; 1228 struct pcxhr_mgr *mgr = chip->mgr;
@@ -1069,8 +1235,10 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer
1069 short ver_maj = (mgr->dsp_version >> 16) & 0xff; 1235 short ver_maj = (mgr->dsp_version >> 16) & 0xff;
1070 short ver_min = (mgr->dsp_version >> 8) & 0xff; 1236 short ver_min = (mgr->dsp_version >> 8) & 0xff;
1071 short ver_build = mgr->dsp_version & 0xff; 1237 short ver_build = mgr->dsp_version & 0xff;
1072 snd_iprintf(buffer, "module version %s\n", PCXHR_DRIVER_VERSION_STRING); 1238 snd_iprintf(buffer, "module version %s\n",
1073 snd_iprintf(buffer, "dsp version %d.%d.%d\n", ver_maj, ver_min, ver_build); 1239 PCXHR_DRIVER_VERSION_STRING);
1240 snd_iprintf(buffer, "dsp version %d.%d.%d\n",
1241 ver_maj, ver_min, ver_build);
1074 if (mgr->board_has_analog) 1242 if (mgr->board_has_analog)
1075 snd_iprintf(buffer, "analog io available\n"); 1243 snd_iprintf(buffer, "analog io available\n");
1076 else 1244 else
@@ -1084,18 +1252,22 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer
1084 if (ref > 0) { 1252 if (ref > 0) {
1085 if (mgr->sample_rate_real != 0 && 1253 if (mgr->sample_rate_real != 0 &&
1086 mgr->sample_rate_real != 48000) { 1254 mgr->sample_rate_real != 48000) {
1087 ref = (ref * 48000) / mgr->sample_rate_real; 1255 ref = (ref * 48000) /
1088 if (mgr->sample_rate_real >= PCXHR_IRQ_TIMER_FREQ) 1256 mgr->sample_rate_real;
1257 if (mgr->sample_rate_real >=
1258 PCXHR_IRQ_TIMER_FREQ)
1089 ref *= 2; 1259 ref *= 2;
1090 } 1260 }
1091 cur = 100 - (100 * cur) / ref; 1261 cur = 100 - (100 * cur) / ref;
1092 snd_iprintf(buffer, "cpu load %d%%\n", cur); 1262 snd_iprintf(buffer, "cpu load %d%%\n", cur);
1093 snd_iprintf(buffer, "buffer pool %d/%d kWords\n", 1263 snd_iprintf(buffer, "buffer pool %d/%d\n",
1094 rmh.stat[2], rmh.stat[3]); 1264 rmh.stat[2], rmh.stat[3]);
1095 } 1265 }
1096 } 1266 }
1097 snd_iprintf(buffer, "dma granularity : %d\n", PCXHR_GRANULARITY); 1267 snd_iprintf(buffer, "dma granularity : %d\n",
1098 snd_iprintf(buffer, "dsp time errors : %d\n", mgr->dsp_time_err); 1268 mgr->granularity);
1269 snd_iprintf(buffer, "dsp time errors : %d\n",
1270 mgr->dsp_time_err);
1099 snd_iprintf(buffer, "dsp async pipe xrun errors : %d\n", 1271 snd_iprintf(buffer, "dsp async pipe xrun errors : %d\n",
1100 mgr->async_err_pipe_xrun); 1272 mgr->async_err_pipe_xrun);
1101 snd_iprintf(buffer, "dsp async stream xrun errors : %d\n", 1273 snd_iprintf(buffer, "dsp async stream xrun errors : %d\n",
@@ -1110,33 +1282,52 @@ static void pcxhr_proc_info(struct snd_info_entry *entry, struct snd_info_buffer
1110 rmh.cmd_idx = CMD_LAST_INDEX; 1282 rmh.cmd_idx = CMD_LAST_INDEX;
1111 if( ! pcxhr_send_msg(mgr, &rmh) ) { 1283 if( ! pcxhr_send_msg(mgr, &rmh) ) {
1112 int i; 1284 int i;
1285 if (rmh.stat_len > 8)
1286 rmh.stat_len = 8;
1113 for (i = 0; i < rmh.stat_len; i++) 1287 for (i = 0; i < rmh.stat_len; i++)
1114 snd_iprintf(buffer, "debug[%02d] = %06x\n", i, rmh.stat[i]); 1288 snd_iprintf(buffer, "debug[%02d] = %06x\n",
1289 i, rmh.stat[i]);
1115 } 1290 }
1116 } else 1291 } else
1117 snd_iprintf(buffer, "no firmware loaded\n"); 1292 snd_iprintf(buffer, "no firmware loaded\n");
1118 snd_iprintf(buffer, "\n"); 1293 snd_iprintf(buffer, "\n");
1119} 1294}
1120static void pcxhr_proc_sync(struct snd_info_entry *entry, struct snd_info_buffer *buffer) 1295static void pcxhr_proc_sync(struct snd_info_entry *entry,
1296 struct snd_info_buffer *buffer)
1121{ 1297{
1122 struct snd_pcxhr *chip = entry->private_data; 1298 struct snd_pcxhr *chip = entry->private_data;
1123 struct pcxhr_mgr *mgr = chip->mgr; 1299 struct pcxhr_mgr *mgr = chip->mgr;
1124 static char *texts[7] = { 1300 static const char *textsHR22[3] = {
1125 "Internal", "Word", "AES Sync", "AES 1", "AES 2", "AES 3", "AES 4" 1301 "Internal", "AES Sync", "AES 1"
1302 };
1303 static const char *textsPCXHR[7] = {
1304 "Internal", "Word", "AES Sync",
1305 "AES 1", "AES 2", "AES 3", "AES 4"
1126 }; 1306 };
1307 const char **texts;
1308 int max_clock;
1309 if (mgr->is_hr_stereo) {
1310 texts = textsHR22;
1311 max_clock = HR22_CLOCK_TYPE_MAX;
1312 } else {
1313 texts = textsPCXHR;
1314 max_clock = PCXHR_CLOCK_TYPE_MAX;
1315 }
1127 1316
1128 snd_iprintf(buffer, "\n%s\n", mgr->longname); 1317 snd_iprintf(buffer, "\n%s\n", mgr->longname);
1129 snd_iprintf(buffer, "Current Sample Clock\t: %s\n", texts[mgr->cur_clock_type]); 1318 snd_iprintf(buffer, "Current Sample Clock\t: %s\n",
1130 snd_iprintf(buffer, "Current Sample Rate\t= %d\n", mgr->sample_rate_real); 1319 texts[mgr->cur_clock_type]);
1131 1320 snd_iprintf(buffer, "Current Sample Rate\t= %d\n",
1321 mgr->sample_rate_real);
1132 /* commands available when embedded DSP is running */ 1322 /* commands available when embedded DSP is running */
1133 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) { 1323 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
1134 int i, err, sample_rate; 1324 int i, err, sample_rate;
1135 for (i = PCXHR_CLOCK_TYPE_WORD_CLOCK; i< (3 + mgr->capture_chips); i++) { 1325 for (i = 1; i <= max_clock; i++) {
1136 err = pcxhr_get_external_clock(mgr, i, &sample_rate); 1326 err = pcxhr_get_external_clock(mgr, i, &sample_rate);
1137 if (err) 1327 if (err)
1138 break; 1328 break;
1139 snd_iprintf(buffer, "%s Clock\t\t= %d\n", texts[i], sample_rate); 1329 snd_iprintf(buffer, "%s Clock\t\t= %d\n",
1330 texts[i], sample_rate);
1140 } 1331 }
1141 } else 1332 } else
1142 snd_iprintf(buffer, "no firmware loaded\n"); 1333 snd_iprintf(buffer, "no firmware loaded\n");
@@ -1194,7 +1385,8 @@ static int pcxhr_free(struct pcxhr_mgr *mgr)
1194/* 1385/*
1195 * probe function - creates the card manager 1386 * probe function - creates the card manager
1196 */ 1387 */
1197static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) 1388static int __devinit pcxhr_probe(struct pci_dev *pci,
1389 const struct pci_device_id *pci_id)
1198{ 1390{
1199 static int dev; 1391 static int dev;
1200 struct pcxhr_mgr *mgr; 1392 struct pcxhr_mgr *mgr;
@@ -1217,7 +1409,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1217 1409
1218 /* check if we can restrict PCI DMA transfers to 32 bits */ 1410 /* check if we can restrict PCI DMA transfers to 32 bits */
1219 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) { 1411 if (pci_set_dma_mask(pci, DMA_32BIT_MASK) < 0) {
1220 snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n"); 1412 snd_printk(KERN_ERR "architecture does not support "
1413 "32bit PCI busmaster DMA\n");
1221 pci_disable_device(pci); 1414 pci_disable_device(pci);
1222 return -ENXIO; 1415 return -ENXIO;
1223 } 1416 }
@@ -1234,11 +1427,25 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1234 pci_disable_device(pci); 1427 pci_disable_device(pci);
1235 return -ENODEV; 1428 return -ENODEV;
1236 } 1429 }
1237 card_name = pcxhr_board_params[pci_id->driver_data].board_name; 1430 card_name =
1238 mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips; 1431 pcxhr_board_params[pci_id->driver_data].board_name;
1239 mgr->capture_chips = pcxhr_board_params[pci_id->driver_data].capture_chips; 1432 mgr->playback_chips =
1240 mgr->firmware_num = pcxhr_board_params[pci_id->driver_data].firmware_num; 1433 pcxhr_board_params[pci_id->driver_data].playback_chips;
1434 mgr->capture_chips =
1435 pcxhr_board_params[pci_id->driver_data].capture_chips;
1436 mgr->fw_file_set =
1437 pcxhr_board_params[pci_id->driver_data].fw_file_set;
1438 mgr->firmware_num =
1439 pcxhr_board_params[pci_id->driver_data].firmware_num;
1241 mgr->mono_capture = mono[dev]; 1440 mgr->mono_capture = mono[dev];
1441 mgr->is_hr_stereo = (mgr->playback_chips == 1);
1442 mgr->board_has_aes1 = PCXHR_BOARD_HAS_AES1(mgr);
1443 mgr->board_aes_in_192k = !PCXHR_BOARD_AESIN_NO_192K(mgr);
1444
1445 if (mgr->is_hr_stereo)
1446 mgr->granularity = PCXHR_GRANULARITY_HR22;
1447 else
1448 mgr->granularity = PCXHR_GRANULARITY;
1242 1449
1243 /* resource assignment */ 1450 /* resource assignment */
1244 if ((err = pci_request_regions(pci, card_name)) < 0) { 1451 if ((err = pci_request_regions(pci, card_name)) < 0) {
@@ -1261,7 +1468,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1261 mgr->irq = pci->irq; 1468 mgr->irq = pci->irq;
1262 1469
1263 sprintf(mgr->shortname, "Digigram %s", card_name); 1470 sprintf(mgr->shortname, "Digigram %s", card_name);
1264 sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i", mgr->shortname, 1471 sprintf(mgr->longname, "%s at 0x%lx & 0x%lx, 0x%lx irq %i",
1472 mgr->shortname,
1265 mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq); 1473 mgr->port[0], mgr->port[1], mgr->port[2], mgr->irq);
1266 1474
1267 /* ISR spinlock */ 1475 /* ISR spinlock */
@@ -1272,10 +1480,14 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1272 mutex_init(&mgr->setup_mutex); 1480 mutex_init(&mgr->setup_mutex);
1273 1481
1274 /* init taslket */ 1482 /* init taslket */
1275 tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet, (unsigned long) mgr); 1483 tasklet_init(&mgr->msg_taskq, pcxhr_msg_tasklet,
1276 tasklet_init(&mgr->trigger_taskq, pcxhr_trigger_tasklet, (unsigned long) mgr); 1484 (unsigned long) mgr);
1485 tasklet_init(&mgr->trigger_taskq, pcxhr_trigger_tasklet,
1486 (unsigned long) mgr);
1487
1277 mgr->prmh = kmalloc(sizeof(*mgr->prmh) + 1488 mgr->prmh = kmalloc(sizeof(*mgr->prmh) +
1278 sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS - PCXHR_SIZE_MAX_STATUS), 1489 sizeof(u32) * (PCXHR_SIZE_MAX_LONG_STATUS -
1490 PCXHR_SIZE_MAX_STATUS),
1279 GFP_KERNEL); 1491 GFP_KERNEL);
1280 if (! mgr->prmh) { 1492 if (! mgr->prmh) {
1281 pcxhr_free(mgr); 1493 pcxhr_free(mgr);
@@ -1296,7 +1508,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1296 else 1508 else
1297 idx = index[dev] + i; 1509 idx = index[dev] + i;
1298 1510
1299 snprintf(tmpid, sizeof(tmpid), "%s-%d", id[dev] ? id[dev] : card_name, i); 1511 snprintf(tmpid, sizeof(tmpid), "%s-%d",
1512 id[dev] ? id[dev] : card_name, i);
1300 card = snd_card_new(idx, tmpid, THIS_MODULE, 0); 1513 card = snd_card_new(idx, tmpid, THIS_MODULE, 0);
1301 1514
1302 if (! card) { 1515 if (! card) {
@@ -1310,6 +1523,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id
1310 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i); 1523 sprintf(card->longname, "%s [PCM #%d]", mgr->longname, i);
1311 1524
1312 if ((err = pcxhr_create(mgr, card, i)) < 0) { 1525 if ((err = pcxhr_create(mgr, card, i)) < 0) {
1526 snd_card_free(card);
1313 pcxhr_free(mgr); 1527 pcxhr_free(mgr);
1314 return err; 1528 return err;
1315 } 1529 }
diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h
index 652064787a55..84131a916c92 100644
--- a/sound/pci/pcxhr/pcxhr.h
+++ b/sound/pci/pcxhr/pcxhr.h
@@ -27,15 +27,18 @@
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29 29
30#define PCXHR_DRIVER_VERSION 0x000804 /* 0.8.4 */ 30#define PCXHR_DRIVER_VERSION 0x000905 /* 0.9.5 */
31#define PCXHR_DRIVER_VERSION_STRING "0.8.4" /* 0.8.4 */ 31#define PCXHR_DRIVER_VERSION_STRING "0.9.5" /* 0.9.5 */
32 32
33 33
34#define PCXHR_MAX_CARDS 6 34#define PCXHR_MAX_CARDS 6
35#define PCXHR_PLAYBACK_STREAMS 4 35#define PCXHR_PLAYBACK_STREAMS 4
36 36
37#define PCXHR_GRANULARITY 96 /* transfer granularity (should be min 96 and multiple of 48) */ 37#define PCXHR_GRANULARITY 96 /* min 96 and multiple of 48 */
38#define PCXHR_GRANULARITY_MIN 96 /* transfer granularity of pipes and the dsp time (MBOX4) */ 38/* transfer granularity of pipes and the dsp time (MBOX4) */
39#define PCXHR_GRANULARITY_MIN 96
40/* TODO : granularity could be 64 or 128 */
41#define PCXHR_GRANULARITY_HR22 192 /* granularity for stereo cards */
39 42
40struct snd_pcxhr; 43struct snd_pcxhr;
41struct pcxhr_mgr; 44struct pcxhr_mgr;
@@ -51,6 +54,11 @@ enum pcxhr_clock_type {
51 PCXHR_CLOCK_TYPE_AES_2, 54 PCXHR_CLOCK_TYPE_AES_2,
52 PCXHR_CLOCK_TYPE_AES_3, 55 PCXHR_CLOCK_TYPE_AES_3,
53 PCXHR_CLOCK_TYPE_AES_4, 56 PCXHR_CLOCK_TYPE_AES_4,
57 PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4,
58 HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL,
59 HR22_CLOCK_TYPE_AES_SYNC,
60 HR22_CLOCK_TYPE_AES_1,
61 HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1,
54}; 62};
55 63
56struct pcxhr_mgr { 64struct pcxhr_mgr {
@@ -61,6 +69,8 @@ struct pcxhr_mgr {
61 69
62 int irq; 70 int irq;
63 71
72 int granularity;
73
64 /* card access with 1 mem bar and 2 io bar's */ 74 /* card access with 1 mem bar and 2 io bar's */
65 unsigned long port[3]; 75 unsigned long port[3];
66 76
@@ -83,11 +93,16 @@ struct pcxhr_mgr {
83 /* hardware interface */ 93 /* hardware interface */
84 unsigned int dsp_loaded; /* bit flags of loaded dsp indices */ 94 unsigned int dsp_loaded; /* bit flags of loaded dsp indices */
85 unsigned int dsp_version; /* read from embedded once firmware is loaded */ 95 unsigned int dsp_version; /* read from embedded once firmware is loaded */
86 int board_has_analog; /* if 0 the board is digital only */ 96 int playback_chips;
87 int mono_capture; /* if 1 the board does mono capture */ 97 int capture_chips;
88 int playback_chips; /* 4 or 6 */ 98 int fw_file_set;
89 int capture_chips; /* 4 or 1 */ 99 int firmware_num;
90 int firmware_num; /* 41 or 42 */ 100 int is_hr_stereo:1;
101 int board_has_aes1:1; /* if 1 board has AES1 plug and SRC */
102 int board_has_analog:1; /* if 0 the board is digital only */
103 int board_has_mic:1; /* if 1 the board has microphone input */
104 int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */
105 int mono_capture:1; /* if 1 the board does mono capture */
91 106
92 struct snd_dma_buffer hostport; 107 struct snd_dma_buffer hostport;
93 108
@@ -106,6 +121,9 @@ struct pcxhr_mgr {
106 int async_err_stream_xrun; 121 int async_err_stream_xrun;
107 int async_err_pipe_xrun; 122 int async_err_pipe_xrun;
108 int async_err_other_last; 123 int async_err_other_last;
124
125 unsigned char xlx_cfg; /* copy of PCXHR_XLX_CFG register */
126 unsigned char xlx_selmic; /* copy of PCXHR_XLX_SELMIC register */
109}; 127};
110 128
111 129
@@ -155,24 +173,30 @@ struct snd_pcxhr {
155 173
156 struct snd_pcm *pcm; /* PCM */ 174 struct snd_pcm *pcm; /* PCM */
157 175
158 struct pcxhr_pipe playback_pipe; /* 1 stereo pipe only */ 176 struct pcxhr_pipe playback_pipe; /* 1 stereo pipe only */
159 struct pcxhr_pipe capture_pipe[2]; /* 1 stereo pipe or 2 mono pipes */ 177 struct pcxhr_pipe capture_pipe[2]; /* 1 stereo or 2 mono pipes */
160 178
161 struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS]; 179 struct pcxhr_stream playback_stream[PCXHR_PLAYBACK_STREAMS];
162 struct pcxhr_stream capture_stream[2]; /* 1 stereo stream or 2 mono streams */ 180 struct pcxhr_stream capture_stream[2]; /* 1 stereo or 2 mono streams */
163 int nb_streams_play; 181 int nb_streams_play;
164 int nb_streams_capt; 182 int nb_streams_capt;
165 183
166 int analog_playback_active[2]; /* Mixer : Master Playback active (!mute) */ 184 int analog_playback_active[2]; /* Mixer : Master Playback !mute */
167 int analog_playback_volume[2]; /* Mixer : Master Playback Volume */ 185 int analog_playback_volume[2]; /* Mixer : Master Playback Volume */
168 int analog_capture_volume[2]; /* Mixer : Master Capture Volume */ 186 int analog_capture_volume[2]; /* Mixer : Master Capture Volume */
169 int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Active [streams][stereo]*/ 187 int digital_playback_active[PCXHR_PLAYBACK_STREAMS][2];
170 int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2]; /* Mixer : Digital Playback Volume [streams][stereo]*/ 188 int digital_playback_volume[PCXHR_PLAYBACK_STREAMS][2];
171 int digital_capture_volume[2]; /* Mixer : Digital Capture Volume [stereo] */ 189 int digital_capture_volume[2]; /* Mixer : Digital Capture Volume */
172 int monitoring_active[2]; /* Mixer : Monitoring Active */ 190 int monitoring_active[2]; /* Mixer : Monitoring Active */
173 int monitoring_volume[2]; /* Mixer : Monitoring Volume */ 191 int monitoring_volume[2]; /* Mixer : Monitoring Volume */
174 int audio_capture_source; /* Mixer : Audio Capture Source */ 192 int audio_capture_source; /* Mixer : Audio Capture Source */
175 unsigned char aes_bits[5]; /* Mixer : IEC958_AES bits */ 193 int mic_volume; /* used by cards with MIC only */
194 int mic_boost; /* used by cards with MIC only */
195 int mic_active; /* used by cards with MIC only */
196 int analog_capture_active; /* used by cards with MIC only */
197 int phantom_power; /* used by cards with MIC only */
198
199 unsigned char aes_bits[5]; /* Mixer : IEC958_AES bits */
176}; 200};
177 201
178struct pcxhr_hostport 202struct pcxhr_hostport
@@ -184,6 +208,8 @@ struct pcxhr_hostport
184/* exported */ 208/* exported */
185int pcxhr_create_pcm(struct snd_pcxhr *chip); 209int pcxhr_create_pcm(struct snd_pcxhr *chip);
186int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate); 210int pcxhr_set_clock(struct pcxhr_mgr *mgr, unsigned int rate);
187int pcxhr_get_external_clock(struct pcxhr_mgr *mgr, enum pcxhr_clock_type clock_type, int *sample_rate); 211int pcxhr_get_external_clock(struct pcxhr_mgr *mgr,
212 enum pcxhr_clock_type clock_type,
213 int *sample_rate);
188 214
189#endif /* __SOUND_PCXHR_H */ 215#endif /* __SOUND_PCXHR_H */
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index 7143259cfe34..833e7180ad2d 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -132,13 +132,15 @@ static int pcxhr_check_reg_bit(struct pcxhr_mgr *mgr, unsigned int reg,
132 *read = PCXHR_INPB(mgr, reg); 132 *read = PCXHR_INPB(mgr, reg);
133 if ((*read & mask) == bit) { 133 if ((*read & mask) == bit) {
134 if (i > 100) 134 if (i > 100)
135 snd_printdd("ATTENTION! check_reg(%x) loopcount=%d\n", 135 snd_printdd("ATTENTION! check_reg(%x) "
136 "loopcount=%d\n",
136 reg, i); 137 reg, i);
137 return 0; 138 return 0;
138 } 139 }
139 i++; 140 i++;
140 } while (time_after_eq(end_time, jiffies)); 141 } while (time_after_eq(end_time, jiffies));
141 snd_printk(KERN_ERR "pcxhr_check_reg_bit: timeout, reg=%x, mask=0x%x, val=0x%x\n", 142 snd_printk(KERN_ERR
143 "pcxhr_check_reg_bit: timeout, reg=%x, mask=0x%x, val=%x\n",
142 reg, mask, *read); 144 reg, mask, *read);
143 return -EIO; 145 return -EIO;
144} 146}
@@ -159,18 +161,22 @@ static int pcxhr_check_reg_bit(struct pcxhr_mgr *mgr, unsigned int reg,
159#define PCXHR_IT_TEST_XILINX (0x0000003C | PCXHR_MASK_IT_HF1 | \ 161#define PCXHR_IT_TEST_XILINX (0x0000003C | PCXHR_MASK_IT_HF1 | \
160 PCXHR_MASK_IT_MANAGE_HF5) 162 PCXHR_MASK_IT_MANAGE_HF5)
161#define PCXHR_IT_DOWNLOAD_BOOT (0x0000000C | PCXHR_MASK_IT_HF1 | \ 163#define PCXHR_IT_DOWNLOAD_BOOT (0x0000000C | PCXHR_MASK_IT_HF1 | \
162 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT) 164 PCXHR_MASK_IT_MANAGE_HF5 | \
165 PCXHR_MASK_IT_WAIT)
163#define PCXHR_IT_RESET_BOARD_FUNC (0x0000000C | PCXHR_MASK_IT_HF0 | \ 166#define PCXHR_IT_RESET_BOARD_FUNC (0x0000000C | PCXHR_MASK_IT_HF0 | \
164 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT_EXTRA) 167 PCXHR_MASK_IT_MANAGE_HF5 | \
168 PCXHR_MASK_IT_WAIT_EXTRA)
165#define PCXHR_IT_DOWNLOAD_DSP (0x0000000C | \ 169#define PCXHR_IT_DOWNLOAD_DSP (0x0000000C | \
166 PCXHR_MASK_IT_MANAGE_HF5 | PCXHR_MASK_IT_WAIT) 170 PCXHR_MASK_IT_MANAGE_HF5 | \
171 PCXHR_MASK_IT_WAIT)
167#define PCXHR_IT_DEBUG (0x0000005A | PCXHR_MASK_IT_NO_HF0_HF1) 172#define PCXHR_IT_DEBUG (0x0000005A | PCXHR_MASK_IT_NO_HF0_HF1)
168#define PCXHR_IT_RESET_SEMAPHORE (0x0000005C | PCXHR_MASK_IT_NO_HF0_HF1) 173#define PCXHR_IT_RESET_SEMAPHORE (0x0000005C | PCXHR_MASK_IT_NO_HF0_HF1)
169#define PCXHR_IT_MESSAGE (0x00000074 | PCXHR_MASK_IT_NO_HF0_HF1) 174#define PCXHR_IT_MESSAGE (0x00000074 | PCXHR_MASK_IT_NO_HF0_HF1)
170#define PCXHR_IT_RESET_CHK (0x00000076 | PCXHR_MASK_IT_NO_HF0_HF1) 175#define PCXHR_IT_RESET_CHK (0x00000076 | PCXHR_MASK_IT_NO_HF0_HF1)
171#define PCXHR_IT_UPDATE_RBUFFER (0x00000078 | PCXHR_MASK_IT_NO_HF0_HF1) 176#define PCXHR_IT_UPDATE_RBUFFER (0x00000078 | PCXHR_MASK_IT_NO_HF0_HF1)
172 177
173static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atomic) 178static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr,
179 unsigned int itdsp, int atomic)
174{ 180{
175 int err; 181 int err;
176 unsigned char reg; 182 unsigned char reg;
@@ -178,17 +184,21 @@ static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atom
178 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) { 184 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
179 /* clear hf5 bit */ 185 /* clear hf5 bit */
180 PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0, 186 PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX0,
181 PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & ~PCXHR_MBOX0_HF5); 187 PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) &
188 ~PCXHR_MBOX0_HF5);
182 } 189 }
183 if ((itdsp & PCXHR_MASK_IT_NO_HF0_HF1) == 0) { 190 if ((itdsp & PCXHR_MASK_IT_NO_HF0_HF1) == 0) {
184 reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ; 191 reg = (PCXHR_ICR_HI08_RREQ |
192 PCXHR_ICR_HI08_TREQ |
193 PCXHR_ICR_HI08_HDRQ);
185 if (itdsp & PCXHR_MASK_IT_HF0) 194 if (itdsp & PCXHR_MASK_IT_HF0)
186 reg |= PCXHR_ICR_HI08_HF0; 195 reg |= PCXHR_ICR_HI08_HF0;
187 if (itdsp & PCXHR_MASK_IT_HF1) 196 if (itdsp & PCXHR_MASK_IT_HF1)
188 reg |= PCXHR_ICR_HI08_HF1; 197 reg |= PCXHR_ICR_HI08_HF1;
189 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg); 198 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
190 } 199 }
191 reg = (unsigned char)(((itdsp & PCXHR_MASK_EXTRA_INFO) >> 1) | PCXHR_CVR_HI08_HC); 200 reg = (unsigned char)(((itdsp & PCXHR_MASK_EXTRA_INFO) >> 1) |
201 PCXHR_CVR_HI08_HC);
192 PCXHR_OUTPB(mgr, PCXHR_DSP_CVR, reg); 202 PCXHR_OUTPB(mgr, PCXHR_DSP_CVR, reg);
193 if (itdsp & PCXHR_MASK_IT_WAIT) { 203 if (itdsp & PCXHR_MASK_IT_WAIT) {
194 if (atomic) 204 if (atomic)
@@ -211,10 +221,14 @@ static int pcxhr_send_it_dsp(struct pcxhr_mgr *mgr, unsigned int itdsp, int atom
211 } 221 }
212 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) { 222 if (itdsp & PCXHR_MASK_IT_MANAGE_HF5) {
213 /* wait for hf5 bit */ 223 /* wait for hf5 bit */
214 err = pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0, PCXHR_MBOX0_HF5, 224 err = pcxhr_check_reg_bit(mgr, PCXHR_PLX_MBOX0,
215 PCXHR_MBOX0_HF5, PCXHR_TIMEOUT_DSP, &reg); 225 PCXHR_MBOX0_HF5,
226 PCXHR_MBOX0_HF5,
227 PCXHR_TIMEOUT_DSP,
228 &reg);
216 if (err) { 229 if (err) {
217 snd_printk(KERN_ERR "pcxhr_send_it_dsp : TIMEOUT HF5\n"); 230 snd_printk(KERN_ERR
231 "pcxhr_send_it_dsp : TIMEOUT HF5\n");
218 return err; 232 return err;
219 } 233 }
220 } 234 }
@@ -263,7 +277,8 @@ void pcxhr_enable_dsp(struct pcxhr_mgr *mgr)
263/* 277/*
264 * load the xilinx image 278 * load the xilinx image
265 */ 279 */
266int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilinx, int second) 280int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr,
281 const struct firmware *xilinx, int second)
267{ 282{
268 unsigned int i; 283 unsigned int i;
269 unsigned int chipsc; 284 unsigned int chipsc;
@@ -274,7 +289,9 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin
274 /* test first xilinx */ 289 /* test first xilinx */
275 chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC); 290 chipsc = PCXHR_INPL(mgr, PCXHR_PLX_CHIPSC);
276 /* REV01 cards do not support the PCXHR_CHIPSC_GPI_USERI bit anymore */ 291 /* REV01 cards do not support the PCXHR_CHIPSC_GPI_USERI bit anymore */
277 /* this bit will always be 1; no possibility to test presence of first xilinx */ 292 /* this bit will always be 1;
293 * no possibility to test presence of first xilinx
294 */
278 if(second) { 295 if(second) {
279 if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) { 296 if ((chipsc & PCXHR_CHIPSC_GPI_USERI) == 0) {
280 snd_printk(KERN_ERR "error loading first xilinx\n"); 297 snd_printk(KERN_ERR "error loading first xilinx\n");
@@ -290,7 +307,8 @@ int pcxhr_load_xilinx_binary(struct pcxhr_mgr *mgr, const struct firmware *xilin
290 data = *image; 307 data = *image;
291 mask = 0x80; 308 mask = 0x80;
292 while (mask) { 309 while (mask) {
293 chipsc &= ~(PCXHR_CHIPSC_DATA_CLK | PCXHR_CHIPSC_DATA_IN); 310 chipsc &= ~(PCXHR_CHIPSC_DATA_CLK |
311 PCXHR_CHIPSC_DATA_IN);
294 if (data & mask) 312 if (data & mask)
295 chipsc |= PCXHR_CHIPSC_DATA_IN; 313 chipsc |= PCXHR_CHIPSC_DATA_IN;
296 PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc); 314 PCXHR_OUTPL(mgr, PCXHR_PLX_CHIPSC, chipsc);
@@ -330,15 +348,20 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
330 data = dsp->data + i; 348 data = dsp->data + i;
331 if (i == 0) { 349 if (i == 0) {
332 /* test data header consistency */ 350 /* test data header consistency */
333 len = (unsigned int)((data[0]<<16) + (data[1]<<8) + data[2]); 351 len = (unsigned int)((data[0]<<16) +
334 if (len && dsp->size != (len + 2) * 3) 352 (data[1]<<8) +
353 data[2]);
354 if (len && (dsp->size != (len + 2) * 3))
335 return -EINVAL; 355 return -EINVAL;
336 } 356 }
337 /* wait DSP ready for new transfer */ 357 /* wait DSP ready for new transfer */
338 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, 358 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
339 PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &dummy); 359 PCXHR_ISR_HI08_TRDY,
360 PCXHR_ISR_HI08_TRDY,
361 PCXHR_TIMEOUT_DSP, &dummy);
340 if (err) { 362 if (err) {
341 snd_printk(KERN_ERR "dsp loading error at position %d\n", i); 363 snd_printk(KERN_ERR
364 "dsp loading error at position %d\n", i);
342 return err; 365 return err;
343 } 366 }
344 /* send host data */ 367 /* send host data */
@@ -357,7 +380,8 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp)
357/* 380/*
358 * load the eeprom image 381 * load the eeprom image
359 */ 382 */
360int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eeprom) 383int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr,
384 const struct firmware *eeprom)
361{ 385{
362 int err; 386 int err;
363 unsigned char reg; 387 unsigned char reg;
@@ -365,7 +389,9 @@ int pcxhr_load_eeprom_binary(struct pcxhr_mgr *mgr, const struct firmware *eepro
365 /* init value of the ICR register */ 389 /* init value of the ICR register */
366 reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ; 390 reg = PCXHR_ICR_HI08_RREQ | PCXHR_ICR_HI08_TREQ | PCXHR_ICR_HI08_HDRQ;
367 if (PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & PCXHR_MBOX0_BOOT_HERE) { 391 if (PCXHR_INPL(mgr, PCXHR_PLX_MBOX0) & PCXHR_MBOX0_BOOT_HERE) {
368 /* no need to load the eeprom binary, but init the HI08 interface */ 392 /* no need to load the eeprom binary,
393 * but init the HI08 interface
394 */
369 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg | PCXHR_ICR_HI08_INIT); 395 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg | PCXHR_ICR_HI08_INIT);
370 msleep(PCXHR_WAIT_DEFAULT); 396 msleep(PCXHR_WAIT_DEFAULT);
371 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg); 397 PCXHR_OUTPB(mgr, PCXHR_DSP_ICR, reg);
@@ -429,8 +455,10 @@ int pcxhr_load_dsp_binary(struct pcxhr_mgr *mgr, const struct firmware *dsp)
429 if (err) 455 if (err)
430 return err; 456 return err;
431 /* wait for chk bit */ 457 /* wait for chk bit */
432 return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_CHK, 458 return pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
433 PCXHR_ISR_HI08_CHK, PCXHR_TIMEOUT_DSP, &dummy); 459 PCXHR_ISR_HI08_CHK,
460 PCXHR_ISR_HI08_CHK,
461 PCXHR_TIMEOUT_DSP, &dummy);
434} 462}
435 463
436 464
@@ -443,8 +471,8 @@ struct pcxhr_cmd_info {
443/* RMH status type */ 471/* RMH status type */
444enum { 472enum {
445 RMH_SSIZE_FIXED = 0, /* status size fix (st_length = 0..x) */ 473 RMH_SSIZE_FIXED = 0, /* status size fix (st_length = 0..x) */
446 RMH_SSIZE_ARG = 1, /* status size given in the LSB byte (used with st_length = 1) */ 474 RMH_SSIZE_ARG = 1, /* status size given in the LSB byte */
447 RMH_SSIZE_MASK = 2, /* status size given in bitmask (used with st_length = 1) */ 475 RMH_SSIZE_MASK = 2, /* status size given in bitmask */
448}; 476};
449 477
450/* 478/*
@@ -474,7 +502,7 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
474[CMD_UPDATE_R_BUFFERS] = { 0x840000, 0, RMH_SSIZE_FIXED }, 502[CMD_UPDATE_R_BUFFERS] = { 0x840000, 0, RMH_SSIZE_FIXED },
475[CMD_FORMAT_STREAM_OUT] = { 0x860000, 0, RMH_SSIZE_FIXED }, 503[CMD_FORMAT_STREAM_OUT] = { 0x860000, 0, RMH_SSIZE_FIXED },
476[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED }, 504[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED },
477[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, /* stat_len = nb_streams * 2 */ 505[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED },
478[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, 506[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED },
479}; 507};
480 508
@@ -524,10 +552,13 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
524 552
525 for (i = 0; i < rmh->stat_len; i++) { 553 for (i = 0; i < rmh->stat_len; i++) {
526 /* wait for receiver full */ 554 /* wait for receiver full */
527 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_RXDF, 555 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
528 PCXHR_ISR_HI08_RXDF, PCXHR_TIMEOUT_DSP, &reg); 556 PCXHR_ISR_HI08_RXDF,
557 PCXHR_ISR_HI08_RXDF,
558 PCXHR_TIMEOUT_DSP, &reg);
529 if (err) { 559 if (err) {
530 snd_printk(KERN_ERR "ERROR RMH stat: ISR:RXDF=1 (ISR = %x; i=%d )\n", 560 snd_printk(KERN_ERR "ERROR RMH stat: "
561 "ISR:RXDF=1 (ISR = %x; i=%d )\n",
531 reg, i); 562 reg, i);
532 return err; 563 return err;
533 } 564 }
@@ -537,10 +568,10 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
537 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL); 568 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
538 569
539 /* need to update rmh->stat_len on the fly ?? */ 570 /* need to update rmh->stat_len on the fly ?? */
540 if (i==0) { 571 if (!i) {
541 if (rmh->dsp_stat != RMH_SSIZE_FIXED) { 572 if (rmh->dsp_stat != RMH_SSIZE_FIXED) {
542 if (rmh->dsp_stat == RMH_SSIZE_ARG) { 573 if (rmh->dsp_stat == RMH_SSIZE_ARG) {
543 rmh->stat_len = (u16)(data & 0x0000ff) + 1; 574 rmh->stat_len = (data & 0x0000ff) + 1;
544 data &= 0xffff00; 575 data &= 0xffff00;
545 } else { 576 } else {
546 /* rmh->dsp_stat == RMH_SSIZE_MASK */ 577 /* rmh->dsp_stat == RMH_SSIZE_MASK */
@@ -562,7 +593,8 @@ static int pcxhr_read_rmh_status(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
562 rmh->stat[i] = data; 593 rmh->stat[i] = data;
563 } 594 }
564 if (rmh->stat_len > max_stat_len) { 595 if (rmh->stat_len > max_stat_len) {
565 snd_printdd("PCXHR : rmh->stat_len=%x too big\n", rmh->stat_len); 596 snd_printdd("PCXHR : rmh->stat_len=%x too big\n",
597 rmh->stat_len);
566 rmh->stat_len = max_stat_len; 598 rmh->stat_len = max_stat_len;
567 } 599 }
568 return 0; 600 return 0;
@@ -605,7 +637,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
605 data &= 0xff7fff; /* MASK_1_WORD_COMMAND */ 637 data &= 0xff7fff; /* MASK_1_WORD_COMMAND */
606#ifdef CONFIG_SND_DEBUG_VERBOSE 638#ifdef CONFIG_SND_DEBUG_VERBOSE
607 if (rmh->cmd_idx < CMD_LAST_INDEX) 639 if (rmh->cmd_idx < CMD_LAST_INDEX)
608 snd_printdd("MSG cmd[0]=%x (%s)\n", data, cmd_names[rmh->cmd_idx]); 640 snd_printdd("MSG cmd[0]=%x (%s)\n",
641 data, cmd_names[rmh->cmd_idx]);
609#endif 642#endif
610 643
611 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, 644 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY,
@@ -619,8 +652,10 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
619 if (rmh->cmd_len > 1) { 652 if (rmh->cmd_len > 1) {
620 /* send length */ 653 /* send length */
621 data = rmh->cmd_len - 1; 654 data = rmh->cmd_len - 1;
622 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, 655 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
623 PCXHR_ISR_HI08_TRDY, PCXHR_TIMEOUT_DSP, &reg); 656 PCXHR_ISR_HI08_TRDY,
657 PCXHR_ISR_HI08_TRDY,
658 PCXHR_TIMEOUT_DSP, &reg);
624 if (err) 659 if (err)
625 return err; 660 return err;
626 PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF); 661 PCXHR_OUTPB(mgr, PCXHR_DSP_TXH, (data>>16)&0xFF);
@@ -653,8 +688,10 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
653 /* test status ISR */ 688 /* test status ISR */
654 if (reg & PCXHR_ISR_HI08_ERR) { 689 if (reg & PCXHR_ISR_HI08_ERR) {
655 /* ERROR, wait for receiver full */ 690 /* ERROR, wait for receiver full */
656 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_RXDF, 691 err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR,
657 PCXHR_ISR_HI08_RXDF, PCXHR_TIMEOUT_DSP, &reg); 692 PCXHR_ISR_HI08_RXDF,
693 PCXHR_ISR_HI08_RXDF,
694 PCXHR_TIMEOUT_DSP, &reg);
658 if (err) { 695 if (err) {
659 snd_printk(KERN_ERR "ERROR RMH: ISR:RXDF=1 (ISR = %x)\n", reg); 696 snd_printk(KERN_ERR "ERROR RMH: ISR:RXDF=1 (ISR = %x)\n", reg);
660 return err; 697 return err;
@@ -663,7 +700,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
663 data = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16; 700 data = PCXHR_INPB(mgr, PCXHR_DSP_TXH) << 16;
664 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8; 701 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXM) << 8;
665 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL); 702 data |= PCXHR_INPB(mgr, PCXHR_DSP_TXL);
666 snd_printk(KERN_ERR "ERROR RMH(%d): 0x%x\n", rmh->cmd_idx, data); 703 snd_printk(KERN_ERR "ERROR RMH(%d): 0x%x\n",
704 rmh->cmd_idx, data);
667 err = -EINVAL; 705 err = -EINVAL;
668 } else { 706 } else {
669 /* read the response data */ 707 /* read the response data */
@@ -732,8 +770,9 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh)
732static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr) 770static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
733{ 771{
734 int start_mask = PCXHR_INPL(mgr, PCXHR_PLX_MBOX2); 772 int start_mask = PCXHR_INPL(mgr, PCXHR_PLX_MBOX2);
735 /* least segnificant 12 bits are the pipe states for the playback audios */ 773 /* least segnificant 12 bits are the pipe states
736 /* next 12 bits are the pipe states for the capture audios 774 * for the playback audios
775 * next 12 bits are the pipe states for the capture audios
737 * (PCXHR_PIPE_STATE_CAPTURE_OFFSET) 776 * (PCXHR_PIPE_STATE_CAPTURE_OFFSET)
738 */ 777 */
739 start_mask &= 0xffffff; 778 start_mask &= 0xffffff;
@@ -744,7 +783,8 @@ static inline int pcxhr_pipes_running(struct pcxhr_mgr *mgr)
744#define PCXHR_PIPE_STATE_CAPTURE_OFFSET 12 783#define PCXHR_PIPE_STATE_CAPTURE_OFFSET 12
745#define MAX_WAIT_FOR_DSP 20 784#define MAX_WAIT_FOR_DSP 20
746 785
747static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr, int audio_mask, int *retry) 786static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr,
787 int audio_mask, int *retry)
748{ 788{
749 struct pcxhr_rmh rmh; 789 struct pcxhr_rmh rmh;
750 int err; 790 int err;
@@ -760,17 +800,20 @@ static int pcxhr_prepair_pipe_start(struct pcxhr_mgr *mgr, int audio_mask, int *
760 } else { 800 } else {
761 /* can start capture pipe */ 801 /* can start capture pipe */
762 pcxhr_set_pipe_cmd_params(&rmh, 1, audio - 802 pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
763 PCXHR_PIPE_STATE_CAPTURE_OFFSET, 803 PCXHR_PIPE_STATE_CAPTURE_OFFSET,
764 0, 0); 804 0, 0);
765 } 805 }
766 err = pcxhr_send_msg(mgr, &rmh); 806 err = pcxhr_send_msg(mgr, &rmh);
767 if (err) { 807 if (err) {
768 snd_printk(KERN_ERR 808 snd_printk(KERN_ERR
769 "error pipe start (CMD_CAN_START_PIPE) err=%x!\n", 809 "error pipe start "
810 "(CMD_CAN_START_PIPE) err=%x!\n",
770 err); 811 err);
771 return err; 812 return err;
772 } 813 }
773 /* if the pipe couldn't be prepaired for start, retry it later */ 814 /* if the pipe couldn't be prepaired for start,
815 * retry it later
816 */
774 if (rmh.stat[0] == 0) 817 if (rmh.stat[0] == 0)
775 *retry |= (1<<audio); 818 *retry |= (1<<audio);
776 } 819 }
@@ -795,14 +838,14 @@ static int pcxhr_stop_pipes(struct pcxhr_mgr *mgr, int audio_mask)
795 } else { 838 } else {
796 /* stop capture pipe */ 839 /* stop capture pipe */
797 pcxhr_set_pipe_cmd_params(&rmh, 1, audio - 840 pcxhr_set_pipe_cmd_params(&rmh, 1, audio -
798 PCXHR_PIPE_STATE_CAPTURE_OFFSET, 841 PCXHR_PIPE_STATE_CAPTURE_OFFSET,
799 0, 0); 842 0, 0);
800 } 843 }
801 err = pcxhr_send_msg(mgr, &rmh); 844 err = pcxhr_send_msg(mgr, &rmh);
802 if (err) { 845 if (err) {
803 snd_printk(KERN_ERR 846 snd_printk(KERN_ERR
804 "error pipe stop (CMD_STOP_PIPE) err=%x!\n", 847 "error pipe stop "
805 err); 848 "(CMD_STOP_PIPE) err=%x!\n", err);
806 return err; 849 return err;
807 } 850 }
808 } 851 }
@@ -822,15 +865,16 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
822 if (audio_mask & 1) { 865 if (audio_mask & 1) {
823 pcxhr_init_rmh(&rmh, CMD_CONF_PIPE); 866 pcxhr_init_rmh(&rmh, CMD_CONF_PIPE);
824 if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET) 867 if (audio < PCXHR_PIPE_STATE_CAPTURE_OFFSET)
825 pcxhr_set_pipe_cmd_params(&rmh, 0, 0, 0, 1 << audio); 868 pcxhr_set_pipe_cmd_params(&rmh, 0, 0, 0,
869 1 << audio);
826 else 870 else
827 pcxhr_set_pipe_cmd_params(&rmh, 1, 0, 0, 871 pcxhr_set_pipe_cmd_params(&rmh, 1, 0, 0,
828 1 << (audio - PCXHR_PIPE_STATE_CAPTURE_OFFSET)); 872 1 << (audio - PCXHR_PIPE_STATE_CAPTURE_OFFSET));
829 err = pcxhr_send_msg(mgr, &rmh); 873 err = pcxhr_send_msg(mgr, &rmh);
830 if (err) { 874 if (err) {
831 snd_printk(KERN_ERR 875 snd_printk(KERN_ERR
832 "error pipe start (CMD_CONF_PIPE) err=%x!\n", 876 "error pipe start "
833 err); 877 "(CMD_CONF_PIPE) err=%x!\n", err);
834 return err; 878 return err;
835 } 879 }
836 } 880 }
@@ -841,7 +885,9 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
841 pcxhr_init_rmh(&rmh, CMD_SEND_IRQA); 885 pcxhr_init_rmh(&rmh, CMD_SEND_IRQA);
842 err = pcxhr_send_msg(mgr, &rmh); 886 err = pcxhr_send_msg(mgr, &rmh);
843 if (err) { 887 if (err) {
844 snd_printk(KERN_ERR "error pipe start (CMD_SEND_IRQA) err=%x!\n", err ); 888 snd_printk(KERN_ERR
889 "error pipe start (CMD_SEND_IRQA) err=%x!\n",
890 err);
845 return err; 891 return err;
846 } 892 }
847 return 0; 893 return 0;
@@ -849,7 +895,8 @@ static int pcxhr_toggle_pipes(struct pcxhr_mgr *mgr, int audio_mask)
849 895
850 896
851 897
852int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_mask, int start) 898int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask,
899 int capture_mask, int start)
853{ 900{
854 int state, i, err; 901 int state, i, err;
855 int audio_mask; 902 int audio_mask;
@@ -858,21 +905,23 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
858 struct timeval my_tv1, my_tv2; 905 struct timeval my_tv1, my_tv2;
859 do_gettimeofday(&my_tv1); 906 do_gettimeofday(&my_tv1);
860#endif 907#endif
861 audio_mask = (playback_mask | (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET)); 908 audio_mask = (playback_mask |
909 (capture_mask << PCXHR_PIPE_STATE_CAPTURE_OFFSET));
862 /* current pipe state (playback + record) */ 910 /* current pipe state (playback + record) */
863 state = pcxhr_pipes_running(mgr); 911 state = pcxhr_pipes_running(mgr);
864 snd_printdd("pcxhr_set_pipe_state %s (mask %x current %x)\n", 912 snd_printdd("pcxhr_set_pipe_state %s (mask %x current %x)\n",
865 start ? "START" : "STOP", audio_mask, state); 913 start ? "START" : "STOP", audio_mask, state);
866 if (start) { 914 if (start) {
867 audio_mask &= ~state; /* start only pipes that are not yet started */ 915 /* start only pipes that are not yet started */
916 audio_mask &= ~state;
868 state = audio_mask; 917 state = audio_mask;
869 for (i = 0; i < MAX_WAIT_FOR_DSP; i++) { 918 for (i = 0; i < MAX_WAIT_FOR_DSP; i++) {
870 err = pcxhr_prepair_pipe_start(mgr, state, &state); 919 err = pcxhr_prepair_pipe_start(mgr, state, &state);
871 if (err) 920 if (err)
872 return err; 921 return err;
873 if (state == 0) 922 if (state == 0)
874 break; /* success, all pipes prepaired for start */ 923 break; /* success, all pipes prepaired */
875 mdelay(1); /* otherwise wait 1 millisecond and retry */ 924 mdelay(1); /* wait 1 millisecond and retry */
876 } 925 }
877 } else { 926 } else {
878 audio_mask &= state; /* stop only pipes that are started */ 927 audio_mask &= state; /* stop only pipes that are started */
@@ -891,7 +940,7 @@ int pcxhr_set_pipe_state(struct pcxhr_mgr *mgr, int playback_mask, int capture_m
891 if ((state & audio_mask) == (start ? audio_mask : 0)) 940 if ((state & audio_mask) == (start ? audio_mask : 0))
892 break; 941 break;
893 if (++i >= MAX_WAIT_FOR_DSP * 100) { 942 if (++i >= MAX_WAIT_FOR_DSP * 100) {
894 snd_printk(KERN_ERR "error pipe start/stop (ED_NO_RESPONSE_AT_IRQA)\n"); 943 snd_printk(KERN_ERR "error pipe start/stop\n");
895 return -EBUSY; 944 return -EBUSY;
896 } 945 }
897 udelay(10); /* wait 10 microseconds */ 946 udelay(10); /* wait 10 microseconds */
@@ -918,7 +967,8 @@ int pcxhr_write_io_num_reg_cont(struct pcxhr_mgr *mgr, unsigned int mask,
918 967
919 spin_lock_irqsave(&mgr->msg_lock, flags); 968 spin_lock_irqsave(&mgr->msg_lock, flags);
920 if ((mgr->io_num_reg_cont & mask) == value) { 969 if ((mgr->io_num_reg_cont & mask) == value) {
921 snd_printdd("IO_NUM_REG_CONT mask %x already is set to %x\n", mask, value); 970 snd_printdd("IO_NUM_REG_CONT mask %x already is set to %x\n",
971 mask, value);
922 if (changed) 972 if (changed)
923 *changed = 0; 973 *changed = 0;
924 spin_unlock_irqrestore(&mgr->msg_lock, flags); 974 spin_unlock_irqrestore(&mgr->msg_lock, flags);
@@ -971,7 +1021,8 @@ static int pcxhr_handle_async_err(struct pcxhr_mgr *mgr, u32 err,
971 err = ((err >> 12) & 0xfff); 1021 err = ((err >> 12) & 0xfff);
972 if (!err) 1022 if (!err)
973 return 0; 1023 return 0;
974 snd_printdd("CMD_ASYNC : Error %s %s Pipe %d err=%x\n", err_src_name[err_src], 1024 snd_printdd("CMD_ASYNC : Error %s %s Pipe %d err=%x\n",
1025 err_src_name[err_src],
975 is_capture ? "Record" : "Play", pipe, err); 1026 is_capture ? "Record" : "Play", pipe, err);
976 if (err == 0xe01) 1027 if (err == 0xe01)
977 mgr->async_err_stream_xrun++; 1028 mgr->async_err_stream_xrun++;
@@ -996,6 +1047,13 @@ void pcxhr_msg_tasklet(unsigned long arg)
996 snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occured\n"); 1047 snd_printdd("TASKLET : PCXHR_IRQ_TIME_CODE event occured\n");
997 if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY) 1048 if (mgr->src_it_dsp & PCXHR_IRQ_NOTIFY)
998 snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occured\n"); 1049 snd_printdd("TASKLET : PCXHR_IRQ_NOTIFY event occured\n");
1050 if (mgr->src_it_dsp & (PCXHR_IRQ_FREQ_CHANGE | PCXHR_IRQ_TIME_CODE)) {
1051 /* clear events FREQ_CHANGE and TIME_CODE */
1052 pcxhr_init_rmh(prmh, CMD_TEST_IT);
1053 err = pcxhr_send_msg(mgr, prmh);
1054 snd_printdd("CMD_TEST_IT : err=%x, stat=%x\n",
1055 err, prmh->stat[0]);
1056 }
999 if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) { 1057 if (mgr->src_it_dsp & PCXHR_IRQ_ASYNC) {
1000 snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occured\n"); 1058 snd_printdd("TASKLET : PCXHR_IRQ_ASYNC event occured\n");
1001 1059
@@ -1005,18 +1063,22 @@ void pcxhr_msg_tasklet(unsigned long arg)
1005 prmh->stat_len = PCXHR_SIZE_MAX_LONG_STATUS; 1063 prmh->stat_len = PCXHR_SIZE_MAX_LONG_STATUS;
1006 err = pcxhr_send_msg(mgr, prmh); 1064 err = pcxhr_send_msg(mgr, prmh);
1007 if (err) 1065 if (err)
1008 snd_printk(KERN_ERR "ERROR pcxhr_msg_tasklet=%x;\n", err); 1066 snd_printk(KERN_ERR "ERROR pcxhr_msg_tasklet=%x;\n",
1067 err);
1009 i = 1; 1068 i = 1;
1010 while (i < prmh->stat_len) { 1069 while (i < prmh->stat_len) {
1011 int nb_audio = (prmh->stat[i] >> FIELD_SIZE) & MASK_FIRST_FIELD; 1070 int nb_audio = ((prmh->stat[i] >> FIELD_SIZE) &
1012 int nb_stream = (prmh->stat[i] >> (2*FIELD_SIZE)) & MASK_FIRST_FIELD; 1071 MASK_FIRST_FIELD);
1072 int nb_stream = ((prmh->stat[i] >> (2*FIELD_SIZE)) &
1073 MASK_FIRST_FIELD);
1013 int pipe = prmh->stat[i] & MASK_FIRST_FIELD; 1074 int pipe = prmh->stat[i] & MASK_FIRST_FIELD;
1014 int is_capture = prmh->stat[i] & 0x400000; 1075 int is_capture = prmh->stat[i] & 0x400000;
1015 u32 err2; 1076 u32 err2;
1016 1077
1017 if (prmh->stat[i] & 0x800000) { /* if BIT_END */ 1078 if (prmh->stat[i] & 0x800000) { /* if BIT_END */
1018 snd_printdd("TASKLET : End%sPipe %d\n", 1079 snd_printdd("TASKLET : End%sPipe %d\n",
1019 is_capture ? "Record" : "Play", pipe); 1080 is_capture ? "Record" : "Play",
1081 pipe);
1020 } 1082 }
1021 i++; 1083 i++;
1022 err2 = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1]; 1084 err2 = prmh->stat[i] ? prmh->stat[i] : prmh->stat[i+1];
@@ -1062,7 +1124,7 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
1062 pcxhr_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT); 1124 pcxhr_init_rmh(&rmh, CMD_STREAM_SAMPLE_COUNT);
1063 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture, 1125 pcxhr_set_pipe_cmd_params(&rmh, stream->pipe->is_capture,
1064 stream->pipe->first_audio, 0, stream_mask); 1126 stream->pipe->first_audio, 0, stream_mask);
1065 /* rmh.stat_len = 2; */ /* 2 resp data for each stream of the pipe */ 1127 /* rmh.stat_len = 2; */ /* 2 resp data for each stream of the pipe */
1066 1128
1067 err = pcxhr_send_msg(mgr, &rmh); 1129 err = pcxhr_send_msg(mgr, &rmh);
1068 if (err) 1130 if (err)
@@ -1072,18 +1134,21 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
1072 hw_sample_count += (u_int64_t)rmh.stat[1]; 1134 hw_sample_count += (u_int64_t)rmh.stat[1];
1073 1135
1074 snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n", 1136 snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n",
1075 stream->pipe->is_capture ? 'C':'P', stream->substream->number, 1137 stream->pipe->is_capture ? 'C' : 'P',
1138 stream->substream->number,
1076 (long unsigned int)hw_sample_count, 1139 (long unsigned int)hw_sample_count,
1077 (long unsigned int)(stream->timer_abs_periods + 1140 (long unsigned int)(stream->timer_abs_periods +
1078 stream->timer_period_frag + PCXHR_GRANULARITY)); 1141 stream->timer_period_frag +
1079 1142 mgr->granularity));
1080 return hw_sample_count; 1143 return hw_sample_count;
1081} 1144}
1082 1145
1083static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr, 1146static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1084 struct pcxhr_stream *stream, int samples_to_add) 1147 struct pcxhr_stream *stream,
1148 int samples_to_add)
1085{ 1149{
1086 if (stream->substream && (stream->status == PCXHR_STREAM_STATUS_RUNNING)) { 1150 if (stream->substream &&
1151 (stream->status == PCXHR_STREAM_STATUS_RUNNING)) {
1087 u_int64_t new_sample_count; 1152 u_int64_t new_sample_count;
1088 int elapsed = 0; 1153 int elapsed = 0;
1089 int hardware_read = 0; 1154 int hardware_read = 0;
@@ -1092,20 +1157,22 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1092 if (samples_to_add < 0) { 1157 if (samples_to_add < 0) {
1093 stream->timer_is_synced = 0; 1158 stream->timer_is_synced = 0;
1094 /* add default if no hardware_read possible */ 1159 /* add default if no hardware_read possible */
1095 samples_to_add = PCXHR_GRANULARITY; 1160 samples_to_add = mgr->granularity;
1096 } 1161 }
1097 1162
1098 if (!stream->timer_is_synced) { 1163 if (!stream->timer_is_synced) {
1099 if (stream->timer_abs_periods != 0 || 1164 if ((stream->timer_abs_periods != 0) ||
1100 stream->timer_period_frag + PCXHR_GRANULARITY >= 1165 ((stream->timer_period_frag + samples_to_add) >=
1101 runtime->period_size) { 1166 runtime->period_size)) {
1102 new_sample_count = pcxhr_stream_read_position(mgr, stream); 1167 new_sample_count =
1168 pcxhr_stream_read_position(mgr, stream);
1103 hardware_read = 1; 1169 hardware_read = 1;
1104 if (new_sample_count >= PCXHR_GRANULARITY_MIN) { 1170 if (new_sample_count >= mgr->granularity) {
1105 /* sub security offset because of jitter and 1171 /* sub security offset because of
1106 * finer granularity of dsp time (MBOX4) 1172 * jitter and finer granularity of
1173 * dsp time (MBOX4)
1107 */ 1174 */
1108 new_sample_count -= PCXHR_GRANULARITY_MIN; 1175 new_sample_count -= mgr->granularity;
1109 stream->timer_is_synced = 1; 1176 stream->timer_is_synced = 1;
1110 } 1177 }
1111 } 1178 }
@@ -1128,12 +1195,15 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1128 stream->timer_buf_periods = 0; 1195 stream->timer_buf_periods = 0;
1129 stream->timer_abs_periods = new_elapse_pos; 1196 stream->timer_abs_periods = new_elapse_pos;
1130 } 1197 }
1131 if (new_sample_count >= stream->timer_abs_periods) 1198 if (new_sample_count >= stream->timer_abs_periods) {
1132 stream->timer_period_frag = (u_int32_t)(new_sample_count - 1199 stream->timer_period_frag =
1133 stream->timer_abs_periods); 1200 (u_int32_t)(new_sample_count -
1134 else 1201 stream->timer_abs_periods);
1135 snd_printk(KERN_ERR "ERROR new_sample_count too small ??? %lx\n", 1202 } else {
1203 snd_printk(KERN_ERR
1204 "ERROR new_sample_count too small ??? %ld\n",
1136 (long unsigned int)new_sample_count); 1205 (long unsigned int)new_sample_count);
1206 }
1137 1207
1138 if (elapsed) { 1208 if (elapsed) {
1139 spin_unlock(&mgr->lock); 1209 spin_unlock(&mgr->lock);
@@ -1143,7 +1213,6 @@ static void pcxhr_update_timer_pos(struct pcxhr_mgr *mgr,
1143 } 1213 }
1144} 1214}
1145 1215
1146
1147irqreturn_t pcxhr_interrupt(int irq, void *dev_id) 1216irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1148{ 1217{
1149 struct pcxhr_mgr *mgr = dev_id; 1218 struct pcxhr_mgr *mgr = dev_id;
@@ -1156,7 +1225,8 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1156 reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS); 1225 reg = PCXHR_INPL(mgr, PCXHR_PLX_IRQCS);
1157 if (! (reg & PCXHR_IRQCS_ACTIVE_PCIDB)) { 1226 if (! (reg & PCXHR_IRQCS_ACTIVE_PCIDB)) {
1158 spin_unlock(&mgr->lock); 1227 spin_unlock(&mgr->lock);
1159 return IRQ_NONE; /* this device did not cause the interrupt */ 1228 /* this device did not cause the interrupt */
1229 return IRQ_NONE;
1160 } 1230 }
1161 1231
1162 /* clear interrupt */ 1232 /* clear interrupt */
@@ -1167,10 +1237,12 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1167 if (reg & PCXHR_IRQ_TIMER) { 1237 if (reg & PCXHR_IRQ_TIMER) {
1168 int timer_toggle = reg & PCXHR_IRQ_TIMER; 1238 int timer_toggle = reg & PCXHR_IRQ_TIMER;
1169 /* is a 24 bit counter */ 1239 /* is a 24 bit counter */
1170 int dsp_time_new = PCXHR_INPL(mgr, PCXHR_PLX_MBOX4) & PCXHR_DSP_TIME_MASK; 1240 int dsp_time_new =
1241 PCXHR_INPL(mgr, PCXHR_PLX_MBOX4) & PCXHR_DSP_TIME_MASK;
1171 int dsp_time_diff = dsp_time_new - mgr->dsp_time_last; 1242 int dsp_time_diff = dsp_time_new - mgr->dsp_time_last;
1172 1243
1173 if (dsp_time_diff < 0 && mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID) { 1244 if ((dsp_time_diff < 0) &&
1245 (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) {
1174 snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " 1246 snd_printdd("ERROR DSP TIME old(%d) new(%d) -> "
1175 "resynchronize all streams\n", 1247 "resynchronize all streams\n",
1176 mgr->dsp_time_last, dsp_time_new); 1248 mgr->dsp_time_last, dsp_time_new);
@@ -1178,42 +1250,51 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1178 } 1250 }
1179#ifdef CONFIG_SND_DEBUG_VERBOSE 1251#ifdef CONFIG_SND_DEBUG_VERBOSE
1180 if (dsp_time_diff == 0) 1252 if (dsp_time_diff == 0)
1181 snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n", dsp_time_new); 1253 snd_printdd("ERROR DSP TIME NO DIFF time(%d)\n",
1182 else if (dsp_time_diff >= (2*PCXHR_GRANULARITY)) 1254 dsp_time_new);
1255 else if (dsp_time_diff >= (2*mgr->granularity))
1183 snd_printdd("ERROR DSP TIME TOO BIG old(%d) add(%d)\n", 1256 snd_printdd("ERROR DSP TIME TOO BIG old(%d) add(%d)\n",
1184 mgr->dsp_time_last, dsp_time_new - mgr->dsp_time_last); 1257 mgr->dsp_time_last,
1258 dsp_time_new - mgr->dsp_time_last);
1259 else if (dsp_time_diff % mgr->granularity)
1260 snd_printdd("ERROR DSP TIME increased by %d\n",
1261 dsp_time_diff);
1185#endif 1262#endif
1186 mgr->dsp_time_last = dsp_time_new; 1263 mgr->dsp_time_last = dsp_time_new;
1187 1264
1188 if (timer_toggle == mgr->timer_toggle) 1265 if (timer_toggle == mgr->timer_toggle) {
1189 snd_printdd("ERROR TIMER TOGGLE\n"); 1266 snd_printdd("ERROR TIMER TOGGLE\n");
1267 mgr->dsp_time_err++;
1268 }
1190 mgr->timer_toggle = timer_toggle; 1269 mgr->timer_toggle = timer_toggle;
1191 1270
1192 reg &= ~PCXHR_IRQ_TIMER; 1271 reg &= ~PCXHR_IRQ_TIMER;
1193 for (i = 0; i < mgr->num_cards; i++) { 1272 for (i = 0; i < mgr->num_cards; i++) {
1194 chip = mgr->chip[i]; 1273 chip = mgr->chip[i];
1195 for (j = 0; j < chip->nb_streams_capt; j++) 1274 for (j = 0; j < chip->nb_streams_capt; j++)
1196 pcxhr_update_timer_pos(mgr, &chip->capture_stream[j], 1275 pcxhr_update_timer_pos(mgr,
1197 dsp_time_diff); 1276 &chip->capture_stream[j],
1277 dsp_time_diff);
1198 } 1278 }
1199 for (i = 0; i < mgr->num_cards; i++) { 1279 for (i = 0; i < mgr->num_cards; i++) {
1200 chip = mgr->chip[i]; 1280 chip = mgr->chip[i];
1201 for (j = 0; j < chip->nb_streams_play; j++) 1281 for (j = 0; j < chip->nb_streams_play; j++)
1202 pcxhr_update_timer_pos(mgr, &chip->playback_stream[j], 1282 pcxhr_update_timer_pos(mgr,
1203 dsp_time_diff); 1283 &chip->playback_stream[j],
1284 dsp_time_diff);
1204 } 1285 }
1205 } 1286 }
1206 /* other irq's handled in the tasklet */ 1287 /* other irq's handled in the tasklet */
1207 if (reg & PCXHR_IRQ_MASK) { 1288 if (reg & PCXHR_IRQ_MASK) {
1208 1289 if (reg & PCXHR_IRQ_ASYNC) {
1209 /* as we didn't request any notifications, some kind of xrun error 1290 /* as we didn't request any async notifications,
1210 * will probably occured 1291 * some kind of xrun error will probably occured
1211 */ 1292 */
1212 /* better resynchronize all streams next interrupt : */ 1293 /* better resynchronize all streams next interrupt : */
1213 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID; 1294 mgr->dsp_time_last = PCXHR_DSP_TIME_INVALID;
1214 1295 }
1215 mgr->src_it_dsp = reg; 1296 mgr->src_it_dsp = reg;
1216 tasklet_hi_schedule(&mgr->msg_taskq); 1297 tasklet_schedule(&mgr->msg_taskq);
1217 } 1298 }
1218#ifdef CONFIG_SND_DEBUG_VERBOSE 1299#ifdef CONFIG_SND_DEBUG_VERBOSE
1219 if (reg & PCXHR_FATAL_DSP_ERR) 1300 if (reg & PCXHR_FATAL_DSP_ERR)
diff --git a/sound/pci/pcxhr/pcxhr_core.h b/sound/pci/pcxhr/pcxhr_core.h
index d9a4ab609875..bbbd66d13a64 100644
--- a/sound/pci/pcxhr/pcxhr_core.h
+++ b/sound/pci/pcxhr/pcxhr_core.h
@@ -65,7 +65,7 @@ enum {
65 CMD_RESYNC_AUDIO_INPUTS, /* cmd_len = 1 stat_len = 0 */ 65 CMD_RESYNC_AUDIO_INPUTS, /* cmd_len = 1 stat_len = 0 */
66 CMD_GET_DSP_RESOURCES, /* cmd_len = 1 stat_len = 4 */ 66 CMD_GET_DSP_RESOURCES, /* cmd_len = 1 stat_len = 4 */
67 CMD_SET_TIMER_INTERRUPT, /* cmd_len = 1 stat_len = 0 */ 67 CMD_SET_TIMER_INTERRUPT, /* cmd_len = 1 stat_len = 0 */
68 CMD_RES_PIPE, /* cmd_len = 2 stat_len = 0 */ 68 CMD_RES_PIPE, /* cmd_len >=2 stat_len = 0 */
69 CMD_FREE_PIPE, /* cmd_len = 1 stat_len = 0 */ 69 CMD_FREE_PIPE, /* cmd_len = 1 stat_len = 0 */
70 CMD_CONF_PIPE, /* cmd_len = 2 stat_len = 0 */ 70 CMD_CONF_PIPE, /* cmd_len = 2 stat_len = 0 */
71 CMD_STOP_PIPE, /* cmd_len = 1 stat_len = 0 */ 71 CMD_STOP_PIPE, /* cmd_len = 1 stat_len = 0 */
@@ -96,6 +96,8 @@ void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd);
96void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh* rmh, int capture, unsigned int param1, 96void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh* rmh, int capture, unsigned int param1,
97 unsigned int param2, unsigned int param3); 97 unsigned int param2, unsigned int param3);
98 98
99#define DSP_EXT_CMD_SET(x) (x->dsp_version > 0x012800)
100
99/* 101/*
100 send the rmh 102 send the rmh
101 */ 103 */
@@ -110,6 +112,7 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh);
110#define IO_NUM_REG_STATUS 5 112#define IO_NUM_REG_STATUS 5
111#define IO_NUM_REG_CUER 10 113#define IO_NUM_REG_CUER 10
112#define IO_NUM_UER_CHIP_REG 11 114#define IO_NUM_UER_CHIP_REG 11
115#define IO_NUM_REG_CONFIG_SRC 12
113#define IO_NUM_REG_OUT_ANA_LEVEL 20 116#define IO_NUM_REG_OUT_ANA_LEVEL 20
114#define IO_NUM_REG_IN_ANA_LEVEL 21 117#define IO_NUM_REG_IN_ANA_LEVEL 21
115 118
diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c
index 96640d9c227d..592743a298b0 100644
--- a/sound/pci/pcxhr/pcxhr_hwdep.c
+++ b/sound/pci/pcxhr/pcxhr_hwdep.c
@@ -31,6 +31,7 @@
31#include "pcxhr_mixer.h" 31#include "pcxhr_mixer.h"
32#include "pcxhr_hwdep.h" 32#include "pcxhr_hwdep.h"
33#include "pcxhr_core.h" 33#include "pcxhr_core.h"
34#include "pcxhr_mix22.h"
34 35
35 36
36#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE) 37#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
@@ -40,10 +41,10 @@
40#endif 41#endif
41 42
42 43
44static int pcxhr_sub_init(struct pcxhr_mgr *mgr);
43/* 45/*
44 * get basic information and init pcxhr card 46 * get basic information and init pcxhr card
45 */ 47 */
46
47static int pcxhr_init_board(struct pcxhr_mgr *mgr) 48static int pcxhr_init_board(struct pcxhr_mgr *mgr)
48{ 49{
49 int err; 50 int err;
@@ -68,7 +69,7 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
68 if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2) 69 if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2)
69 return -EINVAL; 70 return -EINVAL;
70 /* test 8 or 2 phys in */ 71 /* test 8 or 2 phys in */
71 if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) != 72 if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) <
72 mgr->capture_chips * 2) 73 mgr->capture_chips * 2)
73 return -EINVAL; 74 return -EINVAL;
74 /* test max nb substream per board */ 75 /* test max nb substream per board */
@@ -77,20 +78,34 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
77 /* test max nb substream per pipe */ 78 /* test max nb substream per pipe */
78 if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS) 79 if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS)
79 return -EINVAL; 80 return -EINVAL;
81 snd_printdd("supported formats : playback=%x capture=%x\n",
82 rmh.stat[2], rmh.stat[3]);
80 83
81 pcxhr_init_rmh(&rmh, CMD_VERSION); 84 pcxhr_init_rmh(&rmh, CMD_VERSION);
82 /* firmware num for DSP */ 85 /* firmware num for DSP */
83 rmh.cmd[0] |= mgr->firmware_num; 86 rmh.cmd[0] |= mgr->firmware_num;
84 /* transfer granularity in samples (should be multiple of 48) */ 87 /* transfer granularity in samples (should be multiple of 48) */
85 rmh.cmd[1] = (1<<23) + PCXHR_GRANULARITY; 88 rmh.cmd[1] = (1<<23) + mgr->granularity;
86 rmh.cmd_len = 2; 89 rmh.cmd_len = 2;
87 err = pcxhr_send_msg(mgr, &rmh); 90 err = pcxhr_send_msg(mgr, &rmh);
88 if (err) 91 if (err)
89 return err; 92 return err;
90 snd_printdd("PCXHR DSP version is %d.%d.%d\n", 93 snd_printdd("PCXHR DSP version is %d.%d.%d\n", (rmh.stat[0]>>16)&0xff,
91 (rmh.stat[0]>>16)&0xff, (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff); 94 (rmh.stat[0]>>8)&0xff, rmh.stat[0]&0xff);
92 mgr->dsp_version = rmh.stat[0]; 95 mgr->dsp_version = rmh.stat[0];
93 96
97 if (mgr->is_hr_stereo)
98 err = hr222_sub_init(mgr);
99 else
100 err = pcxhr_sub_init(mgr);
101 return err;
102}
103
104static int pcxhr_sub_init(struct pcxhr_mgr *mgr)
105{
106 int err;
107 struct pcxhr_rmh rmh;
108
94 /* get options */ 109 /* get options */
95 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); 110 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
96 rmh.cmd[0] |= IO_NUM_REG_STATUS; 111 rmh.cmd[0] |= IO_NUM_REG_STATUS;
@@ -100,20 +115,22 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr)
100 if (err) 115 if (err)
101 return err; 116 return err;
102 117
103 if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) == REG_STATUS_OPT_ANALOG_BOARD) 118 if ((rmh.stat[1] & REG_STATUS_OPT_DAUGHTER_MASK) ==
104 mgr->board_has_analog = 1; /* analog addon board available */ 119 REG_STATUS_OPT_ANALOG_BOARD)
105 else 120 mgr->board_has_analog = 1; /* analog addon board found */
106 /* analog addon board not available -> no support for instance */
107 return -EINVAL;
108 121
109 /* unmute inputs */ 122 /* unmute inputs */
110 err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, 123 err = pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
111 REG_CONT_UNMUTE_INPUTS, NULL); 124 REG_CONT_UNMUTE_INPUTS, NULL);
112 if (err) 125 if (err)
113 return err; 126 return err;
114 /* unmute outputs */ 127 /* unmute outputs (a write to IO_NUM_REG_MUTE_OUT mutes!) */
115 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); /* a write to IO_NUM_REG_MUTE_OUT mutes! */ 128 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
116 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 129 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
130 if (DSP_EXT_CMD_SET(mgr)) {
131 rmh.cmd[1] = 1; /* unmute digital plugs */
132 rmh.cmd_len = 2;
133 }
117 err = pcxhr_send_msg(mgr, &rmh); 134 err = pcxhr_send_msg(mgr, &rmh);
118 return err; 135 return err;
119} 136}
@@ -124,19 +141,25 @@ void pcxhr_reset_board(struct pcxhr_mgr *mgr)
124 141
125 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) { 142 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) {
126 /* mute outputs */ 143 /* mute outputs */
144 if (!mgr->is_hr_stereo) {
127 /* a read to IO_NUM_REG_MUTE_OUT register unmutes! */ 145 /* a read to IO_NUM_REG_MUTE_OUT register unmutes! */
128 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); 146 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
129 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT; 147 rmh.cmd[0] |= IO_NUM_REG_MUTE_OUT;
130 pcxhr_send_msg(mgr, &rmh); 148 pcxhr_send_msg(mgr, &rmh);
131 /* mute inputs */ 149 /* mute inputs */
132 pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS, 0, NULL); 150 pcxhr_write_io_num_reg_cont(mgr, REG_CONT_UNMUTE_INPUTS,
151 0, NULL);
152 }
153 /* stereo cards mute with reset of dsp */
133 } 154 }
134 /* reset pcxhr dsp */ 155 /* reset pcxhr dsp */
135 if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX)) 156 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_EPRM_INDEX))
136 pcxhr_reset_dsp(mgr); 157 pcxhr_reset_dsp(mgr);
137 /* reset second xilinx */ 158 /* reset second xilinx */
138 if (mgr->dsp_loaded & ( 1 << PCXHR_FIRMWARE_XLX_COM_INDEX)) 159 if (mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_XLX_COM_INDEX)) {
139 pcxhr_reset_xilinx_com(mgr); 160 pcxhr_reset_xilinx_com(mgr);
161 mgr->dsp_loaded = 1;
162 }
140 return; 163 return;
141} 164}
142 165
@@ -144,8 +167,9 @@ void pcxhr_reset_board(struct pcxhr_mgr *mgr)
144/* 167/*
145 * allocate a playback/capture pipe (pcmp0/pcmc0) 168 * allocate a playback/capture pipe (pcmp0/pcmc0)
146 */ 169 */
147static int pcxhr_dsp_allocate_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe, 170static int pcxhr_dsp_allocate_pipe(struct pcxhr_mgr *mgr,
148 int is_capture, int pin) 171 struct pcxhr_pipe *pipe,
172 int is_capture, int pin)
149{ 173{
150 int stream_count, audio_count; 174 int stream_count, audio_count;
151 int err; 175 int err;
@@ -161,15 +185,23 @@ static int pcxhr_dsp_allocate_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pi
161 stream_count = PCXHR_PLAYBACK_STREAMS; 185 stream_count = PCXHR_PLAYBACK_STREAMS;
162 audio_count = 2; /* always stereo */ 186 audio_count = 2; /* always stereo */
163 } 187 }
164 snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n", pin, is_capture ? 'c' : 'p'); 188 snd_printdd("snd_add_ref_pipe pin(%d) pcm%c0\n",
189 pin, is_capture ? 'c' : 'p');
165 pipe->is_capture = is_capture; 190 pipe->is_capture = is_capture;
166 pipe->first_audio = pin; 191 pipe->first_audio = pin;
167 /* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */ 192 /* define pipe (P_PCM_ONLY_MASK (0x020000) is not necessary) */
168 pcxhr_init_rmh(&rmh, CMD_RES_PIPE); 193 pcxhr_init_rmh(&rmh, CMD_RES_PIPE);
169 pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin, audio_count, stream_count); 194 pcxhr_set_pipe_cmd_params(&rmh, is_capture, pin,
195 audio_count, stream_count);
196 rmh.cmd[1] |= 0x020000; /* add P_PCM_ONLY_MASK */
197 if (DSP_EXT_CMD_SET(mgr)) {
198 /* add channel mask to command */
199 rmh.cmd[rmh.cmd_len++] = (audio_count == 1) ? 0x01 : 0x03;
200 }
170 err = pcxhr_send_msg(mgr, &rmh); 201 err = pcxhr_send_msg(mgr, &rmh);
171 if (err < 0) { 202 if (err < 0) {
172 snd_printk(KERN_ERR "error pipe allocation (CMD_RES_PIPE) err=%x!\n", err ); 203 snd_printk(KERN_ERR "error pipe allocation "
204 "(CMD_RES_PIPE) err=%x!\n", err);
173 return err; 205 return err;
174 } 206 }
175 pipe->status = PCXHR_PIPE_DEFINED; 207 pipe->status = PCXHR_PIPE_DEFINED;
@@ -199,10 +231,12 @@ static int pcxhr_dsp_free_pipe( struct pcxhr_mgr *mgr, struct pcxhr_pipe *pipe)
199 snd_printk(KERN_ERR "error stopping pipe!\n"); 231 snd_printk(KERN_ERR "error stopping pipe!\n");
200 /* release the pipe */ 232 /* release the pipe */
201 pcxhr_init_rmh(&rmh, CMD_FREE_PIPE); 233 pcxhr_init_rmh(&rmh, CMD_FREE_PIPE);
202 pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio, 0, 0); 234 pcxhr_set_pipe_cmd_params(&rmh, pipe->is_capture, pipe->first_audio,
235 0, 0);
203 err = pcxhr_send_msg(mgr, &rmh); 236 err = pcxhr_send_msg(mgr, &rmh);
204 if (err < 0) 237 if (err < 0)
205 snd_printk(KERN_ERR "error pipe release (CMD_FREE_PIPE) err(%x)\n", err); 238 snd_printk(KERN_ERR "error pipe release "
239 "(CMD_FREE_PIPE) err(%x)\n", err);
206 pipe->status = PCXHR_PIPE_UNDEFINED; 240 pipe->status = PCXHR_PIPE_UNDEFINED;
207 return err; 241 return err;
208} 242}
@@ -248,15 +282,16 @@ static int pcxhr_start_pipes(struct pcxhr_mgr *mgr)
248 for (i = 0; i < mgr->num_cards; i++) { 282 for (i = 0; i < mgr->num_cards; i++) {
249 chip = mgr->chip[i]; 283 chip = mgr->chip[i];
250 if (chip->nb_streams_play) 284 if (chip->nb_streams_play)
251 playback_mask |= (1 << chip->playback_pipe.first_audio); 285 playback_mask |= 1 << chip->playback_pipe.first_audio;
252 for (j = 0; j < chip->nb_streams_capt; j++) 286 for (j = 0; j < chip->nb_streams_capt; j++)
253 capture_mask |= (1 << chip->capture_pipe[j].first_audio); 287 capture_mask |= 1 << chip->capture_pipe[j].first_audio;
254 } 288 }
255 return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1); 289 return pcxhr_set_pipe_state(mgr, playback_mask, capture_mask, 1);
256} 290}
257 291
258 292
259static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, const struct firmware *dsp) 293static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index,
294 const struct firmware *dsp)
260{ 295{
261 int err, card_index; 296 int err, card_index;
262 297
@@ -330,22 +365,33 @@ static int pcxhr_dsp_load(struct pcxhr_mgr *mgr, int index, const struct firmwar
330 365
331int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) 366int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
332{ 367{
333 static char *fw_files[5] = { 368 static char *fw_files[][5] = {
334 "xi_1_882.dat", 369 [0] = { "xlxint.dat", "xlxc882hr.dat",
335 "xc_1_882.dat", 370 "dspe882.e56", "dspb882hr.b56", "dspd882.d56" },
336 "e321_512.e56", 371 [1] = { "xlxint.dat", "xlxc882e.dat",
337 "b321_512.b56", 372 "dspe882.e56", "dspb882e.b56", "dspd882.d56" },
338 "d321_512.d56" 373 [2] = { "xlxint.dat", "xlxc1222hr.dat",
374 "dspe882.e56", "dspb1222hr.b56", "dspd1222.d56" },
375 [3] = { "xlxint.dat", "xlxc1222e.dat",
376 "dspe882.e56", "dspb1222e.b56", "dspd1222.d56" },
377 [4] = { NULL, "xlxc222.dat",
378 "dspe924.e56", "dspb924.b56", "dspd222.d56" },
379 [5] = { NULL, "xlxc924.dat",
380 "dspe924.e56", "dspb924.b56", "dspd222.d56" },
339 }; 381 };
340 char path[32]; 382 char path[32];
341 383
342 const struct firmware *fw_entry; 384 const struct firmware *fw_entry;
343 int i, err; 385 int i, err;
386 int fw_set = mgr->fw_file_set;
344 387
345 for (i = 0; i < ARRAY_SIZE(fw_files); i++) { 388 for (i = 0; i < 5; i++) {
346 sprintf(path, "pcxhr/%s", fw_files[i]); 389 if (!fw_files[fw_set][i])
390 continue;
391 sprintf(path, "pcxhr/%s", fw_files[fw_set][i]);
347 if (request_firmware(&fw_entry, path, &mgr->pci->dev)) { 392 if (request_firmware(&fw_entry, path, &mgr->pci->dev)) {
348 snd_printk(KERN_ERR "pcxhr: can't load firmware %s\n", path); 393 snd_printk(KERN_ERR "pcxhr: can't load firmware %s\n",
394 path);
349 return -ENOENT; 395 return -ENOENT;
350 } 396 }
351 /* fake hwdep dsp record */ 397 /* fake hwdep dsp record */
@@ -358,11 +404,26 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
358 return 0; 404 return 0;
359} 405}
360 406
361MODULE_FIRMWARE("pcxhr/xi_1_882.dat"); 407MODULE_FIRMWARE("pcxhr/xlxint.dat");
362MODULE_FIRMWARE("pcxhr/xc_1_882.dat"); 408MODULE_FIRMWARE("pcxhr/xlxc882hr.dat");
363MODULE_FIRMWARE("pcxhr/e321_512.e56"); 409MODULE_FIRMWARE("pcxhr/xlxc882e.dat");
364MODULE_FIRMWARE("pcxhr/b321_512.b56"); 410MODULE_FIRMWARE("pcxhr/dspe882.e56");
365MODULE_FIRMWARE("pcxhr/d321_512.d56"); 411MODULE_FIRMWARE("pcxhr/dspb882hr.b56");
412MODULE_FIRMWARE("pcxhr/dspb882e.b56");
413MODULE_FIRMWARE("pcxhr/dspd882.d56");
414
415MODULE_FIRMWARE("pcxhr/xlxc1222hr.dat");
416MODULE_FIRMWARE("pcxhr/xlxc1222e.dat");
417MODULE_FIRMWARE("pcxhr/dspb1222hr.b56");
418MODULE_FIRMWARE("pcxhr/dspb1222e.b56");
419MODULE_FIRMWARE("pcxhr/dspd1222.d56");
420
421MODULE_FIRMWARE("pcxhr/xlxc222.dat");
422MODULE_FIRMWARE("pcxhr/xlxc924.dat");
423MODULE_FIRMWARE("pcxhr/dspe924.e56");
424MODULE_FIRMWARE("pcxhr/dspb924.b56");
425MODULE_FIRMWARE("pcxhr/dspd222.d56");
426
366 427
367#else /* old style firmware loading */ 428#else /* old style firmware loading */
368 429
@@ -373,7 +434,8 @@ MODULE_FIRMWARE("pcxhr/d321_512.d56");
373static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw, 434static int pcxhr_hwdep_dsp_status(struct snd_hwdep *hw,
374 struct snd_hwdep_dsp_status *info) 435 struct snd_hwdep_dsp_status *info)
375{ 436{
376 strcpy(info->id, "pcxhr"); 437 struct pcxhr_mgr *mgr = hw->private_data;
438 sprintf(info->id, "pcxhr%d", mgr->fw_file_set);
377 info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX; 439 info->num_dsps = PCXHR_FIRMWARE_FILES_MAX_INDEX;
378 440
379 if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX)) 441 if (hw->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))
@@ -393,8 +455,8 @@ static int pcxhr_hwdep_dsp_load(struct snd_hwdep *hw,
393 fw.size = dsp->length; 455 fw.size = dsp->length;
394 fw.data = vmalloc(fw.size); 456 fw.data = vmalloc(fw.size);
395 if (! fw.data) { 457 if (! fw.data) {
396 snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image (%lu bytes)\n", 458 snd_printk(KERN_ERR "pcxhr: cannot allocate dsp image "
397 (unsigned long)fw.size); 459 "(%lu bytes)\n", (unsigned long)fw.size);
398 return -ENOMEM; 460 return -ENOMEM;
399 } 461 }
400 if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) { 462 if (copy_from_user((void *)fw.data, dsp->image, dsp->length)) {
@@ -424,8 +486,11 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
424 int err; 486 int err;
425 struct snd_hwdep *hw; 487 struct snd_hwdep *hw;
426 488
427 /* only create hwdep interface for first cardX (see "index" module parameter)*/ 489 /* only create hwdep interface for first cardX
428 if ((err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw)) < 0) 490 * (see "index" module parameter)
491 */
492 err = snd_hwdep_new(mgr->chip[0]->card, PCXHR_HWDEP_ID, 0, &hw);
493 if (err < 0)
429 return err; 494 return err;
430 495
431 hw->iface = SNDRV_HWDEP_IFACE_PCXHR; 496 hw->iface = SNDRV_HWDEP_IFACE_PCXHR;
@@ -435,10 +500,13 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr)
435 hw->ops.dsp_status = pcxhr_hwdep_dsp_status; 500 hw->ops.dsp_status = pcxhr_hwdep_dsp_status;
436 hw->ops.dsp_load = pcxhr_hwdep_dsp_load; 501 hw->ops.dsp_load = pcxhr_hwdep_dsp_load;
437 hw->exclusive = 1; 502 hw->exclusive = 1;
503 /* stereo cards don't need fw_file_0 -> dsp_loaded = 1 */
504 hw->dsp_loaded = mgr->is_hr_stereo ? 1 : 0;
438 mgr->dsp_loaded = 0; 505 mgr->dsp_loaded = 0;
439 sprintf(hw->name, PCXHR_HWDEP_ID); 506 sprintf(hw->name, PCXHR_HWDEP_ID);
440 507
441 if ((err = snd_card_register(mgr->chip[0]->card)) < 0) 508 err = snd_card_register(mgr->chip[0]->card);
509 if (err < 0)
442 return err; 510 return err;
443 return 0; 511 return 0;
444} 512}
diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c
new file mode 100644
index 000000000000..ff019126b672
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_mix22.c
@@ -0,0 +1,820 @@
1/*
2 * Driver for Digigram pcxhr compatible soundcards
3 *
4 * mixer interface for stereo cards
5 *
6 * Copyright (c) 2004 by Digigram <alsa@digigram.com>
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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/delay.h>
24#include <linux/io.h>
25#include <sound/core.h>
26#include <sound/control.h>
27#include <sound/tlv.h>
28#include <sound/asoundef.h>
29#include "pcxhr.h"
30#include "pcxhr_core.h"
31#include "pcxhr_mix22.h"
32
33
34/* registers used on the DSP and Xilinx (port 2) : HR stereo cards only */
35#define PCXHR_DSP_RESET 0x20
36#define PCXHR_XLX_CFG 0x24
37#define PCXHR_XLX_RUER 0x28
38#define PCXHR_XLX_DATA 0x2C
39#define PCXHR_XLX_STATUS 0x30
40#define PCXHR_XLX_LOFREQ 0x34
41#define PCXHR_XLX_HIFREQ 0x38
42#define PCXHR_XLX_CSUER 0x3C
43#define PCXHR_XLX_SELMIC 0x40
44
45#define PCXHR_DSP 2
46
47/* byte access only ! */
48#define PCXHR_INPB(mgr, x) inb((mgr)->port[PCXHR_DSP] + (x))
49#define PCXHR_OUTPB(mgr, x, data) outb((data), (mgr)->port[PCXHR_DSP] + (x))
50
51
52/* values for PCHR_DSP_RESET register */
53#define PCXHR_DSP_RESET_DSP 0x01
54#define PCXHR_DSP_RESET_MUTE 0x02
55#define PCXHR_DSP_RESET_CODEC 0x08
56
57/* values for PCHR_XLX_CFG register */
58#define PCXHR_CFG_SYNCDSP_MASK 0x80
59#define PCXHR_CFG_DEPENDENCY_MASK 0x60
60#define PCXHR_CFG_INDEPENDANT_SEL 0x00
61#define PCXHR_CFG_MASTER_SEL 0x40
62#define PCXHR_CFG_SLAVE_SEL 0x20
63#define PCXHR_CFG_DATA_UER1_SEL_MASK 0x10 /* 0 (UER0), 1(UER1) */
64#define PCXHR_CFG_DATAIN_SEL_MASK 0x08 /* 0 (ana), 1 (UER) */
65#define PCXHR_CFG_SRC_MASK 0x04 /* 0 (Bypass), 1 (SRC Actif) */
66#define PCXHR_CFG_CLOCK_UER1_SEL_MASK 0x02 /* 0 (UER0), 1(UER1) */
67#define PCXHR_CFG_CLOCKIN_SEL_MASK 0x01 /* 0 (internal), 1 (AES/EBU) */
68
69/* values for PCHR_XLX_DATA register */
70#define PCXHR_DATA_CODEC 0x80
71#define AKM_POWER_CONTROL_CMD 0xA007
72#define AKM_RESET_ON_CMD 0xA100
73#define AKM_RESET_OFF_CMD 0xA103
74#define AKM_CLOCK_INF_55K_CMD 0xA240
75#define AKM_CLOCK_SUP_55K_CMD 0xA24D
76#define AKM_MUTE_CMD 0xA38D
77#define AKM_UNMUTE_CMD 0xA30D
78#define AKM_LEFT_LEVEL_CMD 0xA600
79#define AKM_RIGHT_LEVEL_CMD 0xA700
80
81/* values for PCHR_XLX_STATUS register - READ */
82#define PCXHR_STAT_SRC_LOCK 0x01
83#define PCXHR_STAT_LEVEL_IN 0x02
84#define PCXHR_STAT_MIC_CAPS 0x10
85/* values for PCHR_XLX_STATUS register - WRITE */
86#define PCXHR_STAT_FREQ_SYNC_MASK 0x01
87#define PCXHR_STAT_FREQ_UER1_MASK 0x02
88#define PCXHR_STAT_FREQ_SAVE_MASK 0x80
89
90/* values for PCHR_XLX_CSUER register */
91#define PCXHR_SUER1_BIT_U_READ_MASK 0x80
92#define PCXHR_SUER1_BIT_C_READ_MASK 0x40
93#define PCXHR_SUER1_DATA_PRESENT_MASK 0x20
94#define PCXHR_SUER1_CLOCK_PRESENT_MASK 0x10
95#define PCXHR_SUER_BIT_U_READ_MASK 0x08
96#define PCXHR_SUER_BIT_C_READ_MASK 0x04
97#define PCXHR_SUER_DATA_PRESENT_MASK 0x02
98#define PCXHR_SUER_CLOCK_PRESENT_MASK 0x01
99
100#define PCXHR_SUER_BIT_U_WRITE_MASK 0x02
101#define PCXHR_SUER_BIT_C_WRITE_MASK 0x01
102
103/* values for PCXHR_XLX_SELMIC register - WRITE */
104#define PCXHR_SELMIC_PREAMPLI_OFFSET 2
105#define PCXHR_SELMIC_PREAMPLI_MASK 0x0C
106#define PCXHR_SELMIC_PHANTOM_ALIM 0x80
107
108
109static const unsigned char g_hr222_p_level[] = {
110 0x00, /* [000] -49.5 dB: AKM[000] = -1.#INF dB (mute) */
111 0x01, /* [001] -49.0 dB: AKM[001] = -48.131 dB (diff=0.86920 dB) */
112 0x01, /* [002] -48.5 dB: AKM[001] = -48.131 dB (diff=0.36920 dB) */
113 0x01, /* [003] -48.0 dB: AKM[001] = -48.131 dB (diff=0.13080 dB) */
114 0x01, /* [004] -47.5 dB: AKM[001] = -48.131 dB (diff=0.63080 dB) */
115 0x01, /* [005] -46.5 dB: AKM[001] = -48.131 dB (diff=1.63080 dB) */
116 0x01, /* [006] -47.0 dB: AKM[001] = -48.131 dB (diff=1.13080 dB) */
117 0x01, /* [007] -46.0 dB: AKM[001] = -48.131 dB (diff=2.13080 dB) */
118 0x01, /* [008] -45.5 dB: AKM[001] = -48.131 dB (diff=2.63080 dB) */
119 0x02, /* [009] -45.0 dB: AKM[002] = -42.110 dB (diff=2.88980 dB) */
120 0x02, /* [010] -44.5 dB: AKM[002] = -42.110 dB (diff=2.38980 dB) */
121 0x02, /* [011] -44.0 dB: AKM[002] = -42.110 dB (diff=1.88980 dB) */
122 0x02, /* [012] -43.5 dB: AKM[002] = -42.110 dB (diff=1.38980 dB) */
123 0x02, /* [013] -43.0 dB: AKM[002] = -42.110 dB (diff=0.88980 dB) */
124 0x02, /* [014] -42.5 dB: AKM[002] = -42.110 dB (diff=0.38980 dB) */
125 0x02, /* [015] -42.0 dB: AKM[002] = -42.110 dB (diff=0.11020 dB) */
126 0x02, /* [016] -41.5 dB: AKM[002] = -42.110 dB (diff=0.61020 dB) */
127 0x02, /* [017] -41.0 dB: AKM[002] = -42.110 dB (diff=1.11020 dB) */
128 0x02, /* [018] -40.5 dB: AKM[002] = -42.110 dB (diff=1.61020 dB) */
129 0x03, /* [019] -40.0 dB: AKM[003] = -38.588 dB (diff=1.41162 dB) */
130 0x03, /* [020] -39.5 dB: AKM[003] = -38.588 dB (diff=0.91162 dB) */
131 0x03, /* [021] -39.0 dB: AKM[003] = -38.588 dB (diff=0.41162 dB) */
132 0x03, /* [022] -38.5 dB: AKM[003] = -38.588 dB (diff=0.08838 dB) */
133 0x03, /* [023] -38.0 dB: AKM[003] = -38.588 dB (diff=0.58838 dB) */
134 0x03, /* [024] -37.5 dB: AKM[003] = -38.588 dB (diff=1.08838 dB) */
135 0x04, /* [025] -37.0 dB: AKM[004] = -36.090 dB (diff=0.91040 dB) */
136 0x04, /* [026] -36.5 dB: AKM[004] = -36.090 dB (diff=0.41040 dB) */
137 0x04, /* [027] -36.0 dB: AKM[004] = -36.090 dB (diff=0.08960 dB) */
138 0x04, /* [028] -35.5 dB: AKM[004] = -36.090 dB (diff=0.58960 dB) */
139 0x05, /* [029] -35.0 dB: AKM[005] = -34.151 dB (diff=0.84860 dB) */
140 0x05, /* [030] -34.5 dB: AKM[005] = -34.151 dB (diff=0.34860 dB) */
141 0x05, /* [031] -34.0 dB: AKM[005] = -34.151 dB (diff=0.15140 dB) */
142 0x05, /* [032] -33.5 dB: AKM[005] = -34.151 dB (diff=0.65140 dB) */
143 0x06, /* [033] -33.0 dB: AKM[006] = -32.568 dB (diff=0.43222 dB) */
144 0x06, /* [034] -32.5 dB: AKM[006] = -32.568 dB (diff=0.06778 dB) */
145 0x06, /* [035] -32.0 dB: AKM[006] = -32.568 dB (diff=0.56778 dB) */
146 0x07, /* [036] -31.5 dB: AKM[007] = -31.229 dB (diff=0.27116 dB) */
147 0x07, /* [037] -31.0 dB: AKM[007] = -31.229 dB (diff=0.22884 dB) */
148 0x08, /* [038] -30.5 dB: AKM[008] = -30.069 dB (diff=0.43100 dB) */
149 0x08, /* [039] -30.0 dB: AKM[008] = -30.069 dB (diff=0.06900 dB) */
150 0x09, /* [040] -29.5 dB: AKM[009] = -29.046 dB (diff=0.45405 dB) */
151 0x09, /* [041] -29.0 dB: AKM[009] = -29.046 dB (diff=0.04595 dB) */
152 0x0a, /* [042] -28.5 dB: AKM[010] = -28.131 dB (diff=0.36920 dB) */
153 0x0a, /* [043] -28.0 dB: AKM[010] = -28.131 dB (diff=0.13080 dB) */
154 0x0b, /* [044] -27.5 dB: AKM[011] = -27.303 dB (diff=0.19705 dB) */
155 0x0b, /* [045] -27.0 dB: AKM[011] = -27.303 dB (diff=0.30295 dB) */
156 0x0c, /* [046] -26.5 dB: AKM[012] = -26.547 dB (diff=0.04718 dB) */
157 0x0d, /* [047] -26.0 dB: AKM[013] = -25.852 dB (diff=0.14806 dB) */
158 0x0e, /* [048] -25.5 dB: AKM[014] = -25.208 dB (diff=0.29176 dB) */
159 0x0e, /* [049] -25.0 dB: AKM[014] = -25.208 dB (diff=0.20824 dB) */
160 0x0f, /* [050] -24.5 dB: AKM[015] = -24.609 dB (diff=0.10898 dB) */
161 0x10, /* [051] -24.0 dB: AKM[016] = -24.048 dB (diff=0.04840 dB) */
162 0x11, /* [052] -23.5 dB: AKM[017] = -23.522 dB (diff=0.02183 dB) */
163 0x12, /* [053] -23.0 dB: AKM[018] = -23.025 dB (diff=0.02535 dB) */
164 0x13, /* [054] -22.5 dB: AKM[019] = -22.556 dB (diff=0.05573 dB) */
165 0x14, /* [055] -22.0 dB: AKM[020] = -22.110 dB (diff=0.11020 dB) */
166 0x15, /* [056] -21.5 dB: AKM[021] = -21.686 dB (diff=0.18642 dB) */
167 0x17, /* [057] -21.0 dB: AKM[023] = -20.896 dB (diff=0.10375 dB) */
168 0x18, /* [058] -20.5 dB: AKM[024] = -20.527 dB (diff=0.02658 dB) */
169 0x1a, /* [059] -20.0 dB: AKM[026] = -19.831 dB (diff=0.16866 dB) */
170 0x1b, /* [060] -19.5 dB: AKM[027] = -19.504 dB (diff=0.00353 dB) */
171 0x1d, /* [061] -19.0 dB: AKM[029] = -18.883 dB (diff=0.11716 dB) */
172 0x1e, /* [062] -18.5 dB: AKM[030] = -18.588 dB (diff=0.08838 dB) */
173 0x20, /* [063] -18.0 dB: AKM[032] = -18.028 dB (diff=0.02780 dB) */
174 0x22, /* [064] -17.5 dB: AKM[034] = -17.501 dB (diff=0.00123 dB) */
175 0x24, /* [065] -17.0 dB: AKM[036] = -17.005 dB (diff=0.00475 dB) */
176 0x26, /* [066] -16.5 dB: AKM[038] = -16.535 dB (diff=0.03513 dB) */
177 0x28, /* [067] -16.0 dB: AKM[040] = -16.090 dB (diff=0.08960 dB) */
178 0x2b, /* [068] -15.5 dB: AKM[043] = -15.461 dB (diff=0.03857 dB) */
179 0x2d, /* [069] -15.0 dB: AKM[045] = -15.067 dB (diff=0.06655 dB) */
180 0x30, /* [070] -14.5 dB: AKM[048] = -14.506 dB (diff=0.00598 dB) */
181 0x33, /* [071] -14.0 dB: AKM[051] = -13.979 dB (diff=0.02060 dB) */
182 0x36, /* [072] -13.5 dB: AKM[054] = -13.483 dB (diff=0.01707 dB) */
183 0x39, /* [073] -13.0 dB: AKM[057] = -13.013 dB (diff=0.01331 dB) */
184 0x3c, /* [074] -12.5 dB: AKM[060] = -12.568 dB (diff=0.06778 dB) */
185 0x40, /* [075] -12.0 dB: AKM[064] = -12.007 dB (diff=0.00720 dB) */
186 0x44, /* [076] -11.5 dB: AKM[068] = -11.481 dB (diff=0.01937 dB) */
187 0x48, /* [077] -11.0 dB: AKM[072] = -10.984 dB (diff=0.01585 dB) */
188 0x4c, /* [078] -10.5 dB: AKM[076] = -10.515 dB (diff=0.01453 dB) */
189 0x51, /* [079] -10.0 dB: AKM[081] = -9.961 dB (diff=0.03890 dB) */
190 0x55, /* [080] -9.5 dB: AKM[085] = -9.542 dB (diff=0.04243 dB) */
191 0x5a, /* [081] -9.0 dB: AKM[090] = -9.046 dB (diff=0.04595 dB) */
192 0x60, /* [082] -8.5 dB: AKM[096] = -8.485 dB (diff=0.01462 dB) */
193 0x66, /* [083] -8.0 dB: AKM[102] = -7.959 dB (diff=0.04120 dB) */
194 0x6c, /* [084] -7.5 dB: AKM[108] = -7.462 dB (diff=0.03767 dB) */
195 0x72, /* [085] -7.0 dB: AKM[114] = -6.993 dB (diff=0.00729 dB) */
196 0x79, /* [086] -6.5 dB: AKM[121] = -6.475 dB (diff=0.02490 dB) */
197 0x80, /* [087] -6.0 dB: AKM[128] = -5.987 dB (diff=0.01340 dB) */
198 0x87, /* [088] -5.5 dB: AKM[135] = -5.524 dB (diff=0.02413 dB) */
199 0x8f, /* [089] -5.0 dB: AKM[143] = -5.024 dB (diff=0.02408 dB) */
200 0x98, /* [090] -4.5 dB: AKM[152] = -4.494 dB (diff=0.00607 dB) */
201 0xa1, /* [091] -4.0 dB: AKM[161] = -3.994 dB (diff=0.00571 dB) */
202 0xaa, /* [092] -3.5 dB: AKM[170] = -3.522 dB (diff=0.02183 dB) */
203 0xb5, /* [093] -3.0 dB: AKM[181] = -2.977 dB (diff=0.02277 dB) */
204 0xbf, /* [094] -2.5 dB: AKM[191] = -2.510 dB (diff=0.01014 dB) */
205 0xcb, /* [095] -2.0 dB: AKM[203] = -1.981 dB (diff=0.01912 dB) */
206 0xd7, /* [096] -1.5 dB: AKM[215] = -1.482 dB (diff=0.01797 dB) */
207 0xe3, /* [097] -1.0 dB: AKM[227] = -1.010 dB (diff=0.01029 dB) */
208 0xf1, /* [098] -0.5 dB: AKM[241] = -0.490 dB (diff=0.00954 dB) */
209 0xff, /* [099] +0.0 dB: AKM[255] = +0.000 dB (diff=0.00000 dB) */
210};
211
212
213static void hr222_config_akm(struct pcxhr_mgr *mgr, unsigned short data)
214{
215 unsigned short mask = 0x8000;
216 /* activate access to codec registers */
217 PCXHR_INPB(mgr, PCXHR_XLX_HIFREQ);
218
219 while (mask) {
220 PCXHR_OUTPB(mgr, PCXHR_XLX_DATA,
221 data & mask ? PCXHR_DATA_CODEC : 0);
222 mask >>= 1;
223 }
224 /* termiate access to codec registers */
225 PCXHR_INPB(mgr, PCXHR_XLX_RUER);
226}
227
228
229static int hr222_set_hw_playback_level(struct pcxhr_mgr *mgr,
230 int idx, int level)
231{
232 unsigned short cmd;
233 if (idx > 1 ||
234 level < 0 ||
235 level >= ARRAY_SIZE(g_hr222_p_level))
236 return -EINVAL;
237
238 if (idx == 0)
239 cmd = AKM_LEFT_LEVEL_CMD;
240 else
241 cmd = AKM_RIGHT_LEVEL_CMD;
242
243 /* conversion from PmBoardCodedLevel to AKM nonlinear programming */
244 cmd += g_hr222_p_level[level];
245
246 hr222_config_akm(mgr, cmd);
247 return 0;
248}
249
250
251static int hr222_set_hw_capture_level(struct pcxhr_mgr *mgr,
252 int level_l, int level_r, int level_mic)
253{
254 /* program all input levels at the same time */
255 unsigned int data;
256 int i;
257
258 if (!mgr->capture_chips)
259 return -EINVAL; /* no PCX22 */
260
261 data = ((level_mic & 0xff) << 24); /* micro is mono, but apply */
262 data |= ((level_mic & 0xff) << 16); /* level on both channels */
263 data |= ((level_r & 0xff) << 8); /* line input right channel */
264 data |= (level_l & 0xff); /* line input left channel */
265
266 PCXHR_INPB(mgr, PCXHR_XLX_DATA); /* activate input codec */
267 /* send 32 bits (4 x 8 bits) */
268 for (i = 0; i < 32; i++, data <<= 1) {
269 PCXHR_OUTPB(mgr, PCXHR_XLX_DATA,
270 (data & 0x80000000) ? PCXHR_DATA_CODEC : 0);
271 }
272 PCXHR_INPB(mgr, PCXHR_XLX_RUER); /* close input level codec */
273 return 0;
274}
275
276static void hr222_micro_boost(struct pcxhr_mgr *mgr, int level);
277
278int hr222_sub_init(struct pcxhr_mgr *mgr)
279{
280 unsigned char reg;
281
282 mgr->board_has_analog = 1; /* analog always available */
283 mgr->xlx_cfg = PCXHR_CFG_SYNCDSP_MASK;
284
285 reg = PCXHR_INPB(mgr, PCXHR_XLX_STATUS);
286 if (reg & PCXHR_STAT_MIC_CAPS)
287 mgr->board_has_mic = 1; /* microphone available */
288 snd_printdd("MIC input available = %d\n", mgr->board_has_mic);
289
290 /* reset codec */
291 PCXHR_OUTPB(mgr, PCXHR_DSP_RESET,
292 PCXHR_DSP_RESET_DSP);
293 msleep(5);
294 PCXHR_OUTPB(mgr, PCXHR_DSP_RESET,
295 PCXHR_DSP_RESET_DSP |
296 PCXHR_DSP_RESET_MUTE |
297 PCXHR_DSP_RESET_CODEC);
298 msleep(5);
299
300 /* config AKM */
301 hr222_config_akm(mgr, AKM_POWER_CONTROL_CMD);
302 hr222_config_akm(mgr, AKM_CLOCK_INF_55K_CMD);
303 hr222_config_akm(mgr, AKM_UNMUTE_CMD);
304 hr222_config_akm(mgr, AKM_RESET_OFF_CMD);
305
306 /* init micro boost */
307 hr222_micro_boost(mgr, 0);
308
309 return 0;
310}
311
312
313/* calc PLL register */
314/* TODO : there is a very similar fct in pcxhr.c */
315static int hr222_pll_freq_register(unsigned int freq,
316 unsigned int *pllreg,
317 unsigned int *realfreq)
318{
319 unsigned int reg;
320
321 if (freq < 6900 || freq > 219000)
322 return -EINVAL;
323 reg = (28224000 * 2) / freq;
324 reg = (reg - 1) / 2;
325 if (reg < 0x100)
326 *pllreg = reg + 0xC00;
327 else if (reg < 0x200)
328 *pllreg = reg + 0x800;
329 else if (reg < 0x400)
330 *pllreg = reg & 0x1ff;
331 else if (reg < 0x800) {
332 *pllreg = ((reg >> 1) & 0x1ff) + 0x200;
333 reg &= ~1;
334 } else {
335 *pllreg = ((reg >> 2) & 0x1ff) + 0x400;
336 reg &= ~3;
337 }
338 if (realfreq)
339 *realfreq = (28224000 / (reg + 1));
340 return 0;
341}
342
343int hr222_sub_set_clock(struct pcxhr_mgr *mgr,
344 unsigned int rate,
345 int *changed)
346{
347 unsigned int speed, pllreg = 0;
348 int err;
349 unsigned realfreq = rate;
350
351 switch (mgr->use_clock_type) {
352 case HR22_CLOCK_TYPE_INTERNAL:
353 err = hr222_pll_freq_register(rate, &pllreg, &realfreq);
354 if (err)
355 return err;
356
357 mgr->xlx_cfg &= ~(PCXHR_CFG_CLOCKIN_SEL_MASK |
358 PCXHR_CFG_CLOCK_UER1_SEL_MASK);
359 break;
360 case HR22_CLOCK_TYPE_AES_SYNC:
361 mgr->xlx_cfg |= PCXHR_CFG_CLOCKIN_SEL_MASK;
362 mgr->xlx_cfg &= ~PCXHR_CFG_CLOCK_UER1_SEL_MASK;
363 break;
364 case HR22_CLOCK_TYPE_AES_1:
365 if (!mgr->board_has_aes1)
366 return -EINVAL;
367
368 mgr->xlx_cfg |= (PCXHR_CFG_CLOCKIN_SEL_MASK |
369 PCXHR_CFG_CLOCK_UER1_SEL_MASK);
370 break;
371 default:
372 return -EINVAL;
373 }
374 hr222_config_akm(mgr, AKM_MUTE_CMD);
375
376 if (mgr->use_clock_type == HR22_CLOCK_TYPE_INTERNAL) {
377 PCXHR_OUTPB(mgr, PCXHR_XLX_HIFREQ, pllreg >> 8);
378 PCXHR_OUTPB(mgr, PCXHR_XLX_LOFREQ, pllreg & 0xff);
379 }
380
381 /* set clock source */
382 PCXHR_OUTPB(mgr, PCXHR_XLX_CFG, mgr->xlx_cfg);
383
384 /* codec speed modes */
385 speed = rate < 55000 ? 0 : 1;
386 if (mgr->codec_speed != speed) {
387 mgr->codec_speed = speed;
388 if (speed == 0)
389 hr222_config_akm(mgr, AKM_CLOCK_INF_55K_CMD);
390 else
391 hr222_config_akm(mgr, AKM_CLOCK_SUP_55K_CMD);
392 }
393
394 mgr->sample_rate_real = realfreq;
395 mgr->cur_clock_type = mgr->use_clock_type;
396
397 if (changed)
398 *changed = 1;
399
400 hr222_config_akm(mgr, AKM_UNMUTE_CMD);
401
402 snd_printdd("set_clock to %dHz (realfreq=%d pllreg=%x)\n",
403 rate, realfreq, pllreg);
404 return 0;
405}
406
407int hr222_get_external_clock(struct pcxhr_mgr *mgr,
408 enum pcxhr_clock_type clock_type,
409 int *sample_rate)
410{
411 int rate, calc_rate = 0;
412 unsigned int ticks;
413 unsigned char mask, reg;
414
415 if (clock_type == HR22_CLOCK_TYPE_AES_SYNC) {
416
417 mask = (PCXHR_SUER_CLOCK_PRESENT_MASK |
418 PCXHR_SUER_DATA_PRESENT_MASK);
419 reg = PCXHR_STAT_FREQ_SYNC_MASK;
420
421 } else if (clock_type == HR22_CLOCK_TYPE_AES_1 && mgr->board_has_aes1) {
422
423 mask = (PCXHR_SUER1_CLOCK_PRESENT_MASK |
424 PCXHR_SUER1_DATA_PRESENT_MASK);
425 reg = PCXHR_STAT_FREQ_UER1_MASK;
426
427 } else {
428 snd_printdd("get_external_clock : type %d not supported\n",
429 clock_type);
430 return -EINVAL; /* other clocks not supported */
431 }
432
433 if ((PCXHR_INPB(mgr, PCXHR_XLX_CSUER) & mask) != mask) {
434 snd_printdd("get_external_clock(%d) = 0 Hz\n", clock_type);
435 *sample_rate = 0;
436 return 0; /* no external clock locked */
437 }
438
439 PCXHR_OUTPB(mgr, PCXHR_XLX_STATUS, reg); /* calculate freq */
440
441 /* save the measured clock frequency */
442 reg |= PCXHR_STAT_FREQ_SAVE_MASK;
443
444 if (mgr->last_reg_stat != reg) {
445 udelay(500); /* wait min 2 cycles of lowest freq (8000) */
446 mgr->last_reg_stat = reg;
447 }
448
449 PCXHR_OUTPB(mgr, PCXHR_XLX_STATUS, reg); /* save */
450
451 /* get the frequency */
452 ticks = (unsigned int)PCXHR_INPB(mgr, PCXHR_XLX_CFG);
453 ticks = (ticks & 0x03) << 8;
454 ticks |= (unsigned int)PCXHR_INPB(mgr, PCXHR_DSP_RESET);
455
456 if (ticks != 0)
457 calc_rate = 28224000 / ticks;
458 /* rounding */
459 if (calc_rate > 184200)
460 rate = 192000;
461 else if (calc_rate > 152200)
462 rate = 176400;
463 else if (calc_rate > 112000)
464 rate = 128000;
465 else if (calc_rate > 92100)
466 rate = 96000;
467 else if (calc_rate > 76100)
468 rate = 88200;
469 else if (calc_rate > 56000)
470 rate = 64000;
471 else if (calc_rate > 46050)
472 rate = 48000;
473 else if (calc_rate > 38050)
474 rate = 44100;
475 else if (calc_rate > 28000)
476 rate = 32000;
477 else if (calc_rate > 23025)
478 rate = 24000;
479 else if (calc_rate > 19025)
480 rate = 22050;
481 else if (calc_rate > 14000)
482 rate = 16000;
483 else if (calc_rate > 11512)
484 rate = 12000;
485 else if (calc_rate > 9512)
486 rate = 11025;
487 else if (calc_rate > 7000)
488 rate = 8000;
489 else
490 rate = 0;
491
492 snd_printdd("External clock is at %d Hz (measured %d Hz)\n",
493 rate, calc_rate);
494 *sample_rate = rate;
495 return 0;
496}
497
498
499int hr222_update_analog_audio_level(struct snd_pcxhr *chip,
500 int is_capture, int channel)
501{
502 snd_printdd("hr222_update_analog_audio_level(%s chan=%d)\n",
503 is_capture ? "capture" : "playback", channel);
504 if (is_capture) {
505 int level_l, level_r, level_mic;
506 /* we have to update all levels */
507 if (chip->analog_capture_active) {
508 level_l = chip->analog_capture_volume[0];
509 level_r = chip->analog_capture_volume[1];
510 } else {
511 level_l = HR222_LINE_CAPTURE_LEVEL_MIN;
512 level_r = HR222_LINE_CAPTURE_LEVEL_MIN;
513 }
514 if (chip->mic_active)
515 level_mic = chip->mic_volume;
516 else
517 level_mic = HR222_MICRO_CAPTURE_LEVEL_MIN;
518 return hr222_set_hw_capture_level(chip->mgr,
519 level_l, level_r, level_mic);
520 } else {
521 int vol;
522 if (chip->analog_playback_active[channel])
523 vol = chip->analog_playback_volume[channel];
524 else
525 vol = HR222_LINE_PLAYBACK_LEVEL_MIN;
526 return hr222_set_hw_playback_level(chip->mgr, channel, vol);
527 }
528}
529
530
531/*texts[5] = {"Line", "Digital", "Digi+SRC", "Mic", "Line+Mic"}*/
532#define SOURCE_LINE 0
533#define SOURCE_DIGITAL 1
534#define SOURCE_DIGISRC 2
535#define SOURCE_MIC 3
536#define SOURCE_LINEMIC 4
537
538int hr222_set_audio_source(struct snd_pcxhr *chip)
539{
540 int digital = 0;
541 /* default analog source */
542 chip->mgr->xlx_cfg &= ~(PCXHR_CFG_SRC_MASK |
543 PCXHR_CFG_DATAIN_SEL_MASK |
544 PCXHR_CFG_DATA_UER1_SEL_MASK);
545
546 if (chip->audio_capture_source == SOURCE_DIGISRC) {
547 chip->mgr->xlx_cfg |= PCXHR_CFG_SRC_MASK;
548 digital = 1;
549 } else {
550 if (chip->audio_capture_source == SOURCE_DIGITAL)
551 digital = 1;
552 }
553 if (digital) {
554 chip->mgr->xlx_cfg |= PCXHR_CFG_DATAIN_SEL_MASK;
555 if (chip->mgr->board_has_aes1) {
556 /* get data from the AES1 plug */
557 chip->mgr->xlx_cfg |= PCXHR_CFG_DATA_UER1_SEL_MASK;
558 }
559 /* chip->mic_active = 0; */
560 /* chip->analog_capture_active = 0; */
561 } else {
562 int update_lvl = 0;
563 chip->analog_capture_active = 0;
564 chip->mic_active = 0;
565 if (chip->audio_capture_source == SOURCE_LINE ||
566 chip->audio_capture_source == SOURCE_LINEMIC) {
567 if (chip->analog_capture_active == 0)
568 update_lvl = 1;
569 chip->analog_capture_active = 1;
570 }
571 if (chip->audio_capture_source == SOURCE_MIC ||
572 chip->audio_capture_source == SOURCE_LINEMIC) {
573 if (chip->mic_active == 0)
574 update_lvl = 1;
575 chip->mic_active = 1;
576 }
577 if (update_lvl) {
578 /* capture: update all 3 mutes/unmutes with one call */
579 hr222_update_analog_audio_level(chip, 1, 0);
580 }
581 }
582 /* set the source infos (max 3 bits modified) */
583 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_CFG, chip->mgr->xlx_cfg);
584 return 0;
585}
586
587
588int hr222_iec958_capture_byte(struct snd_pcxhr *chip,
589 int aes_idx, unsigned char *aes_bits)
590{
591 unsigned char idx = (unsigned char)(aes_idx * 8);
592 unsigned char temp = 0;
593 unsigned char mask = chip->mgr->board_has_aes1 ?
594 PCXHR_SUER1_BIT_C_READ_MASK : PCXHR_SUER_BIT_C_READ_MASK;
595 int i;
596 for (i = 0; i < 8; i++) {
597 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_RUER, idx++); /* idx < 192 */
598 temp <<= 1;
599 if (PCXHR_INPB(chip->mgr, PCXHR_XLX_CSUER) & mask)
600 temp |= 1;
601 }
602 snd_printdd("read iec958 AES %d byte %d = 0x%x\n",
603 chip->chip_idx, aes_idx, temp);
604 *aes_bits = temp;
605 return 0;
606}
607
608
609int hr222_iec958_update_byte(struct snd_pcxhr *chip,
610 int aes_idx, unsigned char aes_bits)
611{
612 int i;
613 unsigned char new_bits = aes_bits;
614 unsigned char old_bits = chip->aes_bits[aes_idx];
615 unsigned char idx = (unsigned char)(aes_idx * 8);
616 for (i = 0; i < 8; i++) {
617 if ((old_bits & 0x01) != (new_bits & 0x01)) {
618 /* idx < 192 */
619 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_RUER, idx);
620 /* write C and U bit */
621 PCXHR_OUTPB(chip->mgr, PCXHR_XLX_CSUER, new_bits&0x01 ?
622 PCXHR_SUER_BIT_C_WRITE_MASK : 0);
623 }
624 idx++;
625 old_bits >>= 1;
626 new_bits >>= 1;
627 }
628 chip->aes_bits[aes_idx] = aes_bits;
629 return 0;
630}
631
632static void hr222_micro_boost(struct pcxhr_mgr *mgr, int level)
633{
634 unsigned char boost_mask;
635 boost_mask = (unsigned char) (level << PCXHR_SELMIC_PREAMPLI_OFFSET);
636 if (boost_mask & (~PCXHR_SELMIC_PREAMPLI_MASK))
637 return; /* only values form 0 to 3 accepted */
638
639 mgr->xlx_selmic &= ~PCXHR_SELMIC_PREAMPLI_MASK;
640 mgr->xlx_selmic |= boost_mask;
641
642 PCXHR_OUTPB(mgr, PCXHR_XLX_SELMIC, mgr->xlx_selmic);
643
644 snd_printdd("hr222_micro_boost : set %x\n", boost_mask);
645}
646
647static void hr222_phantom_power(struct pcxhr_mgr *mgr, int power)
648{
649 if (power)
650 mgr->xlx_selmic |= PCXHR_SELMIC_PHANTOM_ALIM;
651 else
652 mgr->xlx_selmic &= ~PCXHR_SELMIC_PHANTOM_ALIM;
653
654 PCXHR_OUTPB(mgr, PCXHR_XLX_SELMIC, mgr->xlx_selmic);
655
656 snd_printdd("hr222_phantom_power : set %d\n", power);
657}
658
659
660/* mic level */
661static const DECLARE_TLV_DB_SCALE(db_scale_mic_hr222, -9850, 50, 650);
662
663static int hr222_mic_vol_info(struct snd_kcontrol *kcontrol,
664 struct snd_ctl_elem_info *uinfo)
665{
666 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
667 uinfo->count = 1;
668 uinfo->value.integer.min = HR222_MICRO_CAPTURE_LEVEL_MIN; /* -98 dB */
669 /* gains from 9 dB to 31.5 dB not recommended; use micboost instead */
670 uinfo->value.integer.max = HR222_MICRO_CAPTURE_LEVEL_MAX; /* +7 dB */
671 return 0;
672}
673
674static int hr222_mic_vol_get(struct snd_kcontrol *kcontrol,
675 struct snd_ctl_elem_value *ucontrol)
676{
677 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
678 mutex_lock(&chip->mgr->mixer_mutex);
679 ucontrol->value.integer.value[0] = chip->mic_volume;
680 mutex_unlock(&chip->mgr->mixer_mutex);
681 return 0;
682}
683
684static int hr222_mic_vol_put(struct snd_kcontrol *kcontrol,
685 struct snd_ctl_elem_value *ucontrol)
686{
687 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
688 int changed = 0;
689 mutex_lock(&chip->mgr->mixer_mutex);
690 if (chip->mic_volume != ucontrol->value.integer.value[0]) {
691 changed = 1;
692 chip->mic_volume = ucontrol->value.integer.value[0];
693 hr222_update_analog_audio_level(chip, 1, 0);
694 }
695 mutex_unlock(&chip->mgr->mixer_mutex);
696 return changed;
697}
698
699static struct snd_kcontrol_new hr222_control_mic_level = {
700 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
701 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
702 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
703 .name = "Mic Capture Volume",
704 .info = hr222_mic_vol_info,
705 .get = hr222_mic_vol_get,
706 .put = hr222_mic_vol_put,
707 .tlv = { .p = db_scale_mic_hr222 },
708};
709
710
711/* mic boost level */
712static const DECLARE_TLV_DB_SCALE(db_scale_micboost_hr222, 0, 1800, 5400);
713
714static int hr222_mic_boost_info(struct snd_kcontrol *kcontrol,
715 struct snd_ctl_elem_info *uinfo)
716{
717 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
718 uinfo->count = 1;
719 uinfo->value.integer.min = 0; /* 0 dB */
720 uinfo->value.integer.max = 3; /* 54 dB */
721 return 0;
722}
723
724static int hr222_mic_boost_get(struct snd_kcontrol *kcontrol,
725 struct snd_ctl_elem_value *ucontrol)
726{
727 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
728 mutex_lock(&chip->mgr->mixer_mutex);
729 ucontrol->value.integer.value[0] = chip->mic_boost;
730 mutex_unlock(&chip->mgr->mixer_mutex);
731 return 0;
732}
733
734static int hr222_mic_boost_put(struct snd_kcontrol *kcontrol,
735 struct snd_ctl_elem_value *ucontrol)
736{
737 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
738 int changed = 0;
739 mutex_lock(&chip->mgr->mixer_mutex);
740 if (chip->mic_boost != ucontrol->value.integer.value[0]) {
741 changed = 1;
742 chip->mic_boost = ucontrol->value.integer.value[0];
743 hr222_micro_boost(chip->mgr, chip->mic_boost);
744 }
745 mutex_unlock(&chip->mgr->mixer_mutex);
746 return changed;
747}
748
749static struct snd_kcontrol_new hr222_control_mic_boost = {
750 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
751 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
752 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
753 .name = "MicBoost Capture Volume",
754 .info = hr222_mic_boost_info,
755 .get = hr222_mic_boost_get,
756 .put = hr222_mic_boost_put,
757 .tlv = { .p = db_scale_micboost_hr222 },
758};
759
760
761/******************* Phantom power switch *******************/
762#define hr222_phantom_power_info snd_ctl_boolean_mono_info
763
764static int hr222_phantom_power_get(struct snd_kcontrol *kcontrol,
765 struct snd_ctl_elem_value *ucontrol)
766{
767 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
768 mutex_lock(&chip->mgr->mixer_mutex);
769 ucontrol->value.integer.value[0] = chip->phantom_power;
770 mutex_unlock(&chip->mgr->mixer_mutex);
771 return 0;
772}
773
774static int hr222_phantom_power_put(struct snd_kcontrol *kcontrol,
775 struct snd_ctl_elem_value *ucontrol)
776{
777 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
778 int power, changed = 0;
779
780 mutex_lock(&chip->mgr->mixer_mutex);
781 power = !!ucontrol->value.integer.value[0];
782 if (chip->phantom_power != power) {
783 hr222_phantom_power(chip->mgr, power);
784 chip->phantom_power = power;
785 changed = 1;
786 }
787 mutex_unlock(&chip->mgr->mixer_mutex);
788 return changed;
789}
790
791static struct snd_kcontrol_new hr222_phantom_power_switch = {
792 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
793 .name = "Phantom Power Switch",
794 .info = hr222_phantom_power_info,
795 .get = hr222_phantom_power_get,
796 .put = hr222_phantom_power_put,
797};
798
799
800int hr222_add_mic_controls(struct snd_pcxhr *chip)
801{
802 int err;
803 if (!chip->mgr->board_has_mic)
804 return 0;
805
806 /* controls */
807 err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_control_mic_level,
808 chip));
809 if (err < 0)
810 return err;
811
812 err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_control_mic_boost,
813 chip));
814 if (err < 0)
815 return err;
816
817 err = snd_ctl_add(chip->card, snd_ctl_new1(&hr222_phantom_power_switch,
818 chip));
819 return err;
820}
diff --git a/sound/pci/pcxhr/pcxhr_mix22.h b/sound/pci/pcxhr/pcxhr_mix22.h
new file mode 100644
index 000000000000..6b318b2f0100
--- /dev/null
+++ b/sound/pci/pcxhr/pcxhr_mix22.h
@@ -0,0 +1,56 @@
1/*
2 * Driver for Digigram pcxhr compatible soundcards
3 *
4 * low level interface with interrupt ans message handling
5 *
6 * Copyright (c) 2004 by Digigram <alsa@digigram.com>
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 as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __SOUND_PCXHR_MIX22_H
24#define __SOUND_PCXHR_MIX22_H
25
26struct pcxhr_mgr;
27
28int hr222_sub_init(struct pcxhr_mgr *mgr);
29int hr222_sub_set_clock(struct pcxhr_mgr *mgr, unsigned int rate,
30 int *changed);
31int hr222_get_external_clock(struct pcxhr_mgr *mgr,
32 enum pcxhr_clock_type clock_type,
33 int *sample_rate);
34
35#define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */
36#define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */
37#define HR222_LINE_PLAYBACK_LEVEL_MAX 99 /* +24.0 dB */
38
39#define HR222_LINE_CAPTURE_LEVEL_MIN 0 /* -111.5 dB */
40#define HR222_LINE_CAPTURE_ZERO_LEVEL 223 /* 0.0 dB */
41#define HR222_LINE_CAPTURE_LEVEL_MAX 255 /* +16 dB */
42#define HR222_MICRO_CAPTURE_LEVEL_MIN 0 /* -98.5 dB */
43#define HR222_MICRO_CAPTURE_LEVEL_MAX 210 /* +6.5 dB */
44
45int hr222_update_analog_audio_level(struct snd_pcxhr *chip,
46 int is_capture,
47 int channel);
48int hr222_set_audio_source(struct snd_pcxhr *chip);
49int hr222_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx,
50 unsigned char *aes_bits);
51int hr222_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx,
52 unsigned char aes_bits);
53
54int hr222_add_mic_controls(struct snd_pcxhr *chip);
55
56#endif /* __SOUND_PCXHR_MIX22_H */
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c
index aabc7bc5321e..2436e374586f 100644
--- a/sound/pci/pcxhr/pcxhr_mixer.c
+++ b/sound/pci/pcxhr/pcxhr_mixer.c
@@ -33,20 +33,24 @@
33#include <sound/tlv.h> 33#include <sound/tlv.h>
34#include <sound/asoundef.h> 34#include <sound/asoundef.h>
35#include "pcxhr_mixer.h" 35#include "pcxhr_mixer.h"
36#include "pcxhr_mix22.h"
36 37
38#define PCXHR_LINE_CAPTURE_LEVEL_MIN 0 /* -112.0 dB */
39#define PCXHR_LINE_CAPTURE_LEVEL_MAX 255 /* +15.5 dB */
40#define PCXHR_LINE_CAPTURE_ZERO_LEVEL 224 /* 0.0 dB ( 0 dBu -> 0 dBFS ) */
37 41
38#define PCXHR_ANALOG_CAPTURE_LEVEL_MIN 0 /* -96.0 dB */ 42#define PCXHR_LINE_PLAYBACK_LEVEL_MIN 0 /* -104.0 dB */
39#define PCXHR_ANALOG_CAPTURE_LEVEL_MAX 255 /* +31.5 dB */ 43#define PCXHR_LINE_PLAYBACK_LEVEL_MAX 128 /* +24.0 dB */
40#define PCXHR_ANALOG_CAPTURE_ZERO_LEVEL 224 /* +16.0 dB ( +31.5 dB - fix level +15.5 dB ) */ 44#define PCXHR_LINE_PLAYBACK_ZERO_LEVEL 104 /* 0.0 dB ( 0 dBFS -> 0 dBu ) */
41 45
42#define PCXHR_ANALOG_PLAYBACK_LEVEL_MIN 0 /* -128.0 dB */ 46static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -11200, 50, 1550);
43#define PCXHR_ANALOG_PLAYBACK_LEVEL_MAX 128 /* 0.0 dB */
44#define PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL 104 /* -24.0 dB ( 0.0 dB - fix level +24.0 dB ) */
45
46static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 3150);
47static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400); 47static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400);
48 48
49static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel) 49static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_capture, -11150, 50, 1600);
50static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_playback, -2550, 50, 2400);
51
52static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip,
53 int is_capture, int channel)
50{ 54{
51 int err, vol; 55 int err, vol;
52 struct pcxhr_rmh rmh; 56 struct pcxhr_rmh rmh;
@@ -60,15 +64,17 @@ static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_captur
60 if (chip->analog_playback_active[channel]) 64 if (chip->analog_playback_active[channel])
61 vol = chip->analog_playback_volume[channel]; 65 vol = chip->analog_playback_volume[channel];
62 else 66 else
63 vol = PCXHR_ANALOG_PLAYBACK_LEVEL_MIN; 67 vol = PCXHR_LINE_PLAYBACK_LEVEL_MIN;
64 rmh.cmd[2] = PCXHR_ANALOG_PLAYBACK_LEVEL_MAX - vol; /* playback analog levels are inversed */ 68 /* playback analog levels are inversed */
69 rmh.cmd[2] = PCXHR_LINE_PLAYBACK_LEVEL_MAX - vol;
65 } 70 }
66 rmh.cmd[1] = 1 << ((2 * chip->chip_idx) + channel); /* audio mask */ 71 rmh.cmd[1] = 1 << ((2 * chip->chip_idx) + channel); /* audio mask */
67 rmh.cmd_len = 3; 72 rmh.cmd_len = 3;
68 err = pcxhr_send_msg(chip->mgr, &rmh); 73 err = pcxhr_send_msg(chip->mgr, &rmh);
69 if (err < 0) { 74 if (err < 0) {
70 snd_printk(KERN_DEBUG "error update_analog_audio_level card(%d) " 75 snd_printk(KERN_DEBUG "error update_analog_audio_level card(%d)"
71 "is_capture(%d) err(%x)\n", chip->chip_idx, is_capture, err); 76 " is_capture(%d) err(%x)\n",
77 chip->chip_idx, is_capture, err);
72 return -EINVAL; 78 return -EINVAL;
73 } 79 }
74 return 0; 80 return 0;
@@ -80,14 +86,34 @@ static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_captur
80static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol, 86static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol,
81 struct snd_ctl_elem_info *uinfo) 87 struct snd_ctl_elem_info *uinfo)
82{ 88{
89 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
90
83 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 91 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
84 uinfo->count = 2; 92 uinfo->count = 2;
85 if (kcontrol->private_value == 0) { /* playback */ 93 if (kcontrol->private_value == 0) { /* playback */
86 uinfo->value.integer.min = PCXHR_ANALOG_PLAYBACK_LEVEL_MIN; /* -128 dB */ 94 if (chip->mgr->is_hr_stereo) {
87 uinfo->value.integer.max = PCXHR_ANALOG_PLAYBACK_LEVEL_MAX; /* 0 dB */ 95 uinfo->value.integer.min =
96 HR222_LINE_PLAYBACK_LEVEL_MIN; /* -25 dB */
97 uinfo->value.integer.max =
98 HR222_LINE_PLAYBACK_LEVEL_MAX; /* +24 dB */
99 } else {
100 uinfo->value.integer.min =
101 PCXHR_LINE_PLAYBACK_LEVEL_MIN; /*-104 dB */
102 uinfo->value.integer.max =
103 PCXHR_LINE_PLAYBACK_LEVEL_MAX; /* +24 dB */
104 }
88 } else { /* capture */ 105 } else { /* capture */
89 uinfo->value.integer.min = PCXHR_ANALOG_CAPTURE_LEVEL_MIN; /* -96 dB */ 106 if (chip->mgr->is_hr_stereo) {
90 uinfo->value.integer.max = PCXHR_ANALOG_CAPTURE_LEVEL_MAX; /* 31.5 dB */ 107 uinfo->value.integer.min =
108 HR222_LINE_CAPTURE_LEVEL_MIN; /*-112 dB */
109 uinfo->value.integer.max =
110 HR222_LINE_CAPTURE_LEVEL_MAX; /* +15.5 dB */
111 } else {
112 uinfo->value.integer.min =
113 PCXHR_LINE_CAPTURE_LEVEL_MIN; /*-112 dB */
114 uinfo->value.integer.max =
115 PCXHR_LINE_CAPTURE_LEVEL_MAX; /* +15.5 dB */
116 }
91 } 117 }
92 return 0; 118 return 0;
93} 119}
@@ -98,11 +124,11 @@ static int pcxhr_analog_vol_get(struct snd_kcontrol *kcontrol,
98 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 124 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
99 mutex_lock(&chip->mgr->mixer_mutex); 125 mutex_lock(&chip->mgr->mixer_mutex);
100 if (kcontrol->private_value == 0) { /* playback */ 126 if (kcontrol->private_value == 0) { /* playback */
101 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0]; 127 ucontrol->value.integer.value[0] = chip->analog_playback_volume[0];
102 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1]; 128 ucontrol->value.integer.value[1] = chip->analog_playback_volume[1];
103 } else { /* capture */ 129 } else { /* capture */
104 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0]; 130 ucontrol->value.integer.value[0] = chip->analog_capture_volume[0];
105 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1]; 131 ucontrol->value.integer.value[1] = chip->analog_capture_volume[1];
106 } 132 }
107 mutex_unlock(&chip->mgr->mixer_mutex); 133 mutex_unlock(&chip->mgr->mixer_mutex);
108 return 0; 134 return 0;
@@ -123,18 +149,35 @@ static int pcxhr_analog_vol_put(struct snd_kcontrol *kcontrol,
123 &chip->analog_capture_volume[i] : 149 &chip->analog_capture_volume[i] :
124 &chip->analog_playback_volume[i]; 150 &chip->analog_playback_volume[i];
125 if (is_capture) { 151 if (is_capture) {
126 if (new_volume < PCXHR_ANALOG_CAPTURE_LEVEL_MIN || 152 if (chip->mgr->is_hr_stereo) {
127 new_volume > PCXHR_ANALOG_CAPTURE_LEVEL_MAX) 153 if (new_volume < HR222_LINE_CAPTURE_LEVEL_MIN ||
128 continue; 154 new_volume > HR222_LINE_CAPTURE_LEVEL_MAX)
155 continue;
156 } else {
157 if (new_volume < PCXHR_LINE_CAPTURE_LEVEL_MIN ||
158 new_volume > PCXHR_LINE_CAPTURE_LEVEL_MAX)
159 continue;
160 }
129 } else { 161 } else {
130 if (new_volume < PCXHR_ANALOG_PLAYBACK_LEVEL_MIN || 162 if (chip->mgr->is_hr_stereo) {
131 new_volume > PCXHR_ANALOG_PLAYBACK_LEVEL_MAX) 163 if (new_volume < HR222_LINE_PLAYBACK_LEVEL_MIN ||
132 continue; 164 new_volume > HR222_LINE_PLAYBACK_LEVEL_MAX)
165 continue;
166 } else {
167 if (new_volume < PCXHR_LINE_PLAYBACK_LEVEL_MIN ||
168 new_volume > PCXHR_LINE_PLAYBACK_LEVEL_MAX)
169 continue;
170 }
133 } 171 }
134 if (*stored_volume != new_volume) { 172 if (*stored_volume != new_volume) {
135 *stored_volume = new_volume; 173 *stored_volume = new_volume;
136 changed = 1; 174 changed = 1;
137 pcxhr_update_analog_audio_level(chip, is_capture, i); 175 if (chip->mgr->is_hr_stereo)
176 hr222_update_analog_audio_level(chip,
177 is_capture, i);
178 else
179 pcxhr_update_analog_audio_level(chip,
180 is_capture, i);
138 } 181 }
139 } 182 }
140 mutex_unlock(&chip->mgr->mixer_mutex); 183 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -153,6 +196,7 @@ static struct snd_kcontrol_new pcxhr_control_analog_level = {
153}; 196};
154 197
155/* shared */ 198/* shared */
199
156#define pcxhr_sw_info snd_ctl_boolean_stereo_info 200#define pcxhr_sw_info snd_ctl_boolean_stereo_info
157 201
158static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol, 202static int pcxhr_audio_sw_get(struct snd_kcontrol *kcontrol,
@@ -180,7 +224,10 @@ static int pcxhr_audio_sw_put(struct snd_kcontrol *kcontrol,
180 !!ucontrol->value.integer.value[i]; 224 !!ucontrol->value.integer.value[i];
181 changed = 1; 225 changed = 1;
182 /* update playback levels */ 226 /* update playback levels */
183 pcxhr_update_analog_audio_level(chip, 0, i); 227 if (chip->mgr->is_hr_stereo)
228 hr222_update_analog_audio_level(chip, 0, i);
229 else
230 pcxhr_update_analog_audio_level(chip, 0, i);
184 } 231 }
185 } 232 }
186 mutex_unlock(&chip->mgr->mixer_mutex); 233 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -251,7 +298,8 @@ static int pcxhr_update_playback_stream_level(struct snd_pcxhr* chip, int idx)
251#define VALID_AUDIO_IO_MUTE_LEVEL 0x000004 298#define VALID_AUDIO_IO_MUTE_LEVEL 0x000004
252#define VALID_AUDIO_IO_MUTE_MONITOR_1 0x000008 299#define VALID_AUDIO_IO_MUTE_MONITOR_1 0x000008
253 300
254static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, int channel) 301static int pcxhr_update_audio_pipe_level(struct snd_pcxhr *chip,
302 int capture, int channel)
255{ 303{
256 int err; 304 int err;
257 struct pcxhr_rmh rmh; 305 struct pcxhr_rmh rmh;
@@ -264,18 +312,20 @@ static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, in
264 312
265 pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST); 313 pcxhr_init_rmh(&rmh, CMD_AUDIO_LEVEL_ADJUST);
266 /* add channel mask */ 314 /* add channel mask */
267 pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0, 1 << (channel + pipe->first_audio)); 315 pcxhr_set_pipe_cmd_params(&rmh, capture, 0, 0,
268 /* TODO : if mask (3 << pipe->first_audio) is used, left and right channel 316 1 << (channel + pipe->first_audio));
269 * will be programmed to the same params 317 /* TODO : if mask (3 << pipe->first_audio) is used, left and right
270 */ 318 * channel will be programmed to the same params */
271 if (capture) { 319 if (capture) {
272 rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL; 320 rmh.cmd[0] |= VALID_AUDIO_IO_DIGITAL_LEVEL;
273 /* VALID_AUDIO_IO_MUTE_LEVEL not yet handled (capture pipe level) */ 321 /* VALID_AUDIO_IO_MUTE_LEVEL not yet handled
322 * (capture pipe level) */
274 rmh.cmd[2] = chip->digital_capture_volume[channel]; 323 rmh.cmd[2] = chip->digital_capture_volume[channel];
275 } else { 324 } else {
276 rmh.cmd[0] |= VALID_AUDIO_IO_MONITOR_LEVEL | VALID_AUDIO_IO_MUTE_MONITOR_1; 325 rmh.cmd[0] |= VALID_AUDIO_IO_MONITOR_LEVEL |
277 /* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL not yet 326 VALID_AUDIO_IO_MUTE_MONITOR_1;
278 * handled (playback pipe level) 327 /* VALID_AUDIO_IO_DIGITAL_LEVEL and VALID_AUDIO_IO_MUTE_LEVEL
328 * not yet handled (playback pipe level)
279 */ 329 */
280 rmh.cmd[2] = chip->monitoring_volume[channel] << 10; 330 rmh.cmd[2] = chip->monitoring_volume[channel] << 10;
281 if (chip->monitoring_active[channel] == 0) 331 if (chip->monitoring_active[channel] == 0)
@@ -284,8 +334,8 @@ static int pcxhr_update_audio_pipe_level(struct snd_pcxhr* chip, int capture, in
284 rmh.cmd_len = 3; 334 rmh.cmd_len = 3;
285 335
286 err = pcxhr_send_msg(chip->mgr, &rmh); 336 err = pcxhr_send_msg(chip->mgr, &rmh);
287 if(err<0) { 337 if (err < 0) {
288 snd_printk(KERN_DEBUG "error update_audio_level card(%d) err(%x)\n", 338 snd_printk(KERN_DEBUG "error update_audio_level(%d) err=%x\n",
289 chip->chip_idx, err); 339 chip->chip_idx, err);
290 return -EINVAL; 340 return -EINVAL;
291 } 341 }
@@ -309,15 +359,15 @@ static int pcxhr_pcm_vol_get(struct snd_kcontrol *kcontrol,
309 struct snd_ctl_elem_value *ucontrol) 359 struct snd_ctl_elem_value *ucontrol)
310{ 360{
311 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 361 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
312 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ 362 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
313 int *stored_volume; 363 int *stored_volume;
314 int is_capture = kcontrol->private_value; 364 int is_capture = kcontrol->private_value;
315 365
316 mutex_lock(&chip->mgr->mixer_mutex); 366 mutex_lock(&chip->mgr->mixer_mutex);
317 if (is_capture) 367 if (is_capture) /* digital capture */
318 stored_volume = chip->digital_capture_volume; /* digital capture */ 368 stored_volume = chip->digital_capture_volume;
319 else 369 else /* digital playback */
320 stored_volume = chip->digital_playback_volume[idx]; /* digital playback */ 370 stored_volume = chip->digital_playback_volume[idx];
321 ucontrol->value.integer.value[0] = stored_volume[0]; 371 ucontrol->value.integer.value[0] = stored_volume[0];
322 ucontrol->value.integer.value[1] = stored_volume[1]; 372 ucontrol->value.integer.value[1] = stored_volume[1];
323 mutex_unlock(&chip->mgr->mixer_mutex); 373 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -328,7 +378,7 @@ static int pcxhr_pcm_vol_put(struct snd_kcontrol *kcontrol,
328 struct snd_ctl_elem_value *ucontrol) 378 struct snd_ctl_elem_value *ucontrol)
329{ 379{
330 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 380 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
331 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ 381 int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */
332 int changed = 0; 382 int changed = 0;
333 int is_capture = kcontrol->private_value; 383 int is_capture = kcontrol->private_value;
334 int *stored_volume; 384 int *stored_volume;
@@ -384,7 +434,8 @@ static int pcxhr_pcm_sw_get(struct snd_kcontrol *kcontrol,
384 return 0; 434 return 0;
385} 435}
386 436
387static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 437static int pcxhr_pcm_sw_put(struct snd_kcontrol *kcontrol,
438 struct snd_ctl_elem_value *ucontrol)
388{ 439{
389 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 440 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
390 int changed = 0; 441 int changed = 0;
@@ -444,8 +495,8 @@ static int pcxhr_monitor_vol_put(struct snd_kcontrol *kcontrol,
444 if (chip->monitoring_volume[i] != 495 if (chip->monitoring_volume[i] !=
445 ucontrol->value.integer.value[i]) { 496 ucontrol->value.integer.value[i]) {
446 chip->monitoring_volume[i] = 497 chip->monitoring_volume[i] =
447 !!ucontrol->value.integer.value[i]; 498 ucontrol->value.integer.value[i];
448 if(chip->monitoring_active[i]) 499 if (chip->monitoring_active[i])
449 /* update monitoring volume and mute */ 500 /* update monitoring volume and mute */
450 /* do only when monitoring is unmuted */ 501 /* do only when monitoring is unmuted */
451 pcxhr_update_audio_pipe_level(chip, 0, i); 502 pcxhr_update_audio_pipe_level(chip, 0, i);
@@ -460,7 +511,7 @@ static struct snd_kcontrol_new pcxhr_control_monitor_vol = {
460 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 511 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
461 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 512 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
462 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 513 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
463 .name = "Monitoring Volume", 514 .name = "Monitoring Playback Volume",
464 .info = pcxhr_digital_vol_info, /* shared */ 515 .info = pcxhr_digital_vol_info, /* shared */
465 .get = pcxhr_monitor_vol_get, 516 .get = pcxhr_monitor_vol_get,
466 .put = pcxhr_monitor_vol_put, 517 .put = pcxhr_monitor_vol_put,
@@ -511,7 +562,7 @@ static int pcxhr_monitor_sw_put(struct snd_kcontrol *kcontrol,
511 562
512static struct snd_kcontrol_new pcxhr_control_monitor_sw = { 563static struct snd_kcontrol_new pcxhr_control_monitor_sw = {
513 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
514 .name = "Monitoring Switch", 565 .name = "Monitoring Playback Switch",
515 .info = pcxhr_sw_info, /* shared */ 566 .info = pcxhr_sw_info, /* shared */
516 .get = pcxhr_monitor_sw_get, 567 .get = pcxhr_monitor_sw_get,
517 .put = pcxhr_monitor_sw_put 568 .put = pcxhr_monitor_sw_put
@@ -533,7 +584,7 @@ static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
533 struct pcxhr_rmh rmh; 584 struct pcxhr_rmh rmh;
534 unsigned int mask, reg; 585 unsigned int mask, reg;
535 unsigned int codec; 586 unsigned int codec;
536 int err, use_src, changed; 587 int err, changed;
537 588
538 switch (chip->chip_idx) { 589 switch (chip->chip_idx) {
539 case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break; 590 case 0 : mask = PCXHR_SOURCE_AUDIO01_UER; codec = CS8420_01_CS; break;
@@ -542,13 +593,10 @@ static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
542 case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break; 593 case 3 : mask = PCXHR_SOURCE_AUDIO67_UER; codec = CS8420_67_CS; break;
543 default: return -EINVAL; 594 default: return -EINVAL;
544 } 595 }
545 reg = 0; /* audio source from analog plug */
546 use_src = 0; /* do not activate codec SRC */
547
548 if (chip->audio_capture_source != 0) { 596 if (chip->audio_capture_source != 0) {
549 reg = mask; /* audio source from digital plug */ 597 reg = mask; /* audio source from digital plug */
550 if (chip->audio_capture_source == 2) 598 } else {
551 use_src = 1; 599 reg = 0; /* audio source from analog plug */
552 } 600 }
553 /* set the input source */ 601 /* set the input source */
554 pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed); 602 pcxhr_write_io_num_reg_cont(chip->mgr, mask, reg, &changed);
@@ -560,29 +608,61 @@ static int pcxhr_set_audio_source(struct snd_pcxhr* chip)
560 if (err) 608 if (err)
561 return err; 609 return err;
562 } 610 }
563 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); /* set codec SRC on off */ 611 if (chip->mgr->board_aes_in_192k) {
564 rmh.cmd_len = 3; 612 int i;
565 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG; 613 unsigned int src_config = 0xC0;
566 rmh.cmd[1] = codec; 614 /* update all src configs with one call */
567 rmh.cmd[2] = (CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x54); 615 for (i = 0; (i < 4) && (i < chip->mgr->capture_chips); i++) {
568 err = pcxhr_send_msg(chip->mgr, &rmh); 616 if (chip->mgr->chip[i]->audio_capture_source == 2)
569 if(err) 617 src_config |= (1 << (3 - i));
570 return err; 618 }
571 rmh.cmd[2] = (CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) | (use_src ? 0x41 : 0x49); 619 /* set codec SRC on off */
572 err = pcxhr_send_msg(chip->mgr, &rmh); 620 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
621 rmh.cmd_len = 2;
622 rmh.cmd[0] |= IO_NUM_REG_CONFIG_SRC;
623 rmh.cmd[1] = src_config;
624 err = pcxhr_send_msg(chip->mgr, &rmh);
625 } else {
626 int use_src = 0;
627 if (chip->audio_capture_source == 2)
628 use_src = 1;
629 /* set codec SRC on off */
630 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
631 rmh.cmd_len = 3;
632 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
633 rmh.cmd[1] = codec;
634 rmh.cmd[2] = ((CS8420_DATA_FLOW_CTL & CHIP_SIG_AND_MAP_SPI) |
635 (use_src ? 0x41 : 0x54));
636 err = pcxhr_send_msg(chip->mgr, &rmh);
637 if (err)
638 return err;
639 rmh.cmd[2] = ((CS8420_CLOCK_SRC_CTL & CHIP_SIG_AND_MAP_SPI) |
640 (use_src ? 0x41 : 0x49));
641 err = pcxhr_send_msg(chip->mgr, &rmh);
642 }
573 return err; 643 return err;
574} 644}
575 645
576static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol, 646static int pcxhr_audio_src_info(struct snd_kcontrol *kcontrol,
577 struct snd_ctl_elem_info *uinfo) 647 struct snd_ctl_elem_info *uinfo)
578{ 648{
579 static char *texts[3] = {"Analog", "Digital", "Digi+SRC"}; 649 static const char *texts[5] = {
650 "Line", "Digital", "Digi+SRC", "Mic", "Line+Mic"
651 };
652 int i;
653 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
580 654
655 i = 2; /* no SRC, no Mic available */
656 if (chip->mgr->board_has_aes1) {
657 i = 3; /* SRC available */
658 if (chip->mgr->board_has_mic)
659 i = 5; /* Mic and MicroMix available */
660 }
581 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 661 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
582 uinfo->count = 1; 662 uinfo->count = 1;
583 uinfo->value.enumerated.items = 3; 663 uinfo->value.enumerated.items = i;
584 if (uinfo->value.enumerated.item > 2) 664 if (uinfo->value.enumerated.item > (i-1))
585 uinfo->value.enumerated.item = 2; 665 uinfo->value.enumerated.item = i-1;
586 strcpy(uinfo->value.enumerated.name, 666 strcpy(uinfo->value.enumerated.name,
587 texts[uinfo->value.enumerated.item]); 667 texts[uinfo->value.enumerated.item]);
588 return 0; 668 return 0;
@@ -601,13 +681,21 @@ static int pcxhr_audio_src_put(struct snd_kcontrol *kcontrol,
601{ 681{
602 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 682 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
603 int ret = 0; 683 int ret = 0;
604 684 int i = 2; /* no SRC, no Mic available */
605 if (ucontrol->value.enumerated.item[0] >= 3) 685 if (chip->mgr->board_has_aes1) {
686 i = 3; /* SRC available */
687 if (chip->mgr->board_has_mic)
688 i = 5; /* Mic and MicroMix available */
689 }
690 if (ucontrol->value.enumerated.item[0] >= i)
606 return -EINVAL; 691 return -EINVAL;
607 mutex_lock(&chip->mgr->mixer_mutex); 692 mutex_lock(&chip->mgr->mixer_mutex);
608 if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) { 693 if (chip->audio_capture_source != ucontrol->value.enumerated.item[0]) {
609 chip->audio_capture_source = ucontrol->value.enumerated.item[0]; 694 chip->audio_capture_source = ucontrol->value.enumerated.item[0];
610 pcxhr_set_audio_source(chip); 695 if (chip->mgr->is_hr_stereo)
696 hr222_set_audio_source(chip);
697 else
698 pcxhr_set_audio_source(chip);
611 ret = 1; 699 ret = 1;
612 } 700 }
613 mutex_unlock(&chip->mgr->mixer_mutex); 701 mutex_unlock(&chip->mgr->mixer_mutex);
@@ -626,25 +714,46 @@ static struct snd_kcontrol_new pcxhr_control_audio_src = {
626/* 714/*
627 * clock type selection 715 * clock type selection
628 * enum pcxhr_clock_type { 716 * enum pcxhr_clock_type {
629 * PCXHR_CLOCK_TYPE_INTERNAL = 0, 717 * PCXHR_CLOCK_TYPE_INTERNAL = 0,
630 * PCXHR_CLOCK_TYPE_WORD_CLOCK, 718 * PCXHR_CLOCK_TYPE_WORD_CLOCK,
631 * PCXHR_CLOCK_TYPE_AES_SYNC, 719 * PCXHR_CLOCK_TYPE_AES_SYNC,
632 * PCXHR_CLOCK_TYPE_AES_1, 720 * PCXHR_CLOCK_TYPE_AES_1,
633 * PCXHR_CLOCK_TYPE_AES_2, 721 * PCXHR_CLOCK_TYPE_AES_2,
634 * PCXHR_CLOCK_TYPE_AES_3, 722 * PCXHR_CLOCK_TYPE_AES_3,
635 * PCXHR_CLOCK_TYPE_AES_4, 723 * PCXHR_CLOCK_TYPE_AES_4,
636 * }; 724 * PCXHR_CLOCK_TYPE_MAX = PCXHR_CLOCK_TYPE_AES_4,
725 * HR22_CLOCK_TYPE_INTERNAL = PCXHR_CLOCK_TYPE_INTERNAL,
726 * HR22_CLOCK_TYPE_AES_SYNC,
727 * HR22_CLOCK_TYPE_AES_1,
728 * HR22_CLOCK_TYPE_MAX = HR22_CLOCK_TYPE_AES_1,
729 * };
637 */ 730 */
638 731
639static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol, 732static int pcxhr_clock_type_info(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_info *uinfo) 733 struct snd_ctl_elem_info *uinfo)
641{ 734{
642 static char *texts[7] = { 735 static const char *textsPCXHR[7] = {
643 "Internal", "WordClock", "AES Sync", "AES 1", "AES 2", "AES 3", "AES 4" 736 "Internal", "WordClock", "AES Sync",
737 "AES 1", "AES 2", "AES 3", "AES 4"
738 };
739 static const char *textsHR22[3] = {
740 "Internal", "AES Sync", "AES 1"
644 }; 741 };
742 const char **texts;
645 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); 743 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
646 int clock_items = 3 + mgr->capture_chips; 744 int clock_items = 2; /* at least Internal and AES Sync clock */
647 745 if (mgr->board_has_aes1) {
746 clock_items += mgr->capture_chips; /* add AES x */
747 if (!mgr->is_hr_stereo)
748 clock_items += 1; /* add word clock */
749 }
750 if (mgr->is_hr_stereo) {
751 texts = textsHR22;
752 snd_BUG_ON(clock_items > (HR22_CLOCK_TYPE_MAX+1));
753 } else {
754 texts = textsPCXHR;
755 snd_BUG_ON(clock_items > (PCXHR_CLOCK_TYPE_MAX+1));
756 }
648 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 757 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
649 uinfo->count = 1; 758 uinfo->count = 1;
650 uinfo->value.enumerated.items = clock_items; 759 uinfo->value.enumerated.items = clock_items;
@@ -667,9 +776,13 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
667 struct snd_ctl_elem_value *ucontrol) 776 struct snd_ctl_elem_value *ucontrol)
668{ 777{
669 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol); 778 struct pcxhr_mgr *mgr = snd_kcontrol_chip(kcontrol);
670 unsigned int clock_items = 3 + mgr->capture_chips;
671 int rate, ret = 0; 779 int rate, ret = 0;
672 780 unsigned int clock_items = 2; /* at least Internal and AES Sync clock */
781 if (mgr->board_has_aes1) {
782 clock_items += mgr->capture_chips; /* add AES x */
783 if (!mgr->is_hr_stereo)
784 clock_items += 1; /* add word clock */
785 }
673 if (ucontrol->value.enumerated.item[0] >= clock_items) 786 if (ucontrol->value.enumerated.item[0] >= clock_items)
674 return -EINVAL; 787 return -EINVAL;
675 mutex_lock(&mgr->mixer_mutex); 788 mutex_lock(&mgr->mixer_mutex);
@@ -677,7 +790,8 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
677 mutex_lock(&mgr->setup_mutex); 790 mutex_lock(&mgr->setup_mutex);
678 mgr->use_clock_type = ucontrol->value.enumerated.item[0]; 791 mgr->use_clock_type = ucontrol->value.enumerated.item[0];
679 if (mgr->use_clock_type) 792 if (mgr->use_clock_type)
680 pcxhr_get_external_clock(mgr, mgr->use_clock_type, &rate); 793 pcxhr_get_external_clock(mgr, mgr->use_clock_type,
794 &rate);
681 else 795 else
682 rate = mgr->sample_rate; 796 rate = mgr->sample_rate;
683 if (rate) { 797 if (rate) {
@@ -686,7 +800,7 @@ static int pcxhr_clock_type_put(struct snd_kcontrol *kcontrol,
686 mgr->sample_rate = rate; 800 mgr->sample_rate = rate;
687 } 801 }
688 mutex_unlock(&mgr->setup_mutex); 802 mutex_unlock(&mgr->setup_mutex);
689 ret = 1; /* return 1 even if the set was not done. ok ? */ 803 ret = 1; /* return 1 even if the set was not done. ok ? */
690 } 804 }
691 mutex_unlock(&mgr->mixer_mutex); 805 mutex_unlock(&mgr->mixer_mutex);
692 return ret; 806 return ret;
@@ -747,14 +861,16 @@ static struct snd_kcontrol_new pcxhr_control_clock_rate = {
747/* 861/*
748 * IEC958 status bits 862 * IEC958 status bits
749 */ 863 */
750static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 864static int pcxhr_iec958_info(struct snd_kcontrol *kcontrol,
865 struct snd_ctl_elem_info *uinfo)
751{ 866{
752 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 867 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
753 uinfo->count = 1; 868 uinfo->count = 1;
754 return 0; 869 return 0;
755} 870}
756 871
757static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char* aes_bits) 872static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip,
873 int aes_idx, unsigned char *aes_bits)
758{ 874{
759 int i, err; 875 int i, err;
760 unsigned char temp; 876 unsigned char temp;
@@ -763,39 +879,61 @@ static int pcxhr_iec958_capture_byte(struct snd_pcxhr *chip, int aes_idx, unsign
763 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ); 879 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_READ);
764 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG; 880 rmh.cmd[0] |= IO_NUM_UER_CHIP_REG;
765 switch (chip->chip_idx) { 881 switch (chip->chip_idx) {
766 case 0: rmh.cmd[1] = CS8420_01_CS; break; /* use CS8416_01_CS for AES SYNC plug */ 882 /* instead of CS8420_01_CS use CS8416_01_CS for AES SYNC plug */
883 case 0: rmh.cmd[1] = CS8420_01_CS; break;
767 case 1: rmh.cmd[1] = CS8420_23_CS; break; 884 case 1: rmh.cmd[1] = CS8420_23_CS; break;
768 case 2: rmh.cmd[1] = CS8420_45_CS; break; 885 case 2: rmh.cmd[1] = CS8420_45_CS; break;
769 case 3: rmh.cmd[1] = CS8420_67_CS; break; 886 case 3: rmh.cmd[1] = CS8420_67_CS; break;
770 default: return -EINVAL; 887 default: return -EINVAL;
771 } 888 }
772 switch (aes_idx) { 889 if (chip->mgr->board_aes_in_192k) {
773 case 0: rmh.cmd[2] = CS8420_CSB0; break; /* use CS8416_CSBx for AES SYNC plug */ 890 switch (aes_idx) {
774 case 1: rmh.cmd[2] = CS8420_CSB1; break; 891 case 0: rmh.cmd[2] = CS8416_CSB0; break;
775 case 2: rmh.cmd[2] = CS8420_CSB2; break; 892 case 1: rmh.cmd[2] = CS8416_CSB1; break;
776 case 3: rmh.cmd[2] = CS8420_CSB3; break; 893 case 2: rmh.cmd[2] = CS8416_CSB2; break;
777 case 4: rmh.cmd[2] = CS8420_CSB4; break; 894 case 3: rmh.cmd[2] = CS8416_CSB3; break;
778 default: return -EINVAL; 895 case 4: rmh.cmd[2] = CS8416_CSB4; break;
896 default: return -EINVAL;
897 }
898 } else {
899 switch (aes_idx) {
900 /* instead of CS8420_CSB0 use CS8416_CSBx for AES SYNC plug */
901 case 0: rmh.cmd[2] = CS8420_CSB0; break;
902 case 1: rmh.cmd[2] = CS8420_CSB1; break;
903 case 2: rmh.cmd[2] = CS8420_CSB2; break;
904 case 3: rmh.cmd[2] = CS8420_CSB3; break;
905 case 4: rmh.cmd[2] = CS8420_CSB4; break;
906 default: return -EINVAL;
907 }
779 } 908 }
780 rmh.cmd[1] &= 0x0fffff; /* size and code the chip id for the fpga */ 909 /* size and code the chip id for the fpga */
781 rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI; /* chip signature + map for spi read */ 910 rmh.cmd[1] &= 0x0fffff;
911 /* chip signature + map for spi read */
912 rmh.cmd[2] &= CHIP_SIG_AND_MAP_SPI;
782 rmh.cmd_len = 3; 913 rmh.cmd_len = 3;
783 err = pcxhr_send_msg(chip->mgr, &rmh); 914 err = pcxhr_send_msg(chip->mgr, &rmh);
784 if (err) 915 if (err)
785 return err; 916 return err;
786 temp = 0; 917
787 for (i = 0; i < 8; i++) { 918 if (chip->mgr->board_aes_in_192k) {
788 /* attention : reversed bit order (not with CS8416_01_CS) */ 919 temp = (unsigned char)rmh.stat[1];
789 temp <<= 1; 920 } else {
790 if (rmh.stat[1] & (1 << i)) 921 temp = 0;
791 temp |= 1; 922 /* reversed bit order (not with CS8416_01_CS) */
923 for (i = 0; i < 8; i++) {
924 temp <<= 1;
925 if (rmh.stat[1] & (1 << i))
926 temp |= 1;
927 }
792 } 928 }
793 snd_printdd("read iec958 AES %d byte %d = 0x%x\n", chip->chip_idx, aes_idx, temp); 929 snd_printdd("read iec958 AES %d byte %d = 0x%x\n",
930 chip->chip_idx, aes_idx, temp);
794 *aes_bits = temp; 931 *aes_bits = temp;
795 return 0; 932 return 0;
796} 933}
797 934
798static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 935static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol,
936 struct snd_ctl_elem_value *ucontrol)
799{ 937{
800 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol); 938 struct snd_pcxhr *chip = snd_kcontrol_chip(kcontrol);
801 unsigned char aes_bits; 939 unsigned char aes_bits;
@@ -806,7 +944,12 @@ static int pcxhr_iec958_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
806 if (kcontrol->private_value == 0) /* playback */ 944 if (kcontrol->private_value == 0) /* playback */
807 aes_bits = chip->aes_bits[i]; 945 aes_bits = chip->aes_bits[i];
808 else { /* capture */ 946 else { /* capture */
809 err = pcxhr_iec958_capture_byte(chip, i, &aes_bits); 947 if (chip->mgr->is_hr_stereo)
948 err = hr222_iec958_capture_byte(chip, i,
949 &aes_bits);
950 else
951 err = pcxhr_iec958_capture_byte(chip, i,
952 &aes_bits);
810 if (err) 953 if (err)
811 break; 954 break;
812 } 955 }
@@ -825,7 +968,8 @@ static int pcxhr_iec958_mask_get(struct snd_kcontrol *kcontrol,
825 return 0; 968 return 0;
826} 969}
827 970
828static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx, unsigned char aes_bits) 971static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip,
972 int aes_idx, unsigned char aes_bits)
829{ 973{
830 int i, err, cmd; 974 int i, err, cmd;
831 unsigned char new_bits = aes_bits; 975 unsigned char new_bits = aes_bits;
@@ -834,12 +978,12 @@ static int pcxhr_iec958_update_byte(struct snd_pcxhr *chip, int aes_idx, unsigne
834 978
835 for (i = 0; i < 8; i++) { 979 for (i = 0; i < 8; i++) {
836 if ((old_bits & 0x01) != (new_bits & 0x01)) { 980 if ((old_bits & 0x01) != (new_bits & 0x01)) {
837 cmd = chip->chip_idx & 0x03; /* chip index 0..3 */ 981 cmd = chip->chip_idx & 0x03; /* chip index 0..3 */
838 if(chip->chip_idx > 3) 982 if (chip->chip_idx > 3)
839 /* new bit used if chip_idx>3 (PCX1222HR) */ 983 /* new bit used if chip_idx>3 (PCX1222HR) */
840 cmd |= 1 << 22; 984 cmd |= 1 << 22;
841 cmd |= ((aes_idx << 3) + i) << 2; /* add bit offset */ 985 cmd |= ((aes_idx << 3) + i) << 2; /* add bit offset */
842 cmd |= (new_bits & 0x01) << 23; /* add bit value */ 986 cmd |= (new_bits & 0x01) << 23; /* add bit value */
843 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE); 987 pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
844 rmh.cmd[0] |= IO_NUM_REG_CUER; 988 rmh.cmd[0] |= IO_NUM_REG_CUER;
845 rmh.cmd[1] = cmd; 989 rmh.cmd[1] = cmd;
@@ -867,7 +1011,12 @@ static int pcxhr_iec958_put(struct snd_kcontrol *kcontrol,
867 mutex_lock(&chip->mgr->mixer_mutex); 1011 mutex_lock(&chip->mgr->mixer_mutex);
868 for (i = 0; i < 5; i++) { 1012 for (i = 0; i < 5; i++) {
869 if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) { 1013 if (ucontrol->value.iec958.status[i] != chip->aes_bits[i]) {
870 pcxhr_iec958_update_byte(chip, i, ucontrol->value.iec958.status[i]); 1014 if (chip->mgr->is_hr_stereo)
1015 hr222_iec958_update_byte(chip, i,
1016 ucontrol->value.iec958.status[i]);
1017 else
1018 pcxhr_iec958_update_byte(chip, i,
1019 ucontrol->value.iec958.status[i]);
871 changed = 1; 1020 changed = 1;
872 } 1021 }
873 } 1022 }
@@ -917,29 +1066,53 @@ static void pcxhr_init_audio_levels(struct snd_pcxhr *chip)
917 /* at boot time the digital volumes are unmuted 0dB */ 1066 /* at boot time the digital volumes are unmuted 0dB */
918 for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) { 1067 for (j = 0; j < PCXHR_PLAYBACK_STREAMS; j++) {
919 chip->digital_playback_active[j][i] = 1; 1068 chip->digital_playback_active[j][i] = 1;
920 chip->digital_playback_volume[j][i] = PCXHR_DIGITAL_ZERO_LEVEL; 1069 chip->digital_playback_volume[j][i] =
1070 PCXHR_DIGITAL_ZERO_LEVEL;
921 } 1071 }
922 /* after boot, only two bits are set on the uer interface */ 1072 /* after boot, only two bits are set on the uer
923 chip->aes_bits[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_PRO_FS_48000; 1073 * interface
924/* only for test purpose, remove later */ 1074 */
1075 chip->aes_bits[0] = (IEC958_AES0_PROFESSIONAL |
1076 IEC958_AES0_PRO_FS_48000);
925#ifdef CONFIG_SND_DEBUG 1077#ifdef CONFIG_SND_DEBUG
926 /* analog volumes for playback (is LEVEL_MIN after boot) */ 1078 /* analog volumes for playback
1079 * (is LEVEL_MIN after boot)
1080 */
927 chip->analog_playback_active[i] = 1; 1081 chip->analog_playback_active[i] = 1;
928 chip->analog_playback_volume[i] = PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL; 1082 if (chip->mgr->is_hr_stereo)
929 pcxhr_update_analog_audio_level(chip, 0, i); 1083 chip->analog_playback_volume[i] =
1084 HR222_LINE_PLAYBACK_ZERO_LEVEL;
1085 else {
1086 chip->analog_playback_volume[i] =
1087 PCXHR_LINE_PLAYBACK_ZERO_LEVEL;
1088 pcxhr_update_analog_audio_level(chip, 0, i);
1089 }
930#endif 1090#endif
931/* test end */ 1091 /* stereo cards need to be initialised after boot */
1092 if (chip->mgr->is_hr_stereo)
1093 hr222_update_analog_audio_level(chip, 0, i);
932 } 1094 }
933 if (chip->nb_streams_capt) { 1095 if (chip->nb_streams_capt) {
934 /* at boot time the digital volumes are unmuted 0dB */ 1096 /* at boot time the digital volumes are unmuted 0dB */
935 chip->digital_capture_volume[i] = PCXHR_DIGITAL_ZERO_LEVEL; 1097 chip->digital_capture_volume[i] =
936/* only for test purpose, remove later */ 1098 PCXHR_DIGITAL_ZERO_LEVEL;
1099 chip->analog_capture_active = 1;
937#ifdef CONFIG_SND_DEBUG 1100#ifdef CONFIG_SND_DEBUG
938 /* analog volumes for playback (is LEVEL_MIN after boot) */ 1101 /* analog volumes for playback
939 chip->analog_capture_volume[i] = PCXHR_ANALOG_CAPTURE_ZERO_LEVEL; 1102 * (is LEVEL_MIN after boot)
940 pcxhr_update_analog_audio_level(chip, 1, i); 1103 */
1104 if (chip->mgr->is_hr_stereo)
1105 chip->analog_capture_volume[i] =
1106 HR222_LINE_CAPTURE_ZERO_LEVEL;
1107 else {
1108 chip->analog_capture_volume[i] =
1109 PCXHR_LINE_CAPTURE_ZERO_LEVEL;
1110 pcxhr_update_analog_audio_level(chip, 1, i);
1111 }
941#endif 1112#endif
942/* test end */ 1113 /* stereo cards need to be initialised after boot */
1114 if (chip->mgr->is_hr_stereo)
1115 hr222_update_analog_audio_level(chip, 1, i);
943 } 1116 }
944 } 1117 }
945 1118
@@ -963,90 +1136,125 @@ int pcxhr_create_mixer(struct pcxhr_mgr *mgr)
963 temp = pcxhr_control_analog_level; 1136 temp = pcxhr_control_analog_level;
964 temp.name = "Master Playback Volume"; 1137 temp.name = "Master Playback Volume";
965 temp.private_value = 0; /* playback */ 1138 temp.private_value = 0; /* playback */
966 temp.tlv.p = db_scale_analog_playback; 1139 if (mgr->is_hr_stereo)
967 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1140 temp.tlv.p = db_scale_a_hr222_playback;
1141 else
1142 temp.tlv.p = db_scale_analog_playback;
1143 err = snd_ctl_add(chip->card,
1144 snd_ctl_new1(&temp, chip));
1145 if (err < 0)
968 return err; 1146 return err;
1147
969 /* output mute controls */ 1148 /* output mute controls */
970 if ((err = snd_ctl_add(chip->card, 1149 err = snd_ctl_add(chip->card,
971 snd_ctl_new1(&pcxhr_control_output_switch, 1150 snd_ctl_new1(&pcxhr_control_output_switch,
972 chip))) < 0) 1151 chip));
1152 if (err < 0)
973 return err; 1153 return err;
974 1154
975 temp = snd_pcxhr_pcm_vol; 1155 temp = snd_pcxhr_pcm_vol;
976 temp.name = "PCM Playback Volume"; 1156 temp.name = "PCM Playback Volume";
977 temp.count = PCXHR_PLAYBACK_STREAMS; 1157 temp.count = PCXHR_PLAYBACK_STREAMS;
978 temp.private_value = 0; /* playback */ 1158 temp.private_value = 0; /* playback */
979 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1159 err = snd_ctl_add(chip->card,
1160 snd_ctl_new1(&temp, chip));
1161 if (err < 0)
980 return err; 1162 return err;
981 1163
982 if ((err = snd_ctl_add(chip->card, 1164 err = snd_ctl_add(chip->card,
983 snd_ctl_new1(&pcxhr_control_pcm_switch, 1165 snd_ctl_new1(&pcxhr_control_pcm_switch, chip));
984 chip))) < 0) 1166 if (err < 0)
985 return err; 1167 return err;
986 1168
987 /* IEC958 controls */ 1169 /* IEC958 controls */
988 if ((err = snd_ctl_add(chip->card, 1170 err = snd_ctl_add(chip->card,
989 snd_ctl_new1(&pcxhr_control_playback_iec958_mask, 1171 snd_ctl_new1(&pcxhr_control_playback_iec958_mask,
990 chip))) < 0) 1172 chip));
1173 if (err < 0)
991 return err; 1174 return err;
992 if ((err = snd_ctl_add(chip->card, 1175
993 snd_ctl_new1(&pcxhr_control_playback_iec958, 1176 err = snd_ctl_add(chip->card,
994 chip))) < 0) 1177 snd_ctl_new1(&pcxhr_control_playback_iec958,
1178 chip));
1179 if (err < 0)
995 return err; 1180 return err;
996 } 1181 }
997 if (chip->nb_streams_capt) { 1182 if (chip->nb_streams_capt) {
998 /* analog input level control only on first two chips !*/ 1183 /* analog input level control */
999 temp = pcxhr_control_analog_level; 1184 temp = pcxhr_control_analog_level;
1000 temp.name = "Master Capture Volume"; 1185 temp.name = "Line Capture Volume";
1001 temp.private_value = 1; /* capture */ 1186 temp.private_value = 1; /* capture */
1002 temp.tlv.p = db_scale_analog_capture; 1187 if (mgr->is_hr_stereo)
1003 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1188 temp.tlv.p = db_scale_a_hr222_capture;
1189 else
1190 temp.tlv.p = db_scale_analog_capture;
1191
1192 err = snd_ctl_add(chip->card,
1193 snd_ctl_new1(&temp, chip));
1194 if (err < 0)
1004 return err; 1195 return err;
1005 1196
1006 temp = snd_pcxhr_pcm_vol; 1197 temp = snd_pcxhr_pcm_vol;
1007 temp.name = "PCM Capture Volume"; 1198 temp.name = "PCM Capture Volume";
1008 temp.count = 1; 1199 temp.count = 1;
1009 temp.private_value = 1; /* capture */ 1200 temp.private_value = 1; /* capture */
1010 if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&temp, chip))) < 0) 1201
1202 err = snd_ctl_add(chip->card,
1203 snd_ctl_new1(&temp, chip));
1204 if (err < 0)
1011 return err; 1205 return err;
1206
1012 /* Audio source */ 1207 /* Audio source */
1013 if ((err = snd_ctl_add(chip->card, 1208 err = snd_ctl_add(chip->card,
1014 snd_ctl_new1(&pcxhr_control_audio_src, 1209 snd_ctl_new1(&pcxhr_control_audio_src, chip));
1015 chip))) < 0) 1210 if (err < 0)
1016 return err; 1211 return err;
1212
1017 /* IEC958 controls */ 1213 /* IEC958 controls */
1018 if ((err = snd_ctl_add(chip->card, 1214 err = snd_ctl_add(chip->card,
1019 snd_ctl_new1(&pcxhr_control_capture_iec958_mask, 1215 snd_ctl_new1(&pcxhr_control_capture_iec958_mask,
1020 chip))) < 0) 1216 chip));
1217 if (err < 0)
1021 return err; 1218 return err;
1022 if ((err = snd_ctl_add(chip->card, 1219
1023 snd_ctl_new1(&pcxhr_control_capture_iec958, 1220 err = snd_ctl_add(chip->card,
1024 chip))) < 0) 1221 snd_ctl_new1(&pcxhr_control_capture_iec958,
1222 chip));
1223 if (err < 0)
1025 return err; 1224 return err;
1225
1226 if (mgr->is_hr_stereo) {
1227 err = hr222_add_mic_controls(chip);
1228 if (err < 0)
1229 return err;
1230 }
1026 } 1231 }
1027 /* monitoring only if playback and capture device available */ 1232 /* monitoring only if playback and capture device available */
1028 if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) { 1233 if (chip->nb_streams_capt > 0 && chip->nb_streams_play > 0) {
1029 /* monitoring */ 1234 /* monitoring */
1030 if ((err = snd_ctl_add(chip->card, 1235 err = snd_ctl_add(chip->card,
1031 snd_ctl_new1(&pcxhr_control_monitor_vol, 1236 snd_ctl_new1(&pcxhr_control_monitor_vol, chip));
1032 chip))) < 0) 1237 if (err < 0)
1033 return err; 1238 return err;
1034 if ((err = snd_ctl_add(chip->card, 1239
1035 snd_ctl_new1(&pcxhr_control_monitor_sw, 1240 err = snd_ctl_add(chip->card,
1036 chip))) < 0) 1241 snd_ctl_new1(&pcxhr_control_monitor_sw, chip));
1242 if (err < 0)
1037 return err; 1243 return err;
1038 } 1244 }
1039 1245
1040 if (i == 0) { 1246 if (i == 0) {
1041 /* clock mode only one control per pcxhr */ 1247 /* clock mode only one control per pcxhr */
1042 if ((err = snd_ctl_add(chip->card, 1248 err = snd_ctl_add(chip->card,
1043 snd_ctl_new1(&pcxhr_control_clock_type, 1249 snd_ctl_new1(&pcxhr_control_clock_type, mgr));
1044 mgr))) < 0) 1250 if (err < 0)
1045 return err; 1251 return err;
1046 /* non standard control used to scan the external clock presence/frequencies */ 1252 /* non standard control used to scan
1047 if ((err = snd_ctl_add(chip->card, 1253 * the external clock presence/frequencies
1048 snd_ctl_new1(&pcxhr_control_clock_rate, 1254 */
1049 mgr))) < 0) 1255 err = snd_ctl_add(chip->card,
1256 snd_ctl_new1(&pcxhr_control_clock_rate, mgr));
1257 if (err < 0)
1050 return err; 1258 return err;
1051 } 1259 }
1052 1260
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index e9f0706ed3e4..3caacfb9d8e0 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -172,7 +172,7 @@ MODULE_PARM_DESC(opl3_port, "OPL3 port # for Riptide driver.");
172 172
173#define MAX_WRITE_RETRY 10 /* cmd interface limits */ 173#define MAX_WRITE_RETRY 10 /* cmd interface limits */
174#define MAX_ERROR_COUNT 10 174#define MAX_ERROR_COUNT 10
175#define CMDIF_TIMEOUT 500000 175#define CMDIF_TIMEOUT 50000
176#define RESET_TRIES 5 176#define RESET_TRIES 5
177 177
178#define READ_PORT_ULONG(p) inl((unsigned long)&(p)) 178#define READ_PORT_ULONG(p) inl((unsigned long)&(p))
@@ -1754,7 +1754,7 @@ snd_riptide_interrupt(int irq, void *dev_id)
1754 if (IS_EOBIRQ(cif->hwport) || IS_EOSIRQ(cif->hwport) || 1754 if (IS_EOBIRQ(cif->hwport) || IS_EOSIRQ(cif->hwport) ||
1755 IS_EOCIRQ(cif->hwport)) { 1755 IS_EOCIRQ(cif->hwport)) {
1756 chip->handled_irqs++; 1756 chip->handled_irqs++;
1757 tasklet_hi_schedule(&chip->riptide_tq); 1757 tasklet_schedule(&chip->riptide_tq);
1758 } 1758 }
1759 if (chip->rmidi && IS_MPUIRQ(cif->hwport)) { 1759 if (chip->rmidi && IS_MPUIRQ(cif->hwport)) {
1760 chip->handled_irqs++; 1760 chip->handled_irqs++;
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 736246f98acc..44d0c15e2b71 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -1452,7 +1452,7 @@ static int snd_hdsp_create_midi (struct snd_card *card, struct hdsp *hdsp, int i
1452 if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0) 1452 if (snd_rawmidi_new (card, buf, id, 1, 1, &hdsp->midi[id].rmidi) < 0)
1453 return -1; 1453 return -1;
1454 1454
1455 sprintf (hdsp->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1); 1455 sprintf(hdsp->midi[id].rmidi->name, "HDSP MIDI %d", id+1);
1456 hdsp->midi[id].rmidi->private_data = &hdsp->midi[id]; 1456 hdsp->midi[id].rmidi->private_data = &hdsp->midi[id];
1457 1457
1458 snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output); 1458 snd_rawmidi_set_ops (hdsp->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, &snd_hdsp_midi_output);
@@ -3750,7 +3750,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id)
3750 } 3750 }
3751 } 3751 }
3752 if (hdsp->use_midi_tasklet && schedule) 3752 if (hdsp->use_midi_tasklet && schedule)
3753 tasklet_hi_schedule(&hdsp->midi_tasklet); 3753 tasklet_schedule(&hdsp->midi_tasklet);
3754 return IRQ_HANDLED; 3754 return IRQ_HANDLED;
3755} 3755}
3756 3756
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 98762f909d64..71231cf1b2b0 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -1293,7 +1293,7 @@ static int __devinit snd_hdspm_create_midi (struct snd_card *card,
1293 if (err < 0) 1293 if (err < 0)
1294 return err; 1294 return err;
1295 1295
1296 sprintf (hdspm->midi[id].rmidi->name, "%s MIDI %d", card->id, id+1); 1296 sprintf(hdspm->midi[id].rmidi->name, "HDSPM MIDI %d", id+1);
1297 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id]; 1297 hdspm->midi[id].rmidi->private_data = &hdspm->midi[id];
1298 1298
1299 snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT, 1299 snd_rawmidi_set_ops(hdspm->midi[id].rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
@@ -3476,7 +3476,7 @@ static irqreturn_t snd_hdspm_interrupt(int irq, void *dev_id)
3476 schedule = 1; 3476 schedule = 1;
3477 } 3477 }
3478 if (schedule) 3478 if (schedule)
3479 tasklet_hi_schedule(&hdspm->midi_tasklet); 3479 tasklet_schedule(&hdspm->midi_tasklet);
3480 return IRQ_HANDLED; 3480 return IRQ_HANDLED;
3481} 3481}
3482 3482
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c b/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
index fa4b11398b1f..ea903c8e90dd 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_irq.c
@@ -41,7 +41,7 @@ irqreturn_t pdacf_interrupt(int irq, void *dev)
41 if (stat & PDAUDIOCF_IRQOVR) /* should never happen */ 41 if (stat & PDAUDIOCF_IRQOVR) /* should never happen */
42 snd_printk(KERN_ERR "PDAUDIOCF SRAM buffer overrun detected!\n"); 42 snd_printk(KERN_ERR "PDAUDIOCF SRAM buffer overrun detected!\n");
43 if (chip->pcm_substream) 43 if (chip->pcm_substream)
44 tasklet_hi_schedule(&chip->tq); 44 tasklet_schedule(&chip->tq);
45 if (!(stat & PDAUDIOCF_IRQAKM)) 45 if (!(stat & PDAUDIOCF_IRQAKM))
46 stat |= PDAUDIOCF_IRQAKM; /* check rate */ 46 stat |= PDAUDIOCF_IRQAKM; /* check rate */
47 } 47 }
diff --git a/sound/ppc/pmac.c b/sound/ppc/pmac.c
index a38c0c790d2b..af76ee862d27 100644
--- a/sound/ppc/pmac.c
+++ b/sound/ppc/pmac.c
@@ -1033,7 +1033,7 @@ static int __init snd_pmac_detect(struct snd_pmac *chip)
1033 } 1033 }
1034 if (of_device_is_compatible(sound, "tumbler")) { 1034 if (of_device_is_compatible(sound, "tumbler")) {
1035 chip->model = PMAC_TUMBLER; 1035 chip->model = PMAC_TUMBLER;
1036 chip->can_capture = 0; /* no capture */ 1036 chip->can_capture = machine_is_compatible("PowerMac4,2");
1037 chip->can_duplex = 0; 1037 chip->can_duplex = 0;
1038 // chip->can_byte_swap = 0; /* FIXME: check this */ 1038 // chip->can_byte_swap = 0; /* FIXME: check this */
1039 chip->num_freqs = ARRAY_SIZE(tumbler_freqs); 1039 chip->num_freqs = ARRAY_SIZE(tumbler_freqs);
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c
index f746e15b8481..3eb223385416 100644
--- a/sound/ppc/tumbler.c
+++ b/sound/ppc/tumbler.c
@@ -875,7 +875,8 @@ static struct snd_kcontrol_new snapper_mixers[] __initdata = {
875 .put = tumbler_put_master_switch 875 .put = tumbler_put_master_switch
876 }, 876 },
877 DEFINE_SNAPPER_MIX("PCM Playback Volume", 0, VOL_IDX_PCM), 877 DEFINE_SNAPPER_MIX("PCM Playback Volume", 0, VOL_IDX_PCM),
878 DEFINE_SNAPPER_MIX("PCM Playback Volume", 1, VOL_IDX_PCM2), 878 /* Alternative PCM is assigned to Mic analog loopback on iBook G4 */
879 DEFINE_SNAPPER_MIX("Mic Playback Volume", 0, VOL_IDX_PCM2),
879 DEFINE_SNAPPER_MIX("Monitor Mix Volume", 0, VOL_IDX_ADC), 880 DEFINE_SNAPPER_MIX("Monitor Mix Volume", 0, VOL_IDX_ADC),
880 DEFINE_SNAPPER_MONO("Tone Control - Bass", bass), 881 DEFINE_SNAPPER_MONO("Tone Control - Bass", bass),
881 DEFINE_SNAPPER_MONO("Tone Control - Treble", treble), 882 DEFINE_SNAPPER_MONO("Tone Control - Treble", treble),
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 4dfda6674bec..ef025c66cc66 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -22,17 +22,16 @@ if SND_SOC
22config SND_SOC_AC97_BUS 22config SND_SOC_AC97_BUS
23 bool 23 bool
24 24
25# All the supported Soc's 25# All the supported SoCs
26source "sound/soc/at32/Kconfig" 26source "sound/soc/atmel/Kconfig"
27source "sound/soc/at91/Kconfig"
28source "sound/soc/au1x/Kconfig" 27source "sound/soc/au1x/Kconfig"
28source "sound/soc/blackfin/Kconfig"
29source "sound/soc/davinci/Kconfig"
30source "sound/soc/fsl/Kconfig"
31source "sound/soc/omap/Kconfig"
29source "sound/soc/pxa/Kconfig" 32source "sound/soc/pxa/Kconfig"
30source "sound/soc/s3c24xx/Kconfig" 33source "sound/soc/s3c24xx/Kconfig"
31source "sound/soc/sh/Kconfig" 34source "sound/soc/sh/Kconfig"
32source "sound/soc/fsl/Kconfig"
33source "sound/soc/davinci/Kconfig"
34source "sound/soc/omap/Kconfig"
35source "sound/soc/blackfin/Kconfig"
36 35
37# Supported codecs 36# Supported codecs
38source "sound/soc/codecs/Kconfig" 37source "sound/soc/codecs/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index d849349f2c66..86a9b1f5b0f3 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -1,5 +1,13 @@
1snd-soc-core-objs := soc-core.o soc-dapm.o 1snd-soc-core-objs := soc-core.o soc-dapm.o
2 2
3obj-$(CONFIG_SND_SOC) += snd-soc-core.o 3obj-$(CONFIG_SND_SOC) += snd-soc-core.o
4obj-$(CONFIG_SND_SOC) += codecs/ at32/ at91/ pxa/ s3c24xx/ sh/ fsl/ davinci/ 4obj-$(CONFIG_SND_SOC) += codecs/
5obj-$(CONFIG_SND_SOC) += omap/ au1x/ blackfin/ 5obj-$(CONFIG_SND_SOC) += atmel/
6obj-$(CONFIG_SND_SOC) += au1x/
7obj-$(CONFIG_SND_SOC) += blackfin/
8obj-$(CONFIG_SND_SOC) += davinci/
9obj-$(CONFIG_SND_SOC) += fsl/
10obj-$(CONFIG_SND_SOC) += omap/
11obj-$(CONFIG_SND_SOC) += pxa/
12obj-$(CONFIG_SND_SOC) += s3c24xx/
13obj-$(CONFIG_SND_SOC) += sh/
diff --git a/sound/soc/at32/Kconfig b/sound/soc/at32/Kconfig
deleted file mode 100644
index b0765e86c085..000000000000
--- a/sound/soc/at32/Kconfig
+++ /dev/null
@@ -1,34 +0,0 @@
1config SND_AT32_SOC
2 tristate "SoC Audio for the Atmel AT32 System-on-a-Chip"
3 depends on AVR32 && SND_SOC
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the AT32 SSC interface. You will also need to
7 to select the audio interfaces to support below.
8
9
10config SND_AT32_SOC_SSC
11 tristate
12
13
14
15config SND_AT32_SOC_PLAYPAQ
16 tristate "SoC Audio support for PlayPaq with WM8510"
17 depends on SND_AT32_SOC && BOARD_PLAYPAQ
18 select SND_AT32_SOC_SSC
19 select SND_SOC_WM8510
20 help
21 Say Y or M here if you want to add support for SoC audio
22 on the LRS PlayPaq.
23
24
25
26config SND_AT32_SOC_PLAYPAQ_SLAVE
27 bool "Run CODEC on PlayPaq in slave mode"
28 depends on SND_AT32_SOC_PLAYPAQ
29 default n
30 help
31 Say Y if you want to run with the AT32 SSC generating the BCLK
32 and FRAME signals on the PlayPaq. Unless you want to play
33 with the AT32 as the SSC master, you probably want to say N here,
34 as this will give you better sound quality.
diff --git a/sound/soc/at32/Makefile b/sound/soc/at32/Makefile
deleted file mode 100644
index c03e55ececeb..000000000000
--- a/sound/soc/at32/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
1# AT32 Platform Support
2snd-soc-at32-objs := at32-pcm.o
3snd-soc-at32-ssc-objs := at32-ssc.o
4
5obj-$(CONFIG_SND_AT32_SOC) += snd-soc-at32.o
6obj-$(CONFIG_SND_AT32_SOC_SSC) += snd-soc-at32-ssc.o
7
8# AT32 Machine Support
9snd-soc-playpaq-objs := playpaq_wm8510.o
10
11obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
diff --git a/sound/soc/at32/at32-pcm.c b/sound/soc/at32/at32-pcm.c
deleted file mode 100644
index c83584f989a9..000000000000
--- a/sound/soc/at32/at32-pcm.c
+++ /dev/null
@@ -1,492 +0,0 @@
1/* sound/soc/at32/at32-pcm.c
2 * ASoC PCM interface for Atmel AT32 SoC
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * Note that this is basically a port of the sound/soc/at91-pcm.c to
12 * the AVR32 kernel. Thanks to Frank Mandarino for that code.
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/dma-mapping.h>
20#include <linux/atmel_pdc.h>
21
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26
27#include "at32-pcm.h"
28
29
30
31/*--------------------------------------------------------------------------*\
32 * Hardware definition
33\*--------------------------------------------------------------------------*/
34/* TODO: These values were taken from the AT91 platform driver, check
35 * them against real values for AT32
36 */
37static const struct snd_pcm_hardware at32_pcm_hardware = {
38 .info = (SNDRV_PCM_INFO_MMAP |
39 SNDRV_PCM_INFO_MMAP_VALID |
40 SNDRV_PCM_INFO_INTERLEAVED |
41 SNDRV_PCM_INFO_BLOCK_TRANSFER |
42 SNDRV_PCM_INFO_PAUSE),
43
44 .formats = SNDRV_PCM_FMTBIT_S16,
45 .period_bytes_min = 32,
46 .period_bytes_max = 8192, /* 512 frames * 16 bytes / frame */
47 .periods_min = 2,
48 .periods_max = 1024,
49 .buffer_bytes_max = 32 * 1024,
50};
51
52
53
54/*--------------------------------------------------------------------------*\
55 * Data types
56\*--------------------------------------------------------------------------*/
57struct at32_runtime_data {
58 struct at32_pcm_dma_params *params;
59 dma_addr_t dma_buffer; /* physical address of DMA buffer */
60 dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
61 size_t period_size;
62
63 dma_addr_t period_ptr; /* physical address of next period */
64 int periods; /* period index of period_ptr */
65
66 /* Save PDC registers (for power management) */
67 u32 pdc_xpr_save;
68 u32 pdc_xcr_save;
69 u32 pdc_xnpr_save;
70 u32 pdc_xncr_save;
71};
72
73
74
75/*--------------------------------------------------------------------------*\
76 * Helper functions
77\*--------------------------------------------------------------------------*/
78static int at32_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
79{
80 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
81 struct snd_dma_buffer *dmabuf = &substream->dma_buffer;
82 size_t size = at32_pcm_hardware.buffer_bytes_max;
83
84 dmabuf->dev.type = SNDRV_DMA_TYPE_DEV;
85 dmabuf->dev.dev = pcm->card->dev;
86 dmabuf->private_data = NULL;
87 dmabuf->area = dma_alloc_coherent(pcm->card->dev, size,
88 &dmabuf->addr, GFP_KERNEL);
89 pr_debug("at32_pcm: preallocate_dma_buffer: "
90 "area=%p, addr=%p, size=%ld\n",
91 (void *)dmabuf->area, (void *)dmabuf->addr, size);
92
93 if (!dmabuf->area)
94 return -ENOMEM;
95
96 dmabuf->bytes = size;
97 return 0;
98}
99
100
101
102/*--------------------------------------------------------------------------*\
103 * ISR
104\*--------------------------------------------------------------------------*/
105static void at32_pcm_dma_irq(u32 ssc_sr, struct snd_pcm_substream *substream)
106{
107 struct snd_pcm_runtime *rtd = substream->runtime;
108 struct at32_runtime_data *prtd = rtd->private_data;
109 struct at32_pcm_dma_params *params = prtd->params;
110 static int count;
111
112 count++;
113 if (ssc_sr & params->mask->ssc_endbuf) {
114 pr_warning("at32-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
115 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
116 "underrun" : "overrun", params->name, ssc_sr, count);
117
118 /* re-start the PDC */
119 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
120 params->mask->pdc_disable);
121 prtd->period_ptr += prtd->period_size;
122 if (prtd->period_ptr >= prtd->dma_buffer_end)
123 prtd->period_ptr = prtd->dma_buffer;
124
125
126 ssc_writex(params->ssc->regs, params->pdc->xpr,
127 prtd->period_ptr);
128 ssc_writex(params->ssc->regs, params->pdc->xcr,
129 prtd->period_size / params->pdc_xfer_size);
130 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
131 params->mask->pdc_enable);
132 }
133
134
135 if (ssc_sr & params->mask->ssc_endx) {
136 /* Load the PDC next pointer and counter registers */
137 prtd->period_ptr += prtd->period_size;
138 if (prtd->period_ptr >= prtd->dma_buffer_end)
139 prtd->period_ptr = prtd->dma_buffer;
140 ssc_writex(params->ssc->regs, params->pdc->xnpr,
141 prtd->period_ptr);
142 ssc_writex(params->ssc->regs, params->pdc->xncr,
143 prtd->period_size / params->pdc_xfer_size);
144 }
145
146
147 snd_pcm_period_elapsed(substream);
148}
149
150
151
152/*--------------------------------------------------------------------------*\
153 * PCM operations
154\*--------------------------------------------------------------------------*/
155static int at32_pcm_hw_params(struct snd_pcm_substream *substream,
156 struct snd_pcm_hw_params *params)
157{
158 struct snd_pcm_runtime *runtime = substream->runtime;
159 struct at32_runtime_data *prtd = runtime->private_data;
160 struct snd_soc_pcm_runtime *rtd = substream->private_data;
161
162 /* this may get called several times by oss emulation
163 * with different params
164 */
165 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
166 runtime->dma_bytes = params_buffer_bytes(params);
167
168 prtd->params = rtd->dai->cpu_dai->dma_data;
169 prtd->params->dma_intr_handler = at32_pcm_dma_irq;
170
171 prtd->dma_buffer = runtime->dma_addr;
172 prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
173 prtd->period_size = params_period_bytes(params);
174
175 pr_debug("hw_params: DMA for %s initialized "
176 "(dma_bytes=%ld, period_size=%ld)\n",
177 prtd->params->name, runtime->dma_bytes, prtd->period_size);
178
179 return 0;
180}
181
182
183
184static int at32_pcm_hw_free(struct snd_pcm_substream *substream)
185{
186 struct at32_runtime_data *prtd = substream->runtime->private_data;
187 struct at32_pcm_dma_params *params = prtd->params;
188
189 if (params != NULL) {
190 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
191 params->mask->pdc_disable);
192 prtd->params->dma_intr_handler = NULL;
193 }
194
195 return 0;
196}
197
198
199
200static int at32_pcm_prepare(struct snd_pcm_substream *substream)
201{
202 struct at32_runtime_data *prtd = substream->runtime->private_data;
203 struct at32_pcm_dma_params *params = prtd->params;
204
205 ssc_writex(params->ssc->regs, SSC_IDR,
206 params->mask->ssc_endx | params->mask->ssc_endbuf);
207 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
208 params->mask->pdc_disable);
209
210 return 0;
211}
212
213
214static int at32_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
215{
216 struct snd_pcm_runtime *rtd = substream->runtime;
217 struct at32_runtime_data *prtd = rtd->private_data;
218 struct at32_pcm_dma_params *params = prtd->params;
219 int ret = 0;
220
221 pr_debug("at32_pcm_trigger: buffer_size = %ld, "
222 "dma_area = %p, dma_bytes = %ld\n",
223 rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
224
225 switch (cmd) {
226 case SNDRV_PCM_TRIGGER_START:
227 prtd->period_ptr = prtd->dma_buffer;
228
229 ssc_writex(params->ssc->regs, params->pdc->xpr,
230 prtd->period_ptr);
231 ssc_writex(params->ssc->regs, params->pdc->xcr,
232 prtd->period_size / params->pdc_xfer_size);
233
234 prtd->period_ptr += prtd->period_size;
235 ssc_writex(params->ssc->regs, params->pdc->xnpr,
236 prtd->period_ptr);
237 ssc_writex(params->ssc->regs, params->pdc->xncr,
238 prtd->period_size / params->pdc_xfer_size);
239
240 pr_debug("trigger: period_ptr=%lx, xpr=%x, "
241 "xcr=%d, xnpr=%x, xncr=%d\n",
242 (unsigned long)prtd->period_ptr,
243 ssc_readx(params->ssc->regs, params->pdc->xpr),
244 ssc_readx(params->ssc->regs, params->pdc->xcr),
245 ssc_readx(params->ssc->regs, params->pdc->xnpr),
246 ssc_readx(params->ssc->regs, params->pdc->xncr));
247
248 ssc_writex(params->ssc->regs, SSC_IER,
249 params->mask->ssc_endx | params->mask->ssc_endbuf);
250 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
251 params->mask->pdc_enable);
252
253 pr_debug("sr=%x, imr=%x\n",
254 ssc_readx(params->ssc->regs, SSC_SR),
255 ssc_readx(params->ssc->regs, SSC_IER));
256 break; /* SNDRV_PCM_TRIGGER_START */
257
258
259
260 case SNDRV_PCM_TRIGGER_STOP:
261 case SNDRV_PCM_TRIGGER_SUSPEND:
262 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
263 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
264 params->mask->pdc_disable);
265 break;
266
267
268 case SNDRV_PCM_TRIGGER_RESUME:
269 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
270 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
271 params->mask->pdc_enable);
272 break;
273
274 default:
275 ret = -EINVAL;
276 }
277
278 return ret;
279}
280
281
282
283static snd_pcm_uframes_t at32_pcm_pointer(struct snd_pcm_substream *substream)
284{
285 struct snd_pcm_runtime *runtime = substream->runtime;
286 struct at32_runtime_data *prtd = runtime->private_data;
287 struct at32_pcm_dma_params *params = prtd->params;
288 dma_addr_t ptr;
289 snd_pcm_uframes_t x;
290
291 ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
292 x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
293
294 if (x == runtime->buffer_size)
295 x = 0;
296
297 return x;
298}
299
300
301
302static int at32_pcm_open(struct snd_pcm_substream *substream)
303{
304 struct snd_pcm_runtime *runtime = substream->runtime;
305 struct at32_runtime_data *prtd;
306 int ret = 0;
307
308 snd_soc_set_runtime_hwparams(substream, &at32_pcm_hardware);
309
310 /* ensure that buffer size is a multiple of period size */
311 ret = snd_pcm_hw_constraint_integer(runtime,
312 SNDRV_PCM_HW_PARAM_PERIODS);
313 if (ret < 0)
314 goto out;
315
316 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
317 if (prtd == NULL) {
318 ret = -ENOMEM;
319 goto out;
320 }
321 runtime->private_data = prtd;
322
323
324out:
325 return ret;
326}
327
328
329
330static int at32_pcm_close(struct snd_pcm_substream *substream)
331{
332 struct at32_runtime_data *prtd = substream->runtime->private_data;
333
334 kfree(prtd);
335 return 0;
336}
337
338
339static int at32_pcm_mmap(struct snd_pcm_substream *substream,
340 struct vm_area_struct *vma)
341{
342 return remap_pfn_range(vma, vma->vm_start,
343 substream->dma_buffer.addr >> PAGE_SHIFT,
344 vma->vm_end - vma->vm_start, vma->vm_page_prot);
345}
346
347
348
349static struct snd_pcm_ops at32_pcm_ops = {
350 .open = at32_pcm_open,
351 .close = at32_pcm_close,
352 .ioctl = snd_pcm_lib_ioctl,
353 .hw_params = at32_pcm_hw_params,
354 .hw_free = at32_pcm_hw_free,
355 .prepare = at32_pcm_prepare,
356 .trigger = at32_pcm_trigger,
357 .pointer = at32_pcm_pointer,
358 .mmap = at32_pcm_mmap,
359};
360
361
362
363/*--------------------------------------------------------------------------*\
364 * ASoC platform driver
365\*--------------------------------------------------------------------------*/
366static u64 at32_pcm_dmamask = 0xffffffff;
367
368static int at32_pcm_new(struct snd_card *card,
369 struct snd_soc_dai *dai,
370 struct snd_pcm *pcm)
371{
372 int ret = 0;
373
374 if (!card->dev->dma_mask)
375 card->dev->dma_mask = &at32_pcm_dmamask;
376 if (!card->dev->coherent_dma_mask)
377 card->dev->coherent_dma_mask = 0xffffffff;
378
379 if (dai->playback.channels_min) {
380 ret = at32_pcm_preallocate_dma_buffer(
381 pcm, SNDRV_PCM_STREAM_PLAYBACK);
382 if (ret)
383 goto out;
384 }
385
386 if (dai->capture.channels_min) {
387 pr_debug("at32-pcm: Allocating PCM capture DMA buffer\n");
388 ret = at32_pcm_preallocate_dma_buffer(
389 pcm, SNDRV_PCM_STREAM_CAPTURE);
390 if (ret)
391 goto out;
392 }
393
394
395out:
396 return ret;
397}
398
399
400
401static void at32_pcm_free_dma_buffers(struct snd_pcm *pcm)
402{
403 struct snd_pcm_substream *substream;
404 struct snd_dma_buffer *buf;
405 int stream;
406
407 for (stream = 0; stream < 2; stream++) {
408 substream = pcm->streams[stream].substream;
409 if (substream == NULL)
410 continue;
411
412 buf = &substream->dma_buffer;
413 if (!buf->area)
414 continue;
415 dma_free_coherent(pcm->card->dev, buf->bytes,
416 buf->area, buf->addr);
417 buf->area = NULL;
418 }
419}
420
421
422
423#ifdef CONFIG_PM
424static int at32_pcm_suspend(struct platform_device *pdev,
425 struct snd_soc_dai *dai)
426{
427 struct snd_pcm_runtime *runtime = dai->runtime;
428 struct at32_runtime_data *prtd;
429 struct at32_pcm_dma_params *params;
430
431 if (runtime == NULL)
432 return 0;
433 prtd = runtime->private_data;
434 params = prtd->params;
435
436 /* Disable the PDC and save the PDC registers */
437 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
438 params->mask->pdc_disable);
439
440 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
441 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
442 prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
443 prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
444
445 return 0;
446}
447
448
449
450static int at32_pcm_resume(struct platform_device *pdev,
451 struct snd_soc_dai *dai)
452{
453 struct snd_pcm_runtime *runtime = dai->runtime;
454 struct at32_runtime_data *prtd;
455 struct at32_pcm_dma_params *params;
456
457 if (runtime == NULL)
458 return 0;
459 prtd = runtime->private_data;
460 params = prtd->params;
461
462 /* Restore the PDC registers and enable the PDC */
463 ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
464 ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
465 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
466 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
467
468 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR, params->mask->pdc_enable);
469 return 0;
470}
471#else /* CONFIG_PM */
472# define at32_pcm_suspend NULL
473# define at32_pcm_resume NULL
474#endif /* CONFIG_PM */
475
476
477
478struct snd_soc_platform at32_soc_platform = {
479 .name = "at32-audio",
480 .pcm_ops = &at32_pcm_ops,
481 .pcm_new = at32_pcm_new,
482 .pcm_free = at32_pcm_free_dma_buffers,
483 .suspend = at32_pcm_suspend,
484 .resume = at32_pcm_resume,
485};
486EXPORT_SYMBOL_GPL(at32_soc_platform);
487
488
489
490MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
491MODULE_DESCRIPTION("Atmel AT32 PCM module");
492MODULE_LICENSE("GPL");
diff --git a/sound/soc/at32/at32-pcm.h b/sound/soc/at32/at32-pcm.h
deleted file mode 100644
index 2a52430417da..000000000000
--- a/sound/soc/at32/at32-pcm.h
+++ /dev/null
@@ -1,79 +0,0 @@
1/* sound/soc/at32/at32-pcm.h
2 * ASoC PCM interface for Atmel AT32 SoC
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
6 *
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
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __SOUND_SOC_AT32_AT32_PCM_H
13#define __SOUND_SOC_AT32_AT32_PCM_H __FILE__
14
15#include <linux/atmel-ssc.h>
16
17
18/*
19 * Registers and status bits that are required by the PCM driver
20 * TODO: Is ptcr really used?
21 */
22struct at32_pdc_regs {
23 u32 xpr; /* PDC RX/TX pointer */
24 u32 xcr; /* PDC RX/TX counter */
25 u32 xnpr; /* PDC next RX/TX pointer */
26 u32 xncr; /* PDC next RX/TX counter */
27 u32 ptcr; /* PDC transfer control */
28};
29
30
31
32/*
33 * SSC mask info
34 */
35struct at32_ssc_mask {
36 u32 ssc_enable; /* SSC RX/TX enable */
37 u32 ssc_disable; /* SSC RX/TX disable */
38 u32 ssc_endx; /* SSC ENDTX or ENDRX */
39 u32 ssc_endbuf; /* SSC TXBUFF or RXBUFF */
40 u32 pdc_enable; /* PDC RX/TX enable */
41 u32 pdc_disable; /* PDC RX/TX disable */
42};
43
44
45
46/*
47 * This structure, shared between the PCM driver and the interface,
48 * contains all information required by the PCM driver to perform the
49 * PDC DMA operation. All fields except dma_intr_handler() are initialized
50 * by the interface. The dms_intr_handler() pointer is set by the PCM
51 * driver and called by the interface SSC interrupt handler if it is
52 * non-NULL.
53 */
54struct at32_pcm_dma_params {
55 char *name; /* stream identifier */
56 int pdc_xfer_size; /* PDC counter increment in bytes */
57 struct ssc_device *ssc; /* SSC device for stream */
58 struct at32_pdc_regs *pdc; /* PDC register info */
59 struct at32_ssc_mask *mask; /* SSC mask info */
60 struct snd_pcm_substream *substream;
61 void (*dma_intr_handler) (u32, struct snd_pcm_substream *);
62};
63
64
65
66/*
67 * The AT32 ASoC platform driver
68 */
69extern struct snd_soc_platform at32_soc_platform;
70
71
72
73/*
74 * SSC register access (since ssc_writel() / ssc_readl() require literal name)
75 */
76#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
77#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
78
79#endif /* __SOUND_SOC_AT32_AT32_PCM_H */
diff --git a/sound/soc/at32/at32-ssc.c b/sound/soc/at32/at32-ssc.c
deleted file mode 100644
index 4ef6492c902e..000000000000
--- a/sound/soc/at32/at32-ssc.c
+++ /dev/null
@@ -1,849 +0,0 @@
1/* sound/soc/at32/at32-ssc.c
2 * ASoC platform driver for AT32 using SSC as DAI
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
6 *
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
9 * published by the Free Software Foundation.
10 *
11 * Note that this is basically a port of the sound/soc/at91-ssc.c to
12 * the AVR32 kernel. Thanks to Frank Mandarino for that code.
13 */
14
15/* #define DEBUG */
16
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/interrupt.h>
20#include <linux/device.h>
21#include <linux/delay.h>
22#include <linux/clk.h>
23#include <linux/io.h>
24#include <linux/atmel_pdc.h>
25#include <linux/atmel-ssc.h>
26
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/pcm_params.h>
30#include <sound/initval.h>
31#include <sound/soc.h>
32
33#include "at32-pcm.h"
34#include "at32-ssc.h"
35
36
37
38/*-------------------------------------------------------------------------*\
39 * Constants
40\*-------------------------------------------------------------------------*/
41#define NUM_SSC_DEVICES 3
42
43/*
44 * SSC direction masks
45 */
46#define SSC_DIR_MASK_UNUSED 0
47#define SSC_DIR_MASK_PLAYBACK 1
48#define SSC_DIR_MASK_CAPTURE 2
49
50/*
51 * SSC register values that Atmel left out of <linux/atmel-ssc.h>. These
52 * are expected to be used with SSC_BF
53 */
54/* START bit field values */
55#define SSC_START_CONTINUOUS 0
56#define SSC_START_TX_RX 1
57#define SSC_START_LOW_RF 2
58#define SSC_START_HIGH_RF 3
59#define SSC_START_FALLING_RF 4
60#define SSC_START_RISING_RF 5
61#define SSC_START_LEVEL_RF 6
62#define SSC_START_EDGE_RF 7
63#define SSS_START_COMPARE_0 8
64
65/* CKI bit field values */
66#define SSC_CKI_FALLING 0
67#define SSC_CKI_RISING 1
68
69/* CKO bit field values */
70#define SSC_CKO_NONE 0
71#define SSC_CKO_CONTINUOUS 1
72#define SSC_CKO_TRANSFER 2
73
74/* CKS bit field values */
75#define SSC_CKS_DIV 0
76#define SSC_CKS_CLOCK 1
77#define SSC_CKS_PIN 2
78
79/* FSEDGE bit field values */
80#define SSC_FSEDGE_POSITIVE 0
81#define SSC_FSEDGE_NEGATIVE 1
82
83/* FSOS bit field values */
84#define SSC_FSOS_NONE 0
85#define SSC_FSOS_NEGATIVE 1
86#define SSC_FSOS_POSITIVE 2
87#define SSC_FSOS_LOW 3
88#define SSC_FSOS_HIGH 4
89#define SSC_FSOS_TOGGLE 5
90
91#define START_DELAY 1
92
93
94
95/*-------------------------------------------------------------------------*\
96 * Module data
97\*-------------------------------------------------------------------------*/
98/*
99 * SSC PDC registered required by the PCM DMA engine
100 */
101static struct at32_pdc_regs pdc_tx_reg = {
102 .xpr = SSC_PDC_TPR,
103 .xcr = SSC_PDC_TCR,
104 .xnpr = SSC_PDC_TNPR,
105 .xncr = SSC_PDC_TNCR,
106};
107
108
109
110static struct at32_pdc_regs pdc_rx_reg = {
111 .xpr = SSC_PDC_RPR,
112 .xcr = SSC_PDC_RCR,
113 .xnpr = SSC_PDC_RNPR,
114 .xncr = SSC_PDC_RNCR,
115};
116
117
118
119/*
120 * SSC and PDC status bits for transmit and receive
121 */
122static struct at32_ssc_mask ssc_tx_mask = {
123 .ssc_enable = SSC_BIT(CR_TXEN),
124 .ssc_disable = SSC_BIT(CR_TXDIS),
125 .ssc_endx = SSC_BIT(SR_ENDTX),
126 .ssc_endbuf = SSC_BIT(SR_TXBUFE),
127 .pdc_enable = SSC_BIT(PDC_PTCR_TXTEN),
128 .pdc_disable = SSC_BIT(PDC_PTCR_TXTDIS),
129};
130
131
132
133static struct at32_ssc_mask ssc_rx_mask = {
134 .ssc_enable = SSC_BIT(CR_RXEN),
135 .ssc_disable = SSC_BIT(CR_RXDIS),
136 .ssc_endx = SSC_BIT(SR_ENDRX),
137 .ssc_endbuf = SSC_BIT(SR_RXBUFF),
138 .pdc_enable = SSC_BIT(PDC_PTCR_RXTEN),
139 .pdc_disable = SSC_BIT(PDC_PTCR_RXTDIS),
140};
141
142
143
144/*
145 * DMA parameters for each SSC
146 */
147static struct at32_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
148 {
149 {
150 .name = "SSC0 PCM out",
151 .pdc = &pdc_tx_reg,
152 .mask = &ssc_tx_mask,
153 },
154 {
155 .name = "SSC0 PCM in",
156 .pdc = &pdc_rx_reg,
157 .mask = &ssc_rx_mask,
158 },
159 },
160 {
161 {
162 .name = "SSC1 PCM out",
163 .pdc = &pdc_tx_reg,
164 .mask = &ssc_tx_mask,
165 },
166 {
167 .name = "SSC1 PCM in",
168 .pdc = &pdc_rx_reg,
169 .mask = &ssc_rx_mask,
170 },
171 },
172 {
173 {
174 .name = "SSC2 PCM out",
175 .pdc = &pdc_tx_reg,
176 .mask = &ssc_tx_mask,
177 },
178 {
179 .name = "SSC2 PCM in",
180 .pdc = &pdc_rx_reg,
181 .mask = &ssc_rx_mask,
182 },
183 },
184};
185
186
187
188static struct at32_ssc_info ssc_info[NUM_SSC_DEVICES] = {
189 {
190 .name = "ssc0",
191 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
192 .dir_mask = SSC_DIR_MASK_UNUSED,
193 .initialized = 0,
194 },
195 {
196 .name = "ssc1",
197 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
198 .dir_mask = SSC_DIR_MASK_UNUSED,
199 .initialized = 0,
200 },
201 {
202 .name = "ssc2",
203 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
204 .dir_mask = SSC_DIR_MASK_UNUSED,
205 .initialized = 0,
206 },
207};
208
209
210
211
212/*-------------------------------------------------------------------------*\
213 * ISR
214\*-------------------------------------------------------------------------*/
215/*
216 * SSC interrupt handler. Passes PDC interrupts to the DMA interrupt
217 * handler in the PCM driver.
218 */
219static irqreturn_t at32_ssc_interrupt(int irq, void *dev_id)
220{
221 struct at32_ssc_info *ssc_p = dev_id;
222 struct at32_pcm_dma_params *dma_params;
223 u32 ssc_sr;
224 u32 ssc_substream_mask;
225 int i;
226
227 ssc_sr = (ssc_readl(ssc_p->ssc->regs, SR) &
228 ssc_readl(ssc_p->ssc->regs, IMR));
229
230 /*
231 * Loop through substreams attached to this SSC. If a DMA-related
232 * interrupt occured on that substream, call the DMA interrupt
233 * handler function, if one has been registered in the dma_param
234 * structure by the PCM driver.
235 */
236 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
237 dma_params = ssc_p->dma_params[i];
238
239 if ((dma_params != NULL) &&
240 (dma_params->dma_intr_handler != NULL)) {
241 ssc_substream_mask = (dma_params->mask->ssc_endx |
242 dma_params->mask->ssc_endbuf);
243 if (ssc_sr & ssc_substream_mask) {
244 dma_params->dma_intr_handler(ssc_sr,
245 dma_params->
246 substream);
247 }
248 }
249 }
250
251
252 return IRQ_HANDLED;
253}
254
255/*-------------------------------------------------------------------------*\
256 * DAI functions
257\*-------------------------------------------------------------------------*/
258/*
259 * Startup. Only that one substream allowed in each direction.
260 */
261static int at32_ssc_startup(struct snd_pcm_substream *substream)
262{
263 struct snd_soc_pcm_runtime *rtd = substream->private_data;
264 struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
265 int dir_mask;
266
267 dir_mask = ((substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
268 SSC_DIR_MASK_PLAYBACK : SSC_DIR_MASK_CAPTURE);
269
270 spin_lock_irq(&ssc_p->lock);
271 if (ssc_p->dir_mask & dir_mask) {
272 spin_unlock_irq(&ssc_p->lock);
273 return -EBUSY;
274 }
275 ssc_p->dir_mask |= dir_mask;
276 spin_unlock_irq(&ssc_p->lock);
277
278 return 0;
279}
280
281
282
283/*
284 * Shutdown. Clear DMA parameters and shutdown the SSC if there
285 * are no other substreams open.
286 */
287static void at32_ssc_shutdown(struct snd_pcm_substream *substream)
288{
289 struct snd_soc_pcm_runtime *rtd = substream->private_data;
290 struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
291 struct at32_pcm_dma_params *dma_params;
292 int dir_mask;
293
294 dma_params = ssc_p->dma_params[substream->stream];
295
296 if (dma_params != NULL) {
297 ssc_writel(dma_params->ssc->regs, CR,
298 dma_params->mask->ssc_disable);
299 pr_debug("%s disabled SSC_SR=0x%08x\n",
300 (substream->stream ? "receiver" : "transmit"),
301 ssc_readl(ssc_p->ssc->regs, SR));
302
303 dma_params->ssc = NULL;
304 dma_params->substream = NULL;
305 ssc_p->dma_params[substream->stream] = NULL;
306 }
307
308
309 dir_mask = 1 << substream->stream;
310 spin_lock_irq(&ssc_p->lock);
311 ssc_p->dir_mask &= ~dir_mask;
312 if (!ssc_p->dir_mask) {
313 /* Shutdown the SSC clock */
314 pr_debug("at32-ssc: Stopping user %d clock\n",
315 ssc_p->ssc->user);
316 clk_disable(ssc_p->ssc->clk);
317
318 if (ssc_p->initialized) {
319 free_irq(ssc_p->ssc->irq, ssc_p);
320 ssc_p->initialized = 0;
321 }
322
323 /* Reset the SSC */
324 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
325
326 /* clear the SSC dividers */
327 ssc_p->cmr_div = 0;
328 ssc_p->tcmr_period = 0;
329 ssc_p->rcmr_period = 0;
330 }
331 spin_unlock_irq(&ssc_p->lock);
332}
333
334
335
336/*
337 * Set the SSC system clock rate
338 */
339static int at32_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
340 int clk_id, unsigned int freq, int dir)
341{
342 /* TODO: What the heck do I do here? */
343 return 0;
344}
345
346
347
348/*
349 * Record DAI format for use by hw_params()
350 */
351static int at32_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
352 unsigned int fmt)
353{
354 struct at32_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
355
356 ssc_p->daifmt = fmt;
357 return 0;
358}
359
360
361
362/*
363 * Record SSC clock dividers for use in hw_params()
364 */
365static int at32_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
366 int div_id, int div)
367{
368 struct at32_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
369
370 switch (div_id) {
371 case AT32_SSC_CMR_DIV:
372 /*
373 * The same master clock divider is used for both
374 * transmit and receive, so if a value has already
375 * been set, it must match this value
376 */
377 if (ssc_p->cmr_div == 0)
378 ssc_p->cmr_div = div;
379 else if (div != ssc_p->cmr_div)
380 return -EBUSY;
381 break;
382
383 case AT32_SSC_TCMR_PERIOD:
384 ssc_p->tcmr_period = div;
385 break;
386
387 case AT32_SSC_RCMR_PERIOD:
388 ssc_p->rcmr_period = div;
389 break;
390
391 default:
392 return -EINVAL;
393 }
394
395 return 0;
396}
397
398
399
400/*
401 * Configure the SSC
402 */
403static int at32_ssc_hw_params(struct snd_pcm_substream *substream,
404 struct snd_pcm_hw_params *params)
405{
406 struct snd_soc_pcm_runtime *rtd = substream->private_data;
407 int id = rtd->dai->cpu_dai->id;
408 struct at32_ssc_info *ssc_p = &ssc_info[id];
409 struct at32_pcm_dma_params *dma_params;
410 int channels, bits;
411 u32 tfmr, rfmr, tcmr, rcmr;
412 int start_event;
413 int ret;
414
415
416 /*
417 * Currently, there is only one set of dma_params for each direction.
418 * If more are added, this code will have to be changed to select
419 * the proper set
420 */
421 dma_params = &ssc_dma_params[id][substream->stream];
422 dma_params->ssc = ssc_p->ssc;
423 dma_params->substream = substream;
424
425 ssc_p->dma_params[substream->stream] = dma_params;
426
427
428 /*
429 * The cpu_dai->dma_data field is only used to communicate the
430 * appropriate DMA parameters to the PCM driver's hw_params()
431 * function. It should not be used for other purposes as it
432 * is common to all substreams.
433 */
434 rtd->dai->cpu_dai->dma_data = dma_params;
435
436 channels = params_channels(params);
437
438
439 /*
440 * Determine sample size in bits and the PDC increment
441 */
442 switch (params_format(params)) {
443 case SNDRV_PCM_FORMAT_S8:
444 bits = 8;
445 dma_params->pdc_xfer_size = 1;
446 break;
447
448 case SNDRV_PCM_FORMAT_S16:
449 bits = 16;
450 dma_params->pdc_xfer_size = 2;
451 break;
452
453 case SNDRV_PCM_FORMAT_S24:
454 bits = 24;
455 dma_params->pdc_xfer_size = 4;
456 break;
457
458 case SNDRV_PCM_FORMAT_S32:
459 bits = 32;
460 dma_params->pdc_xfer_size = 4;
461 break;
462
463 default:
464 pr_warning("at32-ssc: Unsupported PCM format %d",
465 params_format(params));
466 return -EINVAL;
467 }
468 pr_debug("at32-ssc: bits = %d, pdc_xfer_size = %d, channels = %d\n",
469 bits, dma_params->pdc_xfer_size, channels);
470
471
472 /*
473 * The SSC only supports up to 16-bit samples in I2S format, due
474 * to the size of the Frame Mode Register FSLEN field.
475 */
476 if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S)
477 if (bits > 16) {
478 pr_warning("at32-ssc: "
479 "sample size %d is too large for I2S\n",
480 bits);
481 return -EINVAL;
482 }
483
484
485 /*
486 * Compute the SSC register settings
487 */
488 switch (ssc_p->daifmt & (SND_SOC_DAIFMT_FORMAT_MASK |
489 SND_SOC_DAIFMT_MASTER_MASK)) {
490 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
491 /*
492 * I2S format, SSC provides BCLK and LRS clocks.
493 *
494 * The SSC transmit and receive clocks are generated from the
495 * MCK divider, and the BCLK signal is output on the SSC TK line
496 */
497 pr_debug("at32-ssc: SSC mode is I2S BCLK / FRAME master\n");
498 rcmr = (SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
499 SSC_BF(RCMR_STTDLY, START_DELAY) |
500 SSC_BF(RCMR_START, SSC_START_FALLING_RF) |
501 SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
502 SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
503 SSC_BF(RCMR_CKS, SSC_CKS_DIV));
504
505 rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
506 SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE) |
507 SSC_BF(RFMR_FSLEN, bits - 1) |
508 SSC_BF(RFMR_DATNB, channels - 1) |
509 SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
510
511 tcmr = (SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) |
512 SSC_BF(TCMR_STTDLY, START_DELAY) |
513 SSC_BF(TCMR_START, SSC_START_FALLING_RF) |
514 SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
515 SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
516 SSC_BF(TCMR_CKS, SSC_CKS_DIV));
517
518 tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
519 SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE) |
520 SSC_BF(TFMR_FSLEN, bits - 1) |
521 SSC_BF(TFMR_DATNB, channels - 1) | SSC_BIT(TFMR_MSBF) |
522 SSC_BF(TFMR_DATLEN, bits - 1));
523 break;
524
525
526 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
527 /*
528 * I2S format, CODEC supplies BCLK and LRC clock.
529 *
530 * The SSC transmit clock is obtained from the BCLK signal
531 * on the TK line, and the SSC receive clock is generated from
532 * the transmit clock.
533 *
534 * For single channel data, one sample is transferred on the
535 * falling edge of the LRC clock. For two channel data, one
536 * sample is transferred on both edges of the LRC clock.
537 */
538 pr_debug("at32-ssc: SSC mode is I2S BCLK / FRAME slave\n");
539 start_event = ((channels == 1) ?
540 SSC_START_FALLING_RF : SSC_START_EDGE_RF);
541
542 rcmr = (SSC_BF(RCMR_STTDLY, START_DELAY) |
543 SSC_BF(RCMR_START, start_event) |
544 SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
545 SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
546 SSC_BF(RCMR_CKS, SSC_CKS_CLOCK));
547
548 rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
549 SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) |
550 SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
551
552 tcmr = (SSC_BF(TCMR_STTDLY, START_DELAY) |
553 SSC_BF(TCMR_START, start_event) |
554 SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
555 SSC_BF(TCMR_CKO, SSC_CKO_NONE) |
556 SSC_BF(TCMR_CKS, SSC_CKS_PIN));
557
558 tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
559 SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) |
560 SSC_BIT(TFMR_MSBF) | SSC_BF(TFMR_DATLEN, bits - 1));
561 break;
562
563
564 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
565 /*
566 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
567 *
568 * The SSC transmit and receive clocks are generated from the
569 * MCK divider, and the BCLK signal is output on the SSC TK line
570 */
571 pr_debug("at32-ssc: SSC mode is DSP A BCLK / FRAME master\n");
572 rcmr = (SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period) |
573 SSC_BF(RCMR_STTDLY, 1) |
574 SSC_BF(RCMR_START, SSC_START_RISING_RF) |
575 SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
576 SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
577 SSC_BF(RCMR_CKS, SSC_CKS_DIV));
578
579 rfmr = (SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
580 SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE) |
581 SSC_BF(RFMR_DATNB, channels - 1) |
582 SSC_BIT(RFMR_MSBF) | SSC_BF(RFMR_DATLEN, bits - 1));
583
584 tcmr = (SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period) |
585 SSC_BF(TCMR_STTDLY, 1) |
586 SSC_BF(TCMR_START, SSC_START_RISING_RF) |
587 SSC_BF(TCMR_CKI, SSC_CKI_RISING) |
588 SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
589 SSC_BF(TCMR_CKS, SSC_CKS_DIV));
590
591 tfmr = (SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
592 SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE) |
593 SSC_BF(TFMR_DATNB, channels - 1) |
594 SSC_BIT(TFMR_MSBF) | SSC_BF(TFMR_DATLEN, bits - 1));
595 break;
596
597
598 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
599 default:
600 pr_warning("at32-ssc: unsupported DAI format 0x%x\n",
601 ssc_p->daifmt);
602 return -EINVAL;
603 break;
604 }
605 pr_debug("at32-ssc: RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
606 rcmr, rfmr, tcmr, tfmr);
607
608
609 if (!ssc_p->initialized) {
610 /* enable peripheral clock */
611 pr_debug("at32-ssc: Starting clock\n");
612 clk_enable(ssc_p->ssc->clk);
613
614 /* Reset the SSC and its PDC registers */
615 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
616
617 ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
618 ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
619 ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
620 ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
621
622 ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
623 ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
624 ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
625 ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
626
627 ret = request_irq(ssc_p->ssc->irq, at32_ssc_interrupt, 0,
628 ssc_p->name, ssc_p);
629 if (ret < 0) {
630 pr_warning("at32-ssc: request irq failed (%d)\n", ret);
631 pr_debug("at32-ssc: Stopping clock\n");
632 clk_disable(ssc_p->ssc->clk);
633 return ret;
634 }
635
636 ssc_p->initialized = 1;
637 }
638
639 /* Set SSC clock mode register */
640 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->cmr_div);
641
642 /* set receive clock mode and format */
643 ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
644 ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
645
646 /* set transmit clock mode and format */
647 ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
648 ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
649
650 pr_debug("at32-ssc: SSC initialized\n");
651 return 0;
652}
653
654
655
656static int at32_ssc_prepare(struct snd_pcm_substream *substream)
657{
658 struct snd_soc_pcm_runtime *rtd = substream->private_data;
659 struct at32_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
660 struct at32_pcm_dma_params *dma_params;
661
662 dma_params = ssc_p->dma_params[substream->stream];
663
664 ssc_writel(dma_params->ssc->regs, CR, dma_params->mask->ssc_enable);
665
666 return 0;
667}
668
669
670
671#ifdef CONFIG_PM
672static int at32_ssc_suspend(struct platform_device *pdev,
673 struct snd_soc_dai *cpu_dai)
674{
675 struct at32_ssc_info *ssc_p;
676
677 if (!cpu_dai->active)
678 return 0;
679
680 ssc_p = &ssc_info[cpu_dai->id];
681
682 /* Save the status register before disabling transmit and receive */
683 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
684 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
685
686 /* Save the current interrupt mask, then disable unmasked interrupts */
687 ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
688 ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
689
690 ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
691 ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
692 ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
693 ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
694 ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
695
696 return 0;
697}
698
699
700
701static int at32_ssc_resume(struct platform_device *pdev,
702 struct snd_soc_dai *cpu_dai)
703{
704 struct at32_ssc_info *ssc_p;
705 u32 cr;
706
707 if (!cpu_dai->active)
708 return 0;
709
710 ssc_p = &ssc_info[cpu_dai->id];
711
712 /* restore SSC register settings */
713 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
714 ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
715 ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
716 ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
717 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
718
719 /* re-enable interrupts */
720 ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
721
722 /* Re-enable recieve and transmit as appropriate */
723 cr = 0;
724 cr |=
725 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
726 cr |=
727 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
728 ssc_writel(ssc_p->ssc->regs, CR, cr);
729
730 return 0;
731}
732#else /* CONFIG_PM */
733# define at32_ssc_suspend NULL
734# define at32_ssc_resume NULL
735#endif /* CONFIG_PM */
736
737
738#define AT32_SSC_RATES \
739 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
740 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
741 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
742
743
744#define AT32_SSC_FORMATS \
745 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16 | \
746 SNDRV_PCM_FMTBIT_S24 | SNDRV_PCM_FMTBIT_S32)
747
748
749struct snd_soc_dai at32_ssc_dai[NUM_SSC_DEVICES] = {
750 {
751 .name = "at32-ssc0",
752 .id = 0,
753 .type = SND_SOC_DAI_PCM,
754 .suspend = at32_ssc_suspend,
755 .resume = at32_ssc_resume,
756 .playback = {
757 .channels_min = 1,
758 .channels_max = 2,
759 .rates = AT32_SSC_RATES,
760 .formats = AT32_SSC_FORMATS,
761 },
762 .capture = {
763 .channels_min = 1,
764 .channels_max = 2,
765 .rates = AT32_SSC_RATES,
766 .formats = AT32_SSC_FORMATS,
767 },
768 .ops = {
769 .startup = at32_ssc_startup,
770 .shutdown = at32_ssc_shutdown,
771 .prepare = at32_ssc_prepare,
772 .hw_params = at32_ssc_hw_params,
773 },
774 .dai_ops = {
775 .set_sysclk = at32_ssc_set_dai_sysclk,
776 .set_fmt = at32_ssc_set_dai_fmt,
777 .set_clkdiv = at32_ssc_set_dai_clkdiv,
778 },
779 .private_data = &ssc_info[0],
780 },
781 {
782 .name = "at32-ssc1",
783 .id = 1,
784 .type = SND_SOC_DAI_PCM,
785 .suspend = at32_ssc_suspend,
786 .resume = at32_ssc_resume,
787 .playback = {
788 .channels_min = 1,
789 .channels_max = 2,
790 .rates = AT32_SSC_RATES,
791 .formats = AT32_SSC_FORMATS,
792 },
793 .capture = {
794 .channels_min = 1,
795 .channels_max = 2,
796 .rates = AT32_SSC_RATES,
797 .formats = AT32_SSC_FORMATS,
798 },
799 .ops = {
800 .startup = at32_ssc_startup,
801 .shutdown = at32_ssc_shutdown,
802 .prepare = at32_ssc_prepare,
803 .hw_params = at32_ssc_hw_params,
804 },
805 .dai_ops = {
806 .set_sysclk = at32_ssc_set_dai_sysclk,
807 .set_fmt = at32_ssc_set_dai_fmt,
808 .set_clkdiv = at32_ssc_set_dai_clkdiv,
809 },
810 .private_data = &ssc_info[1],
811 },
812 {
813 .name = "at32-ssc2",
814 .id = 2,
815 .type = SND_SOC_DAI_PCM,
816 .suspend = at32_ssc_suspend,
817 .resume = at32_ssc_resume,
818 .playback = {
819 .channels_min = 1,
820 .channels_max = 2,
821 .rates = AT32_SSC_RATES,
822 .formats = AT32_SSC_FORMATS,
823 },
824 .capture = {
825 .channels_min = 1,
826 .channels_max = 2,
827 .rates = AT32_SSC_RATES,
828 .formats = AT32_SSC_FORMATS,
829 },
830 .ops = {
831 .startup = at32_ssc_startup,
832 .shutdown = at32_ssc_shutdown,
833 .prepare = at32_ssc_prepare,
834 .hw_params = at32_ssc_hw_params,
835 },
836 .dai_ops = {
837 .set_sysclk = at32_ssc_set_dai_sysclk,
838 .set_fmt = at32_ssc_set_dai_fmt,
839 .set_clkdiv = at32_ssc_set_dai_clkdiv,
840 },
841 .private_data = &ssc_info[2],
842 },
843};
844EXPORT_SYMBOL_GPL(at32_ssc_dai);
845
846
847MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>");
848MODULE_DESCRIPTION("AT32 SSC ASoC Interface");
849MODULE_LICENSE("GPL");
diff --git a/sound/soc/at32/at32-ssc.h b/sound/soc/at32/at32-ssc.h
deleted file mode 100644
index 3c052dbbe460..000000000000
--- a/sound/soc/at32/at32-ssc.h
+++ /dev/null
@@ -1,59 +0,0 @@
1/* sound/soc/at32/at32-ssc.h
2 * ASoC SSC interface for Atmel AT32 SoC
3 *
4 * Copyright (C) 2008 Long Range Systems
5 * Geoffrey Wossum <gwossum@acm.org>
6 *
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
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __SOUND_SOC_AT32_AT32_SSC_H
13#define __SOUND_SOC_AT32_AT32_SSC_H __FILE__
14
15#include <linux/types.h>
16#include <linux/atmel-ssc.h>
17
18#include "at32-pcm.h"
19
20
21
22struct at32_ssc_state {
23 u32 ssc_cmr;
24 u32 ssc_rcmr;
25 u32 ssc_rfmr;
26 u32 ssc_tcmr;
27 u32 ssc_tfmr;
28 u32 ssc_sr;
29 u32 ssc_imr;
30};
31
32
33
34struct at32_ssc_info {
35 char *name;
36 struct ssc_device *ssc;
37 spinlock_t lock; /* lock for dir_mask */
38 unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */
39 unsigned short initialized; /* true if SSC has been initialized */
40 unsigned short daifmt;
41 unsigned short cmr_div;
42 unsigned short tcmr_period;
43 unsigned short rcmr_period;
44 struct at32_pcm_dma_params *dma_params[2];
45 struct at32_ssc_state ssc_state;
46};
47
48
49/* SSC divider ids */
50#define AT32_SSC_CMR_DIV 0 /* MCK divider for BCLK */
51#define AT32_SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
52#define AT32_SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
53
54
55extern struct snd_soc_dai at32_ssc_dai[];
56
57
58
59#endif /* __SOUND_SOC_AT32_AT32_SSC_H */
diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig
deleted file mode 100644
index 85a883299c2e..000000000000
--- a/sound/soc/at91/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
1config SND_AT91_SOC
2 tristate "SoC Audio for the Atmel AT91 System-on-Chip"
3 depends on ARCH_AT91
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the AT91 SSC interface. You will also need
7 to select the audio interfaces to support below.
8
9config SND_AT91_SOC_SSC
10 tristate
diff --git a/sound/soc/at91/Makefile b/sound/soc/at91/Makefile
deleted file mode 100644
index b817f11df286..000000000000
--- a/sound/soc/at91/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
1# AT91 Platform Support
2snd-soc-at91-objs := at91-pcm.o
3snd-soc-at91-ssc-objs := at91-ssc.o
4
5obj-$(CONFIG_SND_AT91_SOC) += snd-soc-at91.o
6obj-$(CONFIG_SND_AT91_SOC_SSC) += snd-soc-at91-ssc.o
diff --git a/sound/soc/at91/at91-pcm.c b/sound/soc/at91/at91-pcm.c
deleted file mode 100644
index 7ab48bd25e4c..000000000000
--- a/sound/soc/at91/at91-pcm.c
+++ /dev/null
@@ -1,434 +0,0 @@
1/*
2 * at91-pcm.c -- ALSA PCM interface for the Atmel AT91 SoC
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Mar 3, 2006
7 *
8 * Based on pxa2xx-pcm.c by:
9 *
10 * Author: Nicolas Pitre
11 * Created: Nov 30, 2004
12 * Copyright: (C) 2004 MontaVista Software, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/platform_device.h>
22#include <linux/slab.h>
23#include <linux/dma-mapping.h>
24#include <linux/atmel_pdc.h>
25
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/soc.h>
30
31#include <mach/hardware.h>
32#include <mach/at91_ssc.h>
33
34#include "at91-pcm.h"
35
36#if 0
37#define DBG(x...) printk(KERN_INFO "at91-pcm: " x)
38#else
39#define DBG(x...)
40#endif
41
42static const struct snd_pcm_hardware at91_pcm_hardware = {
43 .info = SNDRV_PCM_INFO_MMAP |
44 SNDRV_PCM_INFO_MMAP_VALID |
45 SNDRV_PCM_INFO_INTERLEAVED |
46 SNDRV_PCM_INFO_PAUSE,
47 .formats = SNDRV_PCM_FMTBIT_S16_LE,
48 .period_bytes_min = 32,
49 .period_bytes_max = 8192,
50 .periods_min = 2,
51 .periods_max = 1024,
52 .buffer_bytes_max = 32 * 1024,
53};
54
55struct at91_runtime_data {
56 struct at91_pcm_dma_params *params;
57 dma_addr_t dma_buffer; /* physical address of dma buffer */
58 dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
59 size_t period_size;
60 dma_addr_t period_ptr; /* physical address of next period */
61 u32 pdc_xpr_save; /* PDC register save */
62 u32 pdc_xcr_save;
63 u32 pdc_xnpr_save;
64 u32 pdc_xncr_save;
65};
66
67static void at91_pcm_dma_irq(u32 ssc_sr,
68 struct snd_pcm_substream *substream)
69{
70 struct at91_runtime_data *prtd = substream->runtime->private_data;
71 struct at91_pcm_dma_params *params = prtd->params;
72 static int count = 0;
73
74 count++;
75
76 if (ssc_sr & params->mask->ssc_endbuf) {
77
78 printk(KERN_WARNING
79 "at91-pcm: buffer %s on %s (SSC_SR=%#x, count=%d)\n",
80 substream->stream == SNDRV_PCM_STREAM_PLAYBACK
81 ? "underrun" : "overrun",
82 params->name, ssc_sr, count);
83
84 /* re-start the PDC */
85 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
86
87 prtd->period_ptr += prtd->period_size;
88 if (prtd->period_ptr >= prtd->dma_buffer_end) {
89 prtd->period_ptr = prtd->dma_buffer;
90 }
91
92 at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->period_ptr);
93 at91_ssc_write(params->ssc_base + params->pdc->xcr,
94 prtd->period_size / params->pdc_xfer_size);
95
96 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
97 }
98
99 if (ssc_sr & params->mask->ssc_endx) {
100
101 /* Load the PDC next pointer and counter registers */
102 prtd->period_ptr += prtd->period_size;
103 if (prtd->period_ptr >= prtd->dma_buffer_end) {
104 prtd->period_ptr = prtd->dma_buffer;
105 }
106 at91_ssc_write(params->ssc_base + params->pdc->xnpr,
107 prtd->period_ptr);
108 at91_ssc_write(params->ssc_base + params->pdc->xncr,
109 prtd->period_size / params->pdc_xfer_size);
110 }
111
112 snd_pcm_period_elapsed(substream);
113}
114
115static int at91_pcm_hw_params(struct snd_pcm_substream *substream,
116 struct snd_pcm_hw_params *params)
117{
118 struct snd_pcm_runtime *runtime = substream->runtime;
119 struct at91_runtime_data *prtd = runtime->private_data;
120 struct snd_soc_pcm_runtime *rtd = substream->private_data;
121
122 /* this may get called several times by oss emulation
123 * with different params */
124
125 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
126 runtime->dma_bytes = params_buffer_bytes(params);
127
128 prtd->params = rtd->dai->cpu_dai->dma_data;
129 prtd->params->dma_intr_handler = at91_pcm_dma_irq;
130
131 prtd->dma_buffer = runtime->dma_addr;
132 prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
133 prtd->period_size = params_period_bytes(params);
134
135 DBG("hw_params: DMA for %s initialized (dma_bytes=%d, period_size=%d)\n",
136 prtd->params->name, runtime->dma_bytes, prtd->period_size);
137 return 0;
138}
139
140static int at91_pcm_hw_free(struct snd_pcm_substream *substream)
141{
142 struct at91_runtime_data *prtd = substream->runtime->private_data;
143 struct at91_pcm_dma_params *params = prtd->params;
144
145 if (params != NULL) {
146 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
147 prtd->params->dma_intr_handler = NULL;
148 }
149
150 return 0;
151}
152
153static int at91_pcm_prepare(struct snd_pcm_substream *substream)
154{
155 struct at91_runtime_data *prtd = substream->runtime->private_data;
156 struct at91_pcm_dma_params *params = prtd->params;
157
158 at91_ssc_write(params->ssc_base + AT91_SSC_IDR,
159 params->mask->ssc_endx | params->mask->ssc_endbuf);
160
161 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
162 return 0;
163}
164
165static int at91_pcm_trigger(struct snd_pcm_substream *substream,
166 int cmd)
167{
168 struct at91_runtime_data *prtd = substream->runtime->private_data;
169 struct at91_pcm_dma_params *params = prtd->params;
170 int ret = 0;
171
172 switch (cmd) {
173 case SNDRV_PCM_TRIGGER_START:
174 prtd->period_ptr = prtd->dma_buffer;
175
176 at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->period_ptr);
177 at91_ssc_write(params->ssc_base + params->pdc->xcr,
178 prtd->period_size / params->pdc_xfer_size);
179
180 prtd->period_ptr += prtd->period_size;
181 at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->period_ptr);
182 at91_ssc_write(params->ssc_base + params->pdc->xncr,
183 prtd->period_size / params->pdc_xfer_size);
184
185 DBG("trigger: period_ptr=%lx, xpr=%lx, xcr=%ld, xnpr=%lx, xncr=%ld\n",
186 (unsigned long) prtd->period_ptr,
187 at91_ssc_read(params->ssc_base + params->pdc->xpr),
188 at91_ssc_read(params->ssc_base + params->pdc->xcr),
189 at91_ssc_read(params->ssc_base + params->pdc->xnpr),
190 at91_ssc_read(params->ssc_base + params->pdc->xncr));
191
192 at91_ssc_write(params->ssc_base + AT91_SSC_IER,
193 params->mask->ssc_endx | params->mask->ssc_endbuf);
194
195 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR,
196 params->mask->pdc_enable);
197
198 DBG("sr=%lx imr=%lx\n",
199 at91_ssc_read(params->ssc_base + AT91_SSC_SR),
200 at91_ssc_read(params->ssc_base + AT91_SSC_IMR));
201 break;
202
203 case SNDRV_PCM_TRIGGER_STOP:
204 case SNDRV_PCM_TRIGGER_SUSPEND:
205 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
206 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
207 break;
208
209 case SNDRV_PCM_TRIGGER_RESUME:
210 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
211 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
212 break;
213
214 default:
215 ret = -EINVAL;
216 }
217
218 return ret;
219}
220
221static snd_pcm_uframes_t at91_pcm_pointer(
222 struct snd_pcm_substream *substream)
223{
224 struct snd_pcm_runtime *runtime = substream->runtime;
225 struct at91_runtime_data *prtd = runtime->private_data;
226 struct at91_pcm_dma_params *params = prtd->params;
227 dma_addr_t ptr;
228 snd_pcm_uframes_t x;
229
230 ptr = (dma_addr_t) at91_ssc_read(params->ssc_base + params->pdc->xpr);
231 x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
232
233 if (x == runtime->buffer_size)
234 x = 0;
235 return x;
236}
237
238static int at91_pcm_open(struct snd_pcm_substream *substream)
239{
240 struct snd_pcm_runtime *runtime = substream->runtime;
241 struct at91_runtime_data *prtd;
242 int ret = 0;
243
244 snd_soc_set_runtime_hwparams(substream, &at91_pcm_hardware);
245
246 /* ensure that buffer size is a multiple of period size */
247 ret = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
248 if (ret < 0)
249 goto out;
250
251 prtd = kzalloc(sizeof(struct at91_runtime_data), GFP_KERNEL);
252 if (prtd == NULL) {
253 ret = -ENOMEM;
254 goto out;
255 }
256 runtime->private_data = prtd;
257
258 out:
259 return ret;
260}
261
262static int at91_pcm_close(struct snd_pcm_substream *substream)
263{
264 struct at91_runtime_data *prtd = substream->runtime->private_data;
265
266 kfree(prtd);
267 return 0;
268}
269
270static int at91_pcm_mmap(struct snd_pcm_substream *substream,
271 struct vm_area_struct *vma)
272{
273 struct snd_pcm_runtime *runtime = substream->runtime;
274
275 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
276 runtime->dma_area,
277 runtime->dma_addr,
278 runtime->dma_bytes);
279}
280
281struct snd_pcm_ops at91_pcm_ops = {
282 .open = at91_pcm_open,
283 .close = at91_pcm_close,
284 .ioctl = snd_pcm_lib_ioctl,
285 .hw_params = at91_pcm_hw_params,
286 .hw_free = at91_pcm_hw_free,
287 .prepare = at91_pcm_prepare,
288 .trigger = at91_pcm_trigger,
289 .pointer = at91_pcm_pointer,
290 .mmap = at91_pcm_mmap,
291};
292
293static int at91_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
294 int stream)
295{
296 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
297 struct snd_dma_buffer *buf = &substream->dma_buffer;
298 size_t size = at91_pcm_hardware.buffer_bytes_max;
299
300 buf->dev.type = SNDRV_DMA_TYPE_DEV;
301 buf->dev.dev = pcm->card->dev;
302 buf->private_data = NULL;
303 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
304 &buf->addr, GFP_KERNEL);
305
306 DBG("preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
307 (void *) buf->area,
308 (void *) buf->addr,
309 size);
310
311 if (!buf->area)
312 return -ENOMEM;
313
314 buf->bytes = size;
315 return 0;
316}
317
318static u64 at91_pcm_dmamask = 0xffffffff;
319
320static int at91_pcm_new(struct snd_card *card,
321 struct snd_soc_dai *dai, struct snd_pcm *pcm)
322{
323 int ret = 0;
324
325 if (!card->dev->dma_mask)
326 card->dev->dma_mask = &at91_pcm_dmamask;
327 if (!card->dev->coherent_dma_mask)
328 card->dev->coherent_dma_mask = 0xffffffff;
329
330 if (dai->playback.channels_min) {
331 ret = at91_pcm_preallocate_dma_buffer(pcm,
332 SNDRV_PCM_STREAM_PLAYBACK);
333 if (ret)
334 goto out;
335 }
336
337 if (dai->capture.channels_min) {
338 ret = at91_pcm_preallocate_dma_buffer(pcm,
339 SNDRV_PCM_STREAM_CAPTURE);
340 if (ret)
341 goto out;
342 }
343 out:
344 return ret;
345}
346
347static void at91_pcm_free_dma_buffers(struct snd_pcm *pcm)
348{
349 struct snd_pcm_substream *substream;
350 struct snd_dma_buffer *buf;
351 int stream;
352
353 for (stream = 0; stream < 2; stream++) {
354 substream = pcm->streams[stream].substream;
355 if (!substream)
356 continue;
357
358 buf = &substream->dma_buffer;
359 if (!buf->area)
360 continue;
361
362 dma_free_writecombine(pcm->card->dev, buf->bytes,
363 buf->area, buf->addr);
364 buf->area = NULL;
365 }
366}
367
368#ifdef CONFIG_PM
369static int at91_pcm_suspend(struct platform_device *pdev,
370 struct snd_soc_dai *dai)
371{
372 struct snd_pcm_runtime *runtime = dai->runtime;
373 struct at91_runtime_data *prtd;
374 struct at91_pcm_dma_params *params;
375
376 if (!runtime)
377 return 0;
378
379 prtd = runtime->private_data;
380 params = prtd->params;
381
382 /* disable the PDC and save the PDC registers */
383
384 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_disable);
385
386 prtd->pdc_xpr_save = at91_ssc_read(params->ssc_base + params->pdc->xpr);
387 prtd->pdc_xcr_save = at91_ssc_read(params->ssc_base + params->pdc->xcr);
388 prtd->pdc_xnpr_save = at91_ssc_read(params->ssc_base + params->pdc->xnpr);
389 prtd->pdc_xncr_save = at91_ssc_read(params->ssc_base + params->pdc->xncr);
390
391 return 0;
392}
393
394static int at91_pcm_resume(struct platform_device *pdev,
395 struct snd_soc_dai *dai)
396{
397 struct snd_pcm_runtime *runtime = dai->runtime;
398 struct at91_runtime_data *prtd;
399 struct at91_pcm_dma_params *params;
400
401 if (!runtime)
402 return 0;
403
404 prtd = runtime->private_data;
405 params = prtd->params;
406
407 /* restore the PDC registers and enable the PDC */
408 at91_ssc_write(params->ssc_base + params->pdc->xpr, prtd->pdc_xpr_save);
409 at91_ssc_write(params->ssc_base + params->pdc->xcr, prtd->pdc_xcr_save);
410 at91_ssc_write(params->ssc_base + params->pdc->xnpr, prtd->pdc_xnpr_save);
411 at91_ssc_write(params->ssc_base + params->pdc->xncr, prtd->pdc_xncr_save);
412
413 at91_ssc_write(params->ssc_base + ATMEL_PDC_PTCR, params->mask->pdc_enable);
414 return 0;
415}
416#else
417#define at91_pcm_suspend NULL
418#define at91_pcm_resume NULL
419#endif
420
421struct snd_soc_platform at91_soc_platform = {
422 .name = "at91-audio",
423 .pcm_ops = &at91_pcm_ops,
424 .pcm_new = at91_pcm_new,
425 .pcm_free = at91_pcm_free_dma_buffers,
426 .suspend = at91_pcm_suspend,
427 .resume = at91_pcm_resume,
428};
429
430EXPORT_SYMBOL_GPL(at91_soc_platform);
431
432MODULE_AUTHOR("Frank Mandarino <fmandarino@endrelia.com>");
433MODULE_DESCRIPTION("Atmel AT91 PCM module");
434MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-pcm.h b/sound/soc/at91/at91-pcm.h
deleted file mode 100644
index e5aada2cb102..000000000000
--- a/sound/soc/at91/at91-pcm.h
+++ /dev/null
@@ -1,72 +0,0 @@
1/*
2 * at91-pcm.h - ALSA PCM interface for the Atmel AT91 SoC
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Mar 3, 2006
7 *
8 * Based on pxa2xx-pcm.h by:
9 *
10 * Author: Nicolas Pitre
11 * Created: Nov 30, 2004
12 * Copyright: MontaVista Software, Inc.
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 */
18
19#ifndef _AT91_PCM_H
20#define _AT91_PCM_H
21
22#include <mach/hardware.h>
23
24struct at91_ssc_periph {
25 void __iomem *base;
26 u32 pid;
27};
28
29/*
30 * Registers and status bits that are required by the PCM driver.
31 */
32struct at91_pdc_regs {
33 unsigned int xpr; /* PDC recv/trans pointer */
34 unsigned int xcr; /* PDC recv/trans counter */
35 unsigned int xnpr; /* PDC next recv/trans pointer */
36 unsigned int xncr; /* PDC next recv/trans counter */
37 unsigned int ptcr; /* PDC transfer control */
38};
39
40struct at91_ssc_mask {
41 u32 ssc_enable; /* SSC recv/trans enable */
42 u32 ssc_disable; /* SSC recv/trans disable */
43 u32 ssc_endx; /* SSC ENDTX or ENDRX */
44 u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */
45 u32 pdc_enable; /* PDC recv/trans enable */
46 u32 pdc_disable; /* PDC recv/trans disable */
47};
48
49/*
50 * This structure, shared between the PCM driver and the interface,
51 * contains all information required by the PCM driver to perform the
52 * PDC DMA operation. All fields except dma_intr_handler() are initialized
53 * by the interface. The dms_intr_handler() pointer is set by the PCM
54 * driver and called by the interface SSC interrupt handler if it is
55 * non-NULL.
56 */
57struct at91_pcm_dma_params {
58 char *name; /* stream identifier */
59 int pdc_xfer_size; /* PDC counter increment in bytes */
60 void __iomem *ssc_base; /* SSC base address */
61 struct at91_pdc_regs *pdc; /* PDC receive or transmit registers */
62 struct at91_ssc_mask *mask;/* SSC & PDC status bits */
63 struct snd_pcm_substream *substream;
64 void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
65};
66
67extern struct snd_soc_platform at91_soc_platform;
68
69#define at91_ssc_read(a) ((unsigned long) __raw_readl(a))
70#define at91_ssc_write(a,v) __raw_writel((v),(a))
71
72#endif /* _AT91_PCM_H */
diff --git a/sound/soc/at91/at91-ssc.c b/sound/soc/at91/at91-ssc.c
deleted file mode 100644
index 1b61cc461261..000000000000
--- a/sound/soc/at91/at91-ssc.c
+++ /dev/null
@@ -1,791 +0,0 @@
1/*
2 * at91-ssc.c -- ALSA SoC AT91 SSC Audio Layer Platform driver
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 *
7 * Based on pxa2xx Platform drivers by
8 * Liam Girdwood <lrg@slimlogic.co.uk>
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
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/interrupt.h>
20#include <linux/device.h>
21#include <linux/delay.h>
22#include <linux/clk.h>
23#include <linux/atmel_pdc.h>
24
25#include <sound/core.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/initval.h>
29#include <sound/soc.h>
30
31#include <mach/hardware.h>
32#include <mach/at91_pmc.h>
33#include <mach/at91_ssc.h>
34
35#include "at91-pcm.h"
36#include "at91-ssc.h"
37
38#if 0
39#define DBG(x...) printk(KERN_DEBUG "at91-ssc:" x)
40#else
41#define DBG(x...)
42#endif
43
44#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
45#define NUM_SSC_DEVICES 1
46#else
47#define NUM_SSC_DEVICES 3
48#endif
49
50
51/*
52 * SSC PDC registers required by the PCM DMA engine.
53 */
54static struct at91_pdc_regs pdc_tx_reg = {
55 .xpr = ATMEL_PDC_TPR,
56 .xcr = ATMEL_PDC_TCR,
57 .xnpr = ATMEL_PDC_TNPR,
58 .xncr = ATMEL_PDC_TNCR,
59};
60
61static struct at91_pdc_regs pdc_rx_reg = {
62 .xpr = ATMEL_PDC_RPR,
63 .xcr = ATMEL_PDC_RCR,
64 .xnpr = ATMEL_PDC_RNPR,
65 .xncr = ATMEL_PDC_RNCR,
66};
67
68/*
69 * SSC & PDC status bits for transmit and receive.
70 */
71static struct at91_ssc_mask ssc_tx_mask = {
72 .ssc_enable = AT91_SSC_TXEN,
73 .ssc_disable = AT91_SSC_TXDIS,
74 .ssc_endx = AT91_SSC_ENDTX,
75 .ssc_endbuf = AT91_SSC_TXBUFE,
76 .pdc_enable = ATMEL_PDC_TXTEN,
77 .pdc_disable = ATMEL_PDC_TXTDIS,
78};
79
80static struct at91_ssc_mask ssc_rx_mask = {
81 .ssc_enable = AT91_SSC_RXEN,
82 .ssc_disable = AT91_SSC_RXDIS,
83 .ssc_endx = AT91_SSC_ENDRX,
84 .ssc_endbuf = AT91_SSC_RXBUFF,
85 .pdc_enable = ATMEL_PDC_RXTEN,
86 .pdc_disable = ATMEL_PDC_RXTDIS,
87};
88
89
90/*
91 * DMA parameters.
92 */
93static struct at91_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
94 {{
95 .name = "SSC0 PCM out",
96 .pdc = &pdc_tx_reg,
97 .mask = &ssc_tx_mask,
98 },
99 {
100 .name = "SSC0 PCM in",
101 .pdc = &pdc_rx_reg,
102 .mask = &ssc_rx_mask,
103 }},
104#if NUM_SSC_DEVICES == 3
105 {{
106 .name = "SSC1 PCM out",
107 .pdc = &pdc_tx_reg,
108 .mask = &ssc_tx_mask,
109 },
110 {
111 .name = "SSC1 PCM in",
112 .pdc = &pdc_rx_reg,
113 .mask = &ssc_rx_mask,
114 }},
115 {{
116 .name = "SSC2 PCM out",
117 .pdc = &pdc_tx_reg,
118 .mask = &ssc_tx_mask,
119 },
120 {
121 .name = "SSC2 PCM in",
122 .pdc = &pdc_rx_reg,
123 .mask = &ssc_rx_mask,
124 }},
125#endif
126};
127
128struct at91_ssc_state {
129 u32 ssc_cmr;
130 u32 ssc_rcmr;
131 u32 ssc_rfmr;
132 u32 ssc_tcmr;
133 u32 ssc_tfmr;
134 u32 ssc_sr;
135 u32 ssc_imr;
136};
137
138static struct at91_ssc_info {
139 char *name;
140 struct at91_ssc_periph ssc;
141 spinlock_t lock; /* lock for dir_mask */
142 unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */
143 unsigned short initialized; /* 1=SSC has been initialized */
144 unsigned short daifmt;
145 unsigned short cmr_div;
146 unsigned short tcmr_period;
147 unsigned short rcmr_period;
148 struct at91_pcm_dma_params *dma_params[2];
149 struct at91_ssc_state ssc_state;
150
151} ssc_info[NUM_SSC_DEVICES] = {
152 {
153 .name = "ssc0",
154 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
155 .dir_mask = 0,
156 .initialized = 0,
157 },
158#if NUM_SSC_DEVICES == 3
159 {
160 .name = "ssc1",
161 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
162 .dir_mask = 0,
163 .initialized = 0,
164 },
165 {
166 .name = "ssc2",
167 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
168 .dir_mask = 0,
169 .initialized = 0,
170 },
171#endif
172};
173
174static unsigned int at91_ssc_sysclk;
175
176/*
177 * SSC interrupt handler. Passes PDC interrupts to the DMA
178 * interrupt handler in the PCM driver.
179 */
180static irqreturn_t at91_ssc_interrupt(int irq, void *dev_id)
181{
182 struct at91_ssc_info *ssc_p = dev_id;
183 struct at91_pcm_dma_params *dma_params;
184 u32 ssc_sr;
185 int i;
186
187 ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR)
188 & at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
189
190 /*
191 * Loop through the substreams attached to this SSC. If
192 * a DMA-related interrupt occurred on that substream, call
193 * the DMA interrupt handler function, if one has been
194 * registered in the dma_params structure by the PCM driver.
195 */
196 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
197 dma_params = ssc_p->dma_params[i];
198
199 if (dma_params != NULL && dma_params->dma_intr_handler != NULL &&
200 (ssc_sr &
201 (dma_params->mask->ssc_endx | dma_params->mask->ssc_endbuf)))
202
203 dma_params->dma_intr_handler(ssc_sr, dma_params->substream);
204 }
205
206 return IRQ_HANDLED;
207}
208
209/*
210 * Startup. Only that one substream allowed in each direction.
211 */
212static int at91_ssc_startup(struct snd_pcm_substream *substream)
213{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
216 int dir_mask;
217
218 DBG("ssc_startup: SSC_SR=0x%08lx\n",
219 at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
220 dir_mask = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0x1 : 0x2;
221
222 spin_lock_irq(&ssc_p->lock);
223 if (ssc_p->dir_mask & dir_mask) {
224 spin_unlock_irq(&ssc_p->lock);
225 return -EBUSY;
226 }
227 ssc_p->dir_mask |= dir_mask;
228 spin_unlock_irq(&ssc_p->lock);
229
230 return 0;
231}
232
233/*
234 * Shutdown. Clear DMA parameters and shutdown the SSC if there
235 * are no other substreams open.
236 */
237static void at91_ssc_shutdown(struct snd_pcm_substream *substream)
238{
239 struct snd_soc_pcm_runtime *rtd = substream->private_data;
240 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
241 struct at91_pcm_dma_params *dma_params;
242 int dir, dir_mask;
243
244 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
245 dma_params = ssc_p->dma_params[dir];
246
247 if (dma_params != NULL) {
248 at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
249 dma_params->mask->ssc_disable);
250 DBG("%s disabled SSC_SR=0x%08lx\n", (dir ? "receive" : "transmit"),
251 at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR));
252
253 dma_params->ssc_base = NULL;
254 dma_params->substream = NULL;
255 ssc_p->dma_params[dir] = NULL;
256 }
257
258 dir_mask = 1 << dir;
259
260 spin_lock_irq(&ssc_p->lock);
261 ssc_p->dir_mask &= ~dir_mask;
262 if (!ssc_p->dir_mask) {
263 /* Shutdown the SSC clock. */
264 DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
265 at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
266
267 if (ssc_p->initialized) {
268 free_irq(ssc_p->ssc.pid, ssc_p);
269 ssc_p->initialized = 0;
270 }
271
272 /* Reset the SSC */
273 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
274
275 /* Clear the SSC dividers */
276 ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
277 }
278 spin_unlock_irq(&ssc_p->lock);
279}
280
281/*
282 * Record the SSC system clock rate.
283 */
284static int at91_ssc_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
285 int clk_id, unsigned int freq, int dir)
286{
287 /*
288 * The only clock supplied to the SSC is the AT91 master clock,
289 * which is only used if the SSC is generating BCLK and/or
290 * LRC clocks.
291 */
292 switch (clk_id) {
293 case AT91_SYSCLK_MCK:
294 at91_ssc_sysclk = freq;
295 break;
296 default:
297 return -EINVAL;
298 }
299
300 return 0;
301}
302
303/*
304 * Record the DAI format for use in hw_params().
305 */
306static int at91_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
307 unsigned int fmt)
308{
309 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
310
311 ssc_p->daifmt = fmt;
312 return 0;
313}
314
315/*
316 * Record SSC clock dividers for use in hw_params().
317 */
318static int at91_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
319 int div_id, int div)
320{
321 struct at91_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
322
323 switch (div_id) {
324 case AT91SSC_CMR_DIV:
325 /*
326 * The same master clock divider is used for both
327 * transmit and receive, so if a value has already
328 * been set, it must match this value.
329 */
330 if (ssc_p->cmr_div == 0)
331 ssc_p->cmr_div = div;
332 else
333 if (div != ssc_p->cmr_div)
334 return -EBUSY;
335 break;
336
337 case AT91SSC_TCMR_PERIOD:
338 ssc_p->tcmr_period = div;
339 break;
340
341 case AT91SSC_RCMR_PERIOD:
342 ssc_p->rcmr_period = div;
343 break;
344
345 default:
346 return -EINVAL;
347 }
348
349 return 0;
350}
351
352/*
353 * Configure the SSC.
354 */
355static int at91_ssc_hw_params(struct snd_pcm_substream *substream,
356 struct snd_pcm_hw_params *params)
357{
358 struct snd_soc_pcm_runtime *rtd = substream->private_data;
359 int id = rtd->dai->cpu_dai->id;
360 struct at91_ssc_info *ssc_p = &ssc_info[id];
361 struct at91_pcm_dma_params *dma_params;
362 int dir, channels, bits;
363 u32 tfmr, rfmr, tcmr, rcmr;
364 int start_event;
365 int ret;
366
367 /*
368 * Currently, there is only one set of dma params for
369 * each direction. If more are added, this code will
370 * have to be changed to select the proper set.
371 */
372 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
373
374 dma_params = &ssc_dma_params[id][dir];
375 dma_params->ssc_base = ssc_p->ssc.base;
376 dma_params->substream = substream;
377
378 ssc_p->dma_params[dir] = dma_params;
379
380 /*
381 * The cpu_dai->dma_data field is only used to communicate the
382 * appropriate DMA parameters to the pcm driver hw_params()
383 * function. It should not be used for other purposes
384 * as it is common to all substreams.
385 */
386 rtd->dai->cpu_dai->dma_data = dma_params;
387
388 channels = params_channels(params);
389
390 /*
391 * Determine sample size in bits and the PDC increment.
392 */
393 switch(params_format(params)) {
394 case SNDRV_PCM_FORMAT_S8:
395 bits = 8;
396 dma_params->pdc_xfer_size = 1;
397 break;
398 case SNDRV_PCM_FORMAT_S16_LE:
399 bits = 16;
400 dma_params->pdc_xfer_size = 2;
401 break;
402 case SNDRV_PCM_FORMAT_S24_LE:
403 bits = 24;
404 dma_params->pdc_xfer_size = 4;
405 break;
406 case SNDRV_PCM_FORMAT_S32_LE:
407 bits = 32;
408 dma_params->pdc_xfer_size = 4;
409 break;
410 default:
411 printk(KERN_WARNING "at91-ssc: unsupported PCM format\n");
412 return -EINVAL;
413 }
414
415 /*
416 * The SSC only supports up to 16-bit samples in I2S format, due
417 * to the size of the Frame Mode Register FSLEN field.
418 */
419 if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
420 && bits > 16) {
421 printk(KERN_WARNING
422 "at91-ssc: sample size %d is too large for I2S\n", bits);
423 return -EINVAL;
424 }
425
426 /*
427 * Compute SSC register settings.
428 */
429 switch (ssc_p->daifmt
430 & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
431
432 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
433 /*
434 * I2S format, SSC provides BCLK and LRC clocks.
435 *
436 * The SSC transmit and receive clocks are generated from the
437 * MCK divider, and the BCLK signal is output on the SSC TK line.
438 */
439 rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD)
440 | (( 1 << 16) & AT91_SSC_STTDLY)
441 | (( AT91_SSC_START_FALLING_RF ) & AT91_SSC_START)
442 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
443 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
444 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
445
446 rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
447 | (( AT91_SSC_FSOS_NEGATIVE ) & AT91_SSC_FSOS)
448 | (((bits - 1) << 16) & AT91_SSC_FSLEN)
449 | (((channels - 1) << 8) & AT91_SSC_DATNB)
450 | (( 1 << 7) & AT91_SSC_MSBF)
451 | (( 0 << 5) & AT91_SSC_LOOP)
452 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
453
454 tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD)
455 | (( 1 << 16) & AT91_SSC_STTDLY)
456 | (( AT91_SSC_START_FALLING_RF ) & AT91_SSC_START)
457 | (( AT91_SSC_CKI_FALLING ) & AT91_SSC_CKI)
458 | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO)
459 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
460
461 tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
462 | (( 0 << 23) & AT91_SSC_FSDEN)
463 | (( AT91_SSC_FSOS_NEGATIVE ) & AT91_SSC_FSOS)
464 | (((bits - 1) << 16) & AT91_SSC_FSLEN)
465 | (((channels - 1) << 8) & AT91_SSC_DATNB)
466 | (( 1 << 7) & AT91_SSC_MSBF)
467 | (( 0 << 5) & AT91_SSC_DATDEF)
468 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
469 break;
470
471 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
472 /*
473 * I2S format, CODEC supplies BCLK and LRC clocks.
474 *
475 * The SSC transmit clock is obtained from the BCLK signal on
476 * on the TK line, and the SSC receive clock is generated from the
477 * transmit clock.
478 *
479 * For single channel data, one sample is transferred on the falling
480 * edge of the LRC clock. For two channel data, one sample is
481 * transferred on both edges of the LRC clock.
482 */
483 start_event = channels == 1
484 ? AT91_SSC_START_FALLING_RF
485 : AT91_SSC_START_EDGE_RF;
486
487 rcmr = (( 0 << 24) & AT91_SSC_PERIOD)
488 | (( 1 << 16) & AT91_SSC_STTDLY)
489 | (( start_event ) & AT91_SSC_START)
490 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
491 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
492 | (( AT91_SSC_CKS_CLOCK ) & AT91_SSC_CKS);
493
494 rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
495 | (( AT91_SSC_FSOS_NONE ) & AT91_SSC_FSOS)
496 | (( 0 << 16) & AT91_SSC_FSLEN)
497 | (( 0 << 8) & AT91_SSC_DATNB)
498 | (( 1 << 7) & AT91_SSC_MSBF)
499 | (( 0 << 5) & AT91_SSC_LOOP)
500 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
501
502 tcmr = (( 0 << 24) & AT91_SSC_PERIOD)
503 | (( 1 << 16) & AT91_SSC_STTDLY)
504 | (( start_event ) & AT91_SSC_START)
505 | (( AT91_SSC_CKI_FALLING ) & AT91_SSC_CKI)
506 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
507 | (( AT91_SSC_CKS_PIN ) & AT91_SSC_CKS);
508
509 tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
510 | (( 0 << 23) & AT91_SSC_FSDEN)
511 | (( AT91_SSC_FSOS_NONE ) & AT91_SSC_FSOS)
512 | (( 0 << 16) & AT91_SSC_FSLEN)
513 | (( 0 << 8) & AT91_SSC_DATNB)
514 | (( 1 << 7) & AT91_SSC_MSBF)
515 | (( 0 << 5) & AT91_SSC_DATDEF)
516 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
517 break;
518
519 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
520 /*
521 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
522 *
523 * The SSC transmit and receive clocks are generated from the
524 * MCK divider, and the BCLK signal is output on the SSC TK line.
525 */
526 rcmr = (( ssc_p->rcmr_period << 24) & AT91_SSC_PERIOD)
527 | (( 1 << 16) & AT91_SSC_STTDLY)
528 | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START)
529 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
530 | (( AT91_SSC_CKO_NONE ) & AT91_SSC_CKO)
531 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
532
533 rfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
534 | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS)
535 | (( 0 << 16) & AT91_SSC_FSLEN)
536 | (((channels - 1) << 8) & AT91_SSC_DATNB)
537 | (( 1 << 7) & AT91_SSC_MSBF)
538 | (( 0 << 5) & AT91_SSC_LOOP)
539 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
540
541 tcmr = (( ssc_p->tcmr_period << 24) & AT91_SSC_PERIOD)
542 | (( 1 << 16) & AT91_SSC_STTDLY)
543 | (( AT91_SSC_START_RISING_RF ) & AT91_SSC_START)
544 | (( AT91_SSC_CK_RISING ) & AT91_SSC_CKI)
545 | (( AT91_SSC_CKO_CONTINUOUS ) & AT91_SSC_CKO)
546 | (( AT91_SSC_CKS_DIV ) & AT91_SSC_CKS);
547
548 tfmr = (( AT91_SSC_FSEDGE_POSITIVE ) & AT91_SSC_FSEDGE)
549 | (( 0 << 23) & AT91_SSC_FSDEN)
550 | (( AT91_SSC_FSOS_POSITIVE ) & AT91_SSC_FSOS)
551 | (( 0 << 16) & AT91_SSC_FSLEN)
552 | (((channels - 1) << 8) & AT91_SSC_DATNB)
553 | (( 1 << 7) & AT91_SSC_MSBF)
554 | (( 0 << 5) & AT91_SSC_DATDEF)
555 | (((bits - 1) << 0) & AT91_SSC_DATALEN);
556
557
558
559 break;
560
561 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
562 default:
563 printk(KERN_WARNING "at91-ssc: unsupported DAI format 0x%x.\n",
564 ssc_p->daifmt);
565 return -EINVAL;
566 break;
567 }
568 DBG("RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", rcmr, rfmr, tcmr, tfmr);
569
570 if (!ssc_p->initialized) {
571
572 /* Enable PMC peripheral clock for this SSC */
573 DBG("Starting pid %d clock\n", ssc_p->ssc.pid);
574 at91_sys_write(AT91_PMC_PCER, 1<<ssc_p->ssc.pid);
575
576 /* Reset the SSC and its PDC registers */
577 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR, AT91_SSC_SWRST);
578
579 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RPR, 0);
580 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RCR, 0);
581 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNPR, 0);
582 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_RNCR, 0);
583 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TPR, 0);
584 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TCR, 0);
585 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNPR, 0);
586 at91_ssc_write(ssc_p->ssc.base + ATMEL_PDC_TNCR, 0);
587
588 if ((ret = request_irq(ssc_p->ssc.pid, at91_ssc_interrupt,
589 0, ssc_p->name, ssc_p)) < 0) {
590 printk(KERN_WARNING "at91-ssc: request_irq failure\n");
591
592 DBG("Stopping pid %d clock\n", ssc_p->ssc.pid);
593 at91_sys_write(AT91_PMC_PCDR, 1<<ssc_p->ssc.pid);
594 return ret;
595 }
596
597 ssc_p->initialized = 1;
598 }
599
600 /* set SSC clock mode register */
601 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->cmr_div);
602
603 /* set receive clock mode and format */
604 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, rcmr);
605 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, rfmr);
606
607 /* set transmit clock mode and format */
608 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, tcmr);
609 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, tfmr);
610
611 DBG("hw_params: SSC initialized\n");
612 return 0;
613}
614
615
616static int at91_ssc_prepare(struct snd_pcm_substream *substream)
617{
618 struct snd_soc_pcm_runtime *rtd = substream->private_data;
619 struct at91_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
620 struct at91_pcm_dma_params *dma_params;
621 int dir;
622
623 dir = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1;
624 dma_params = ssc_p->dma_params[dir];
625
626 at91_ssc_write(dma_params->ssc_base + AT91_SSC_CR,
627 dma_params->mask->ssc_enable);
628
629 DBG("%s enabled SSC_SR=0x%08lx\n", dir ? "receive" : "transmit",
630 at91_ssc_read(dma_params->ssc_base + AT91_SSC_SR));
631 return 0;
632}
633
634
635#ifdef CONFIG_PM
636static int at91_ssc_suspend(struct platform_device *pdev,
637 struct snd_soc_dai *cpu_dai)
638{
639 struct at91_ssc_info *ssc_p;
640
641 if(!cpu_dai->active)
642 return 0;
643
644 ssc_p = &ssc_info[cpu_dai->id];
645
646 /* Save the status register before disabling transmit and receive. */
647 ssc_p->ssc_state.ssc_sr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_SR);
648 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
649 AT91_SSC_TXDIS | AT91_SSC_RXDIS);
650
651 /* Save the current interrupt mask, then disable unmasked interrupts. */
652 ssc_p->ssc_state.ssc_imr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_IMR);
653 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IDR, ssc_p->ssc_state.ssc_imr);
654
655 ssc_p->ssc_state.ssc_cmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_CMR);
656 ssc_p->ssc_state.ssc_rcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RCMR);
657 ssc_p->ssc_state.ssc_rfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_RFMR);
658 ssc_p->ssc_state.ssc_tcmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TCMR);
659 ssc_p->ssc_state.ssc_tfmr = at91_ssc_read(ssc_p->ssc.base + AT91_SSC_TFMR);
660
661 return 0;
662}
663
664static int at91_ssc_resume(struct platform_device *pdev,
665 struct snd_soc_dai *cpu_dai)
666{
667 struct at91_ssc_info *ssc_p;
668
669 if(!cpu_dai->active)
670 return 0;
671
672 ssc_p = &ssc_info[cpu_dai->id];
673
674 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TFMR, ssc_p->ssc_state.ssc_tfmr);
675 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_TCMR, ssc_p->ssc_state.ssc_tcmr);
676 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RFMR, ssc_p->ssc_state.ssc_rfmr);
677 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_RCMR, ssc_p->ssc_state.ssc_rcmr);
678 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CMR, ssc_p->ssc_state.ssc_cmr);
679
680 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_IER, ssc_p->ssc_state.ssc_imr);
681
682 at91_ssc_write(ssc_p->ssc.base + AT91_SSC_CR,
683 ((ssc_p->ssc_state.ssc_sr & AT91_SSC_RXENA) ? AT91_SSC_RXEN : 0) |
684 ((ssc_p->ssc_state.ssc_sr & AT91_SSC_TXENA) ? AT91_SSC_TXEN : 0));
685
686 return 0;
687}
688
689#else
690#define at91_ssc_suspend NULL
691#define at91_ssc_resume NULL
692#endif
693
694#define AT91_SSC_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
695 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
696 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
697 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
698 SNDRV_PCM_RATE_96000)
699
700#define AT91_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
701 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
702
703struct snd_soc_dai at91_ssc_dai[NUM_SSC_DEVICES] = {
704 { .name = "at91-ssc0",
705 .id = 0,
706 .type = SND_SOC_DAI_PCM,
707 .suspend = at91_ssc_suspend,
708 .resume = at91_ssc_resume,
709 .playback = {
710 .channels_min = 1,
711 .channels_max = 2,
712 .rates = AT91_SSC_RATES,
713 .formats = AT91_SSC_FORMATS,},
714 .capture = {
715 .channels_min = 1,
716 .channels_max = 2,
717 .rates = AT91_SSC_RATES,
718 .formats = AT91_SSC_FORMATS,},
719 .ops = {
720 .startup = at91_ssc_startup,
721 .shutdown = at91_ssc_shutdown,
722 .prepare = at91_ssc_prepare,
723 .hw_params = at91_ssc_hw_params,},
724 .dai_ops = {
725 .set_sysclk = at91_ssc_set_dai_sysclk,
726 .set_fmt = at91_ssc_set_dai_fmt,
727 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
728 .private_data = &ssc_info[0].ssc,
729 },
730#if NUM_SSC_DEVICES == 3
731 { .name = "at91-ssc1",
732 .id = 1,
733 .type = SND_SOC_DAI_PCM,
734 .suspend = at91_ssc_suspend,
735 .resume = at91_ssc_resume,
736 .playback = {
737 .channels_min = 1,
738 .channels_max = 2,
739 .rates = AT91_SSC_RATES,
740 .formats = AT91_SSC_FORMATS,},
741 .capture = {
742 .channels_min = 1,
743 .channels_max = 2,
744 .rates = AT91_SSC_RATES,
745 .formats = AT91_SSC_FORMATS,},
746 .ops = {
747 .startup = at91_ssc_startup,
748 .shutdown = at91_ssc_shutdown,
749 .prepare = at91_ssc_prepare,
750 .hw_params = at91_ssc_hw_params,},
751 .dai_ops = {
752 .set_sysclk = at91_ssc_set_dai_sysclk,
753 .set_fmt = at91_ssc_set_dai_fmt,
754 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
755 .private_data = &ssc_info[1].ssc,
756 },
757 { .name = "at91-ssc2",
758 .id = 2,
759 .type = SND_SOC_DAI_PCM,
760 .suspend = at91_ssc_suspend,
761 .resume = at91_ssc_resume,
762 .playback = {
763 .channels_min = 1,
764 .channels_max = 2,
765 .rates = AT91_SSC_RATES,
766 .formats = AT91_SSC_FORMATS,},
767 .capture = {
768 .channels_min = 1,
769 .channels_max = 2,
770 .rates = AT91_SSC_RATES,
771 .formats = AT91_SSC_FORMATS,},
772 .ops = {
773 .startup = at91_ssc_startup,
774 .shutdown = at91_ssc_shutdown,
775 .prepare = at91_ssc_prepare,
776 .hw_params = at91_ssc_hw_params,},
777 .dai_ops = {
778 .set_sysclk = at91_ssc_set_dai_sysclk,
779 .set_fmt = at91_ssc_set_dai_fmt,
780 .set_clkdiv = at91_ssc_set_dai_clkdiv,},
781 .private_data = &ssc_info[2].ssc,
782 },
783#endif
784};
785
786EXPORT_SYMBOL_GPL(at91_ssc_dai);
787
788/* Module information */
789MODULE_AUTHOR("Frank Mandarino, fmandarino@endrelia.com, www.endrelia.com");
790MODULE_DESCRIPTION("AT91 SSC ASoC Interface");
791MODULE_LICENSE("GPL");
diff --git a/sound/soc/at91/at91-ssc.h b/sound/soc/at91/at91-ssc.h
deleted file mode 100644
index 6b7bf382d06f..000000000000
--- a/sound/soc/at91/at91-ssc.h
+++ /dev/null
@@ -1,27 +0,0 @@
1/*
2 * at91-ssc.h - ALSA SSC interface for the Atmel AT91 SoC
3 *
4 * Author: Frank Mandarino <fmandarino@endrelia.com>
5 * Endrelia Technologies Inc.
6 * Created: Jan 9, 2007
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
13#ifndef _AT91_SSC_H
14#define _AT91_SSC_H
15
16/* SSC system clock ids */
17#define AT91_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */
18
19/* SSC divider ids */
20#define AT91SSC_CMR_DIV 0 /* MCK divider for BCLK */
21#define AT91SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
22#define AT91SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
23
24extern struct snd_soc_dai at91_ssc_dai[];
25
26#endif /* _AT91_SSC_H */
27
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig
new file mode 100644
index 000000000000..a608d7009dbd
--- /dev/null
+++ b/sound/soc/atmel/Kconfig
@@ -0,0 +1,43 @@
1config SND_ATMEL_SOC
2 tristate "SoC Audio for the Atmel System-on-Chip"
3 depends on ARCH_AT91 || AVR32
4 help
5 Say Y or M if you want to add support for codecs attached to
6 the ATMEL SSC interface. You will also need
7 to select the audio interfaces to support below.
8
9config SND_ATMEL_SOC_SSC
10 tristate
11 depends on SND_ATMEL_SOC
12 help
13 Say Y or M if you want to add support for codecs the
14 ATMEL SSC interface. You will also needs to select the individual
15 machine drivers to support below.
16
17config SND_AT91_SOC_SAM9G20_WM8731
18 tristate "SoC Audio support for WM8731-based At91sam9g20 evaluation board"
19 depends on ATMEL_SSC && ARCH_AT91SAM9G20 && SND_ATMEL_SOC
20 select SND_ATMEL_SOC_SSC
21 select SND_SOC_WM8731
22 help
23 Say Y if you want to add support for SoC audio on WM8731-based
24 AT91sam9g20 evaluation board.
25
26config SND_AT32_SOC_PLAYPAQ
27 tristate "SoC Audio support for PlayPaq with WM8510"
28 depends on SND_ATMEL_SOC && BOARD_PLAYPAQ
29 select SND_ATMEL_SOC_SSC
30 select SND_SOC_WM8510
31 help
32 Say Y or M here if you want to add support for SoC audio
33 on the LRS PlayPaq.
34
35config SND_AT32_SOC_PLAYPAQ_SLAVE
36 bool "Run CODEC on PlayPaq in slave mode"
37 depends on SND_AT32_SOC_PLAYPAQ
38 default n
39 help
40 Say Y if you want to run with the AT32 SSC generating the BCLK
41 and FRAME signals on the PlayPaq. Unless you want to play
42 with the AT32 as the SSC master, you probably want to say N here,
43 as this will give you better sound quality.
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile
new file mode 100644
index 000000000000..f54a7cc68e66
--- /dev/null
+++ b/sound/soc/atmel/Makefile
@@ -0,0 +1,15 @@
1# AT91 Platform Support
2snd-soc-atmel-pcm-objs := atmel-pcm.o
3snd-soc-atmel_ssc_dai-objs := atmel_ssc_dai.o
4
5obj-$(CONFIG_SND_ATMEL_SOC) += snd-soc-atmel-pcm.o
6obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o
7
8# AT91 Machine Support
9snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o
10
11# AT32 Machine Support
12snd-soc-playpaq-objs := playpaq_wm8510.o
13
14obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o
15obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c
new file mode 100644
index 000000000000..1fac5efd285b
--- /dev/null
+++ b/sound/soc/atmel/atmel-pcm.c
@@ -0,0 +1,494 @@
1/*
2 * atmel-pcm.c -- ALSA PCM interface for the Atmel atmel SoC.
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 *
9 * Based on at91-pcm. by:
10 * Frank Mandarino <fmandarino@endrelia.com>
11 * Copyright 2006 Endrelia Technologies Inc.
12 *
13 * Based on pxa2xx-pcm.c by:
14 *
15 * Author: Nicolas Pitre
16 * Created: Nov 30, 2004
17 * Copyright: (C) 2004 MontaVista Software, Inc.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34#include <linux/module.h>
35#include <linux/init.h>
36#include <linux/platform_device.h>
37#include <linux/slab.h>
38#include <linux/dma-mapping.h>
39#include <linux/atmel_pdc.h>
40#include <linux/atmel-ssc.h>
41
42#include <sound/core.h>
43#include <sound/pcm.h>
44#include <sound/pcm_params.h>
45#include <sound/soc.h>
46
47#include <mach/hardware.h>
48
49#include "atmel-pcm.h"
50
51
52/*--------------------------------------------------------------------------*\
53 * Hardware definition
54\*--------------------------------------------------------------------------*/
55/* TODO: These values were taken from the AT91 platform driver, check
56 * them against real values for AT32
57 */
58static const struct snd_pcm_hardware atmel_pcm_hardware = {
59 .info = SNDRV_PCM_INFO_MMAP |
60 SNDRV_PCM_INFO_MMAP_VALID |
61 SNDRV_PCM_INFO_INTERLEAVED |
62 SNDRV_PCM_INFO_PAUSE,
63 .formats = SNDRV_PCM_FMTBIT_S16_LE,
64 .period_bytes_min = 32,
65 .period_bytes_max = 8192,
66 .periods_min = 2,
67 .periods_max = 1024,
68 .buffer_bytes_max = 32 * 1024,
69};
70
71
72/*--------------------------------------------------------------------------*\
73 * Data types
74\*--------------------------------------------------------------------------*/
75struct atmel_runtime_data {
76 struct atmel_pcm_dma_params *params;
77 dma_addr_t dma_buffer; /* physical address of dma buffer */
78 dma_addr_t dma_buffer_end; /* first address beyond DMA buffer */
79 size_t period_size;
80
81 dma_addr_t period_ptr; /* physical address of next period */
82 int periods; /* period index of period_ptr */
83
84 /* PDC register save */
85 u32 pdc_xpr_save;
86 u32 pdc_xcr_save;
87 u32 pdc_xnpr_save;
88 u32 pdc_xncr_save;
89};
90
91
92/*--------------------------------------------------------------------------*\
93 * Helper functions
94\*--------------------------------------------------------------------------*/
95static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm,
96 int stream)
97{
98 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
99 struct snd_dma_buffer *buf = &substream->dma_buffer;
100 size_t size = atmel_pcm_hardware.buffer_bytes_max;
101
102 buf->dev.type = SNDRV_DMA_TYPE_DEV;
103 buf->dev.dev = pcm->card->dev;
104 buf->private_data = NULL;
105 buf->area = dma_alloc_coherent(pcm->card->dev, size,
106 &buf->addr, GFP_KERNEL);
107 pr_debug("atmel-pcm:"
108 "preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
109 (void *) buf->area,
110 (void *) buf->addr,
111 size);
112
113 if (!buf->area)
114 return -ENOMEM;
115
116 buf->bytes = size;
117 return 0;
118}
119/*--------------------------------------------------------------------------*\
120 * ISR
121\*--------------------------------------------------------------------------*/
122static void atmel_pcm_dma_irq(u32 ssc_sr,
123 struct snd_pcm_substream *substream)
124{
125 struct atmel_runtime_data *prtd = substream->runtime->private_data;
126 struct atmel_pcm_dma_params *params = prtd->params;
127 static int count;
128
129 count++;
130
131 if (ssc_sr & params->mask->ssc_endbuf) {
132 pr_warning("atmel-pcm: buffer %s on %s"
133 " (SSC_SR=%#x, count=%d)\n",
134 substream->stream == SNDRV_PCM_STREAM_PLAYBACK
135 ? "underrun" : "overrun",
136 params->name, ssc_sr, count);
137
138 /* re-start the PDC */
139 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
140 params->mask->pdc_disable);
141 prtd->period_ptr += prtd->period_size;
142 if (prtd->period_ptr >= prtd->dma_buffer_end)
143 prtd->period_ptr = prtd->dma_buffer;
144
145 ssc_writex(params->ssc->regs, params->pdc->xpr,
146 prtd->period_ptr);
147 ssc_writex(params->ssc->regs, params->pdc->xcr,
148 prtd->period_size / params->pdc_xfer_size);
149 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
150 params->mask->pdc_enable);
151 }
152
153 if (ssc_sr & params->mask->ssc_endx) {
154 /* Load the PDC next pointer and counter registers */
155 prtd->period_ptr += prtd->period_size;
156 if (prtd->period_ptr >= prtd->dma_buffer_end)
157 prtd->period_ptr = prtd->dma_buffer;
158
159 ssc_writex(params->ssc->regs, params->pdc->xnpr,
160 prtd->period_ptr);
161 ssc_writex(params->ssc->regs, params->pdc->xncr,
162 prtd->period_size / params->pdc_xfer_size);
163 }
164
165 snd_pcm_period_elapsed(substream);
166}
167
168
169/*--------------------------------------------------------------------------*\
170 * PCM operations
171\*--------------------------------------------------------------------------*/
172static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
173 struct snd_pcm_hw_params *params)
174{
175 struct snd_pcm_runtime *runtime = substream->runtime;
176 struct atmel_runtime_data *prtd = runtime->private_data;
177 struct snd_soc_pcm_runtime *rtd = substream->private_data;
178
179 /* this may get called several times by oss emulation
180 * with different params */
181
182 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
183 runtime->dma_bytes = params_buffer_bytes(params);
184
185 prtd->params = rtd->dai->cpu_dai->dma_data;
186 prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
187
188 prtd->dma_buffer = runtime->dma_addr;
189 prtd->dma_buffer_end = runtime->dma_addr + runtime->dma_bytes;
190 prtd->period_size = params_period_bytes(params);
191
192 pr_debug("atmel-pcm: "
193 "hw_params: DMA for %s initialized "
194 "(dma_bytes=%u, period_size=%u)\n",
195 prtd->params->name,
196 runtime->dma_bytes,
197 prtd->period_size);
198 return 0;
199}
200
201static int atmel_pcm_hw_free(struct snd_pcm_substream *substream)
202{
203 struct atmel_runtime_data *prtd = substream->runtime->private_data;
204 struct atmel_pcm_dma_params *params = prtd->params;
205
206 if (params != NULL) {
207 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
208 params->mask->pdc_disable);
209 prtd->params->dma_intr_handler = NULL;
210 }
211
212 return 0;
213}
214
215static int atmel_pcm_prepare(struct snd_pcm_substream *substream)
216{
217 struct atmel_runtime_data *prtd = substream->runtime->private_data;
218 struct atmel_pcm_dma_params *params = prtd->params;
219
220 ssc_writex(params->ssc->regs, SSC_IDR,
221 params->mask->ssc_endx | params->mask->ssc_endbuf);
222 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
223 params->mask->pdc_disable);
224 return 0;
225}
226
227static int atmel_pcm_trigger(struct snd_pcm_substream *substream,
228 int cmd)
229{
230 struct snd_pcm_runtime *rtd = substream->runtime;
231 struct atmel_runtime_data *prtd = rtd->private_data;
232 struct atmel_pcm_dma_params *params = prtd->params;
233 int ret = 0;
234
235 pr_debug("atmel-pcm:buffer_size = %ld,"
236 "dma_area = %p, dma_bytes = %u\n",
237 rtd->buffer_size, rtd->dma_area, rtd->dma_bytes);
238
239 switch (cmd) {
240 case SNDRV_PCM_TRIGGER_START:
241 prtd->period_ptr = prtd->dma_buffer;
242
243 ssc_writex(params->ssc->regs, params->pdc->xpr,
244 prtd->period_ptr);
245 ssc_writex(params->ssc->regs, params->pdc->xcr,
246 prtd->period_size / params->pdc_xfer_size);
247
248 prtd->period_ptr += prtd->period_size;
249 ssc_writex(params->ssc->regs, params->pdc->xnpr,
250 prtd->period_ptr);
251 ssc_writex(params->ssc->regs, params->pdc->xncr,
252 prtd->period_size / params->pdc_xfer_size);
253
254 pr_debug("atmel-pcm: trigger: "
255 "period_ptr=%lx, xpr=%u, "
256 "xcr=%u, xnpr=%u, xncr=%u\n",
257 (unsigned long)prtd->period_ptr,
258 ssc_readx(params->ssc->regs, params->pdc->xpr),
259 ssc_readx(params->ssc->regs, params->pdc->xcr),
260 ssc_readx(params->ssc->regs, params->pdc->xnpr),
261 ssc_readx(params->ssc->regs, params->pdc->xncr));
262
263 ssc_writex(params->ssc->regs, SSC_IER,
264 params->mask->ssc_endx | params->mask->ssc_endbuf);
265 ssc_writex(params->ssc->regs, SSC_PDC_PTCR,
266 params->mask->pdc_enable);
267
268 pr_debug("sr=%u imr=%u\n",
269 ssc_readx(params->ssc->regs, SSC_SR),
270 ssc_readx(params->ssc->regs, SSC_IER));
271 break; /* SNDRV_PCM_TRIGGER_START */
272
273 case SNDRV_PCM_TRIGGER_STOP:
274 case SNDRV_PCM_TRIGGER_SUSPEND:
275 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
276 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
277 params->mask->pdc_disable);
278 break;
279
280 case SNDRV_PCM_TRIGGER_RESUME:
281 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
282 ssc_writex(params->ssc->regs, ATMEL_PDC_PTCR,
283 params->mask->pdc_enable);
284 break;
285
286 default:
287 ret = -EINVAL;
288 }
289
290 return ret;
291}
292
293static snd_pcm_uframes_t atmel_pcm_pointer(
294 struct snd_pcm_substream *substream)
295{
296 struct snd_pcm_runtime *runtime = substream->runtime;
297 struct atmel_runtime_data *prtd = runtime->private_data;
298 struct atmel_pcm_dma_params *params = prtd->params;
299 dma_addr_t ptr;
300 snd_pcm_uframes_t x;
301
302 ptr = (dma_addr_t) ssc_readx(params->ssc->regs, params->pdc->xpr);
303 x = bytes_to_frames(runtime, ptr - prtd->dma_buffer);
304
305 if (x == runtime->buffer_size)
306 x = 0;
307
308 return x;
309}
310
311static int atmel_pcm_open(struct snd_pcm_substream *substream)
312{
313 struct snd_pcm_runtime *runtime = substream->runtime;
314 struct atmel_runtime_data *prtd;
315 int ret = 0;
316
317 snd_soc_set_runtime_hwparams(substream, &atmel_pcm_hardware);
318
319 /* ensure that buffer size is a multiple of period size */
320 ret = snd_pcm_hw_constraint_integer(runtime,
321 SNDRV_PCM_HW_PARAM_PERIODS);
322 if (ret < 0)
323 goto out;
324
325 prtd = kzalloc(sizeof(struct atmel_runtime_data), GFP_KERNEL);
326 if (prtd == NULL) {
327 ret = -ENOMEM;
328 goto out;
329 }
330 runtime->private_data = prtd;
331
332 out:
333 return ret;
334}
335
336static int atmel_pcm_close(struct snd_pcm_substream *substream)
337{
338 struct atmel_runtime_data *prtd = substream->runtime->private_data;
339
340 kfree(prtd);
341 return 0;
342}
343
344static int atmel_pcm_mmap(struct snd_pcm_substream *substream,
345 struct vm_area_struct *vma)
346{
347 return remap_pfn_range(vma, vma->vm_start,
348 substream->dma_buffer.addr >> PAGE_SHIFT,
349 vma->vm_end - vma->vm_start, vma->vm_page_prot);
350}
351
352struct snd_pcm_ops atmel_pcm_ops = {
353 .open = atmel_pcm_open,
354 .close = atmel_pcm_close,
355 .ioctl = snd_pcm_lib_ioctl,
356 .hw_params = atmel_pcm_hw_params,
357 .hw_free = atmel_pcm_hw_free,
358 .prepare = atmel_pcm_prepare,
359 .trigger = atmel_pcm_trigger,
360 .pointer = atmel_pcm_pointer,
361 .mmap = atmel_pcm_mmap,
362};
363
364
365/*--------------------------------------------------------------------------*\
366 * ASoC platform driver
367\*--------------------------------------------------------------------------*/
368static u64 atmel_pcm_dmamask = 0xffffffff;
369
370static int atmel_pcm_new(struct snd_card *card,
371 struct snd_soc_dai *dai, struct snd_pcm *pcm)
372{
373 int ret = 0;
374
375 if (!card->dev->dma_mask)
376 card->dev->dma_mask = &atmel_pcm_dmamask;
377 if (!card->dev->coherent_dma_mask)
378 card->dev->coherent_dma_mask = 0xffffffff;
379
380 if (dai->playback.channels_min) {
381 ret = atmel_pcm_preallocate_dma_buffer(pcm,
382 SNDRV_PCM_STREAM_PLAYBACK);
383 if (ret)
384 goto out;
385 }
386
387 if (dai->capture.channels_min) {
388 pr_debug("at32-pcm:"
389 "Allocating PCM capture DMA buffer\n");
390 ret = atmel_pcm_preallocate_dma_buffer(pcm,
391 SNDRV_PCM_STREAM_CAPTURE);
392 if (ret)
393 goto out;
394 }
395 out:
396 return ret;
397}
398
399static void atmel_pcm_free_dma_buffers(struct snd_pcm *pcm)
400{
401 struct snd_pcm_substream *substream;
402 struct snd_dma_buffer *buf;
403 int stream;
404
405 for (stream = 0; stream < 2; stream++) {
406 substream = pcm->streams[stream].substream;
407 if (!substream)
408 continue;
409
410 buf = &substream->dma_buffer;
411 if (!buf->area)
412 continue;
413 dma_free_coherent(pcm->card->dev, buf->bytes,
414 buf->area, buf->addr);
415 buf->area = NULL;
416 }
417}
418
419#ifdef CONFIG_PM
420static int atmel_pcm_suspend(struct snd_soc_dai *dai)
421{
422 struct snd_pcm_runtime *runtime = dai->runtime;
423 struct atmel_runtime_data *prtd;
424 struct atmel_pcm_dma_params *params;
425
426 if (!runtime)
427 return 0;
428
429 prtd = runtime->private_data;
430 params = prtd->params;
431
432 /* disable the PDC and save the PDC registers */
433
434 ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_disable);
435
436 prtd->pdc_xpr_save = ssc_readx(params->ssc->regs, params->pdc->xpr);
437 prtd->pdc_xcr_save = ssc_readx(params->ssc->regs, params->pdc->xcr);
438 prtd->pdc_xnpr_save = ssc_readx(params->ssc->regs, params->pdc->xnpr);
439 prtd->pdc_xncr_save = ssc_readx(params->ssc->regs, params->pdc->xncr);
440
441 return 0;
442}
443
444static int atmel_pcm_resume(struct snd_soc_dai *dai)
445{
446 struct snd_pcm_runtime *runtime = dai->runtime;
447 struct atmel_runtime_data *prtd;
448 struct atmel_pcm_dma_params *params;
449
450 if (!runtime)
451 return 0;
452
453 prtd = runtime->private_data;
454 params = prtd->params;
455
456 /* restore the PDC registers and enable the PDC */
457 ssc_writex(params->ssc->regs, params->pdc->xpr, prtd->pdc_xpr_save);
458 ssc_writex(params->ssc->regs, params->pdc->xcr, prtd->pdc_xcr_save);
459 ssc_writex(params->ssc->regs, params->pdc->xnpr, prtd->pdc_xnpr_save);
460 ssc_writex(params->ssc->regs, params->pdc->xncr, prtd->pdc_xncr_save);
461
462 ssc_writel(params->ssc->regs, PDC_PTCR, params->mask->pdc_enable);
463 return 0;
464}
465#else
466#define atmel_pcm_suspend NULL
467#define atmel_pcm_resume NULL
468#endif
469
470struct snd_soc_platform atmel_soc_platform = {
471 .name = "atmel-audio",
472 .pcm_ops = &atmel_pcm_ops,
473 .pcm_new = atmel_pcm_new,
474 .pcm_free = atmel_pcm_free_dma_buffers,
475 .suspend = atmel_pcm_suspend,
476 .resume = atmel_pcm_resume,
477};
478EXPORT_SYMBOL_GPL(atmel_soc_platform);
479
480static int __init atmel_pcm_modinit(void)
481{
482 return snd_soc_register_platform(&atmel_soc_platform);
483}
484module_init(atmel_pcm_modinit);
485
486static void __exit atmel_pcm_modexit(void)
487{
488 snd_soc_unregister_platform(&atmel_soc_platform);
489}
490module_exit(atmel_pcm_modexit);
491
492MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
493MODULE_DESCRIPTION("Atmel PCM module");
494MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel-pcm.h b/sound/soc/atmel/atmel-pcm.h
new file mode 100644
index 000000000000..ec9b2824b663
--- /dev/null
+++ b/sound/soc/atmel/atmel-pcm.h
@@ -0,0 +1,86 @@
1/*
2 * at91-pcm.h - ALSA PCM interface for the Atmel AT91 SoC.
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 *
9 * Based on at91-pcm. by:
10 * Frank Mandarino <fmandarino@endrelia.com>
11 * Copyright 2006 Endrelia Technologies Inc.
12 *
13 * Based on pxa2xx-pcm.c by:
14 *
15 * Author: Nicolas Pitre
16 * Created: Nov 30, 2004
17 * Copyright: (C) 2004 MontaVista Software, Inc.
18 *
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License as published by
21 * the Free Software Foundation; either version 2 of the License, or
22 * (at your option) any later version.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 */
33
34#ifndef _ATMEL_PCM_H
35#define _ATMEL_PCM_H
36
37#include <linux/atmel-ssc.h>
38
39/*
40 * Registers and status bits that are required by the PCM driver.
41 */
42struct atmel_pdc_regs {
43 unsigned int xpr; /* PDC recv/trans pointer */
44 unsigned int xcr; /* PDC recv/trans counter */
45 unsigned int xnpr; /* PDC next recv/trans pointer */
46 unsigned int xncr; /* PDC next recv/trans counter */
47 unsigned int ptcr; /* PDC transfer control */
48};
49
50struct atmel_ssc_mask {
51 u32 ssc_enable; /* SSC recv/trans enable */
52 u32 ssc_disable; /* SSC recv/trans disable */
53 u32 ssc_endx; /* SSC ENDTX or ENDRX */
54 u32 ssc_endbuf; /* SSC TXBUFE or RXBUFF */
55 u32 pdc_enable; /* PDC recv/trans enable */
56 u32 pdc_disable; /* PDC recv/trans disable */
57};
58
59/*
60 * This structure, shared between the PCM driver and the interface,
61 * contains all information required by the PCM driver to perform the
62 * PDC DMA operation. All fields except dma_intr_handler() are initialized
63 * by the interface. The dms_intr_handler() pointer is set by the PCM
64 * driver and called by the interface SSC interrupt handler if it is
65 * non-NULL.
66 */
67struct atmel_pcm_dma_params {
68 char *name; /* stream identifier */
69 int pdc_xfer_size; /* PDC counter increment in bytes */
70 struct ssc_device *ssc; /* SSC device for stream */
71 struct atmel_pdc_regs *pdc; /* PDC receive or transmit registers */
72 struct atmel_ssc_mask *mask; /* SSC & PDC status bits */
73 struct snd_pcm_substream *substream;
74 void (*dma_intr_handler)(u32, struct snd_pcm_substream *);
75};
76
77extern struct snd_soc_platform atmel_soc_platform;
78
79
80/*
81 * SSC register access (since ssc_writel() / ssc_readl() require literal name)
82 */
83#define ssc_readx(base, reg) (__raw_readl((base) + (reg)))
84#define ssc_writex(base, reg, value) __raw_writel((value), (base) + (reg))
85
86#endif /* _ATMEL_PCM_H */
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c
new file mode 100644
index 000000000000..c5d67900d666
--- /dev/null
+++ b/sound/soc/atmel/atmel_ssc_dai.c
@@ -0,0 +1,790 @@
1/*
2 * atmel_ssc_dai.c -- ALSA SoC ATMEL SSC Audio Layer Platform driver
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 * ATMEL CORP.
9 *
10 * Based on at91-ssc.c by
11 * Frank Mandarino <fmandarino@endrelia.com>
12 * Based on pxa2xx Platform drivers by
13 * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#include <linux/init.h>
31#include <linux/module.h>
32#include <linux/interrupt.h>
33#include <linux/device.h>
34#include <linux/delay.h>
35#include <linux/clk.h>
36#include <linux/atmel_pdc.h>
37
38#include <linux/atmel-ssc.h>
39#include <sound/core.h>
40#include <sound/pcm.h>
41#include <sound/pcm_params.h>
42#include <sound/initval.h>
43#include <sound/soc.h>
44
45#include <mach/hardware.h>
46
47#include "atmel-pcm.h"
48#include "atmel_ssc_dai.h"
49
50
51#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9G20)
52#define NUM_SSC_DEVICES 1
53#else
54#define NUM_SSC_DEVICES 3
55#endif
56
57/*
58 * SSC PDC registers required by the PCM DMA engine.
59 */
60static struct atmel_pdc_regs pdc_tx_reg = {
61 .xpr = ATMEL_PDC_TPR,
62 .xcr = ATMEL_PDC_TCR,
63 .xnpr = ATMEL_PDC_TNPR,
64 .xncr = ATMEL_PDC_TNCR,
65};
66
67static struct atmel_pdc_regs pdc_rx_reg = {
68 .xpr = ATMEL_PDC_RPR,
69 .xcr = ATMEL_PDC_RCR,
70 .xnpr = ATMEL_PDC_RNPR,
71 .xncr = ATMEL_PDC_RNCR,
72};
73
74/*
75 * SSC & PDC status bits for transmit and receive.
76 */
77static struct atmel_ssc_mask ssc_tx_mask = {
78 .ssc_enable = SSC_BIT(CR_TXEN),
79 .ssc_disable = SSC_BIT(CR_TXDIS),
80 .ssc_endx = SSC_BIT(SR_ENDTX),
81 .ssc_endbuf = SSC_BIT(SR_TXBUFE),
82 .pdc_enable = ATMEL_PDC_TXTEN,
83 .pdc_disable = ATMEL_PDC_TXTDIS,
84};
85
86static struct atmel_ssc_mask ssc_rx_mask = {
87 .ssc_enable = SSC_BIT(CR_RXEN),
88 .ssc_disable = SSC_BIT(CR_RXDIS),
89 .ssc_endx = SSC_BIT(SR_ENDRX),
90 .ssc_endbuf = SSC_BIT(SR_RXBUFF),
91 .pdc_enable = ATMEL_PDC_RXTEN,
92 .pdc_disable = ATMEL_PDC_RXTDIS,
93};
94
95
96/*
97 * DMA parameters.
98 */
99static struct atmel_pcm_dma_params ssc_dma_params[NUM_SSC_DEVICES][2] = {
100 {{
101 .name = "SSC0 PCM out",
102 .pdc = &pdc_tx_reg,
103 .mask = &ssc_tx_mask,
104 },
105 {
106 .name = "SSC0 PCM in",
107 .pdc = &pdc_rx_reg,
108 .mask = &ssc_rx_mask,
109 } },
110#if NUM_SSC_DEVICES == 3
111 {{
112 .name = "SSC1 PCM out",
113 .pdc = &pdc_tx_reg,
114 .mask = &ssc_tx_mask,
115 },
116 {
117 .name = "SSC1 PCM in",
118 .pdc = &pdc_rx_reg,
119 .mask = &ssc_rx_mask,
120 } },
121 {{
122 .name = "SSC2 PCM out",
123 .pdc = &pdc_tx_reg,
124 .mask = &ssc_tx_mask,
125 },
126 {
127 .name = "SSC2 PCM in",
128 .pdc = &pdc_rx_reg,
129 .mask = &ssc_rx_mask,
130 } },
131#endif
132};
133
134
135static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = {
136 {
137 .name = "ssc0",
138 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock),
139 .dir_mask = SSC_DIR_MASK_UNUSED,
140 .initialized = 0,
141 },
142#if NUM_SSC_DEVICES == 3
143 {
144 .name = "ssc1",
145 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock),
146 .dir_mask = SSC_DIR_MASK_UNUSED,
147 .initialized = 0,
148 },
149 {
150 .name = "ssc2",
151 .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock),
152 .dir_mask = SSC_DIR_MASK_UNUSED,
153 .initialized = 0,
154 },
155#endif
156};
157
158
159/*
160 * SSC interrupt handler. Passes PDC interrupts to the DMA
161 * interrupt handler in the PCM driver.
162 */
163static irqreturn_t atmel_ssc_interrupt(int irq, void *dev_id)
164{
165 struct atmel_ssc_info *ssc_p = dev_id;
166 struct atmel_pcm_dma_params *dma_params;
167 u32 ssc_sr;
168 u32 ssc_substream_mask;
169 int i;
170
171 ssc_sr = (unsigned long)ssc_readl(ssc_p->ssc->regs, SR)
172 & (unsigned long)ssc_readl(ssc_p->ssc->regs, IMR);
173
174 /*
175 * Loop through the substreams attached to this SSC. If
176 * a DMA-related interrupt occurred on that substream, call
177 * the DMA interrupt handler function, if one has been
178 * registered in the dma_params structure by the PCM driver.
179 */
180 for (i = 0; i < ARRAY_SIZE(ssc_p->dma_params); i++) {
181 dma_params = ssc_p->dma_params[i];
182
183 if ((dma_params != NULL) &&
184 (dma_params->dma_intr_handler != NULL)) {
185 ssc_substream_mask = (dma_params->mask->ssc_endx |
186 dma_params->mask->ssc_endbuf);
187 if (ssc_sr & ssc_substream_mask) {
188 dma_params->dma_intr_handler(ssc_sr,
189 dma_params->
190 substream);
191 }
192 }
193 }
194
195 return IRQ_HANDLED;
196}
197
198
199/*-------------------------------------------------------------------------*\
200 * DAI functions
201\*-------------------------------------------------------------------------*/
202/*
203 * Startup. Only that one substream allowed in each direction.
204 */
205static int atmel_ssc_startup(struct snd_pcm_substream *substream,
206 struct snd_soc_dai *dai)
207{
208 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
209 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
210 int dir_mask;
211
212 pr_debug("atmel_ssc_startup: SSC_SR=0x%u\n",
213 ssc_readl(ssc_p->ssc->regs, SR));
214
215 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
216 dir_mask = SSC_DIR_MASK_PLAYBACK;
217 else
218 dir_mask = SSC_DIR_MASK_CAPTURE;
219
220 spin_lock_irq(&ssc_p->lock);
221 if (ssc_p->dir_mask & dir_mask) {
222 spin_unlock_irq(&ssc_p->lock);
223 return -EBUSY;
224 }
225 ssc_p->dir_mask |= dir_mask;
226 spin_unlock_irq(&ssc_p->lock);
227
228 return 0;
229}
230
231/*
232 * Shutdown. Clear DMA parameters and shutdown the SSC if there
233 * are no other substreams open.
234 */
235static void atmel_ssc_shutdown(struct snd_pcm_substream *substream,
236 struct snd_soc_dai *dai)
237{
238 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
239 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
240 struct atmel_pcm_dma_params *dma_params;
241 int dir, dir_mask;
242
243 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
244 dir = 0;
245 else
246 dir = 1;
247
248 dma_params = ssc_p->dma_params[dir];
249
250 if (dma_params != NULL) {
251 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_disable);
252 pr_debug("atmel_ssc_shutdown: %s disabled SSC_SR=0x%08x\n",
253 (dir ? "receive" : "transmit"),
254 ssc_readl(ssc_p->ssc->regs, SR));
255
256 dma_params->ssc = NULL;
257 dma_params->substream = NULL;
258 ssc_p->dma_params[dir] = NULL;
259 }
260
261 dir_mask = 1 << dir;
262
263 spin_lock_irq(&ssc_p->lock);
264 ssc_p->dir_mask &= ~dir_mask;
265 if (!ssc_p->dir_mask) {
266 if (ssc_p->initialized) {
267 /* Shutdown the SSC clock. */
268 pr_debug("atmel_ssc_dau: Stopping clock\n");
269 clk_disable(ssc_p->ssc->clk);
270
271 free_irq(ssc_p->ssc->irq, ssc_p);
272 ssc_p->initialized = 0;
273 }
274
275 /* Reset the SSC */
276 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
277 /* Clear the SSC dividers */
278 ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0;
279 }
280 spin_unlock_irq(&ssc_p->lock);
281}
282
283
284/*
285 * Record the DAI format for use in hw_params().
286 */
287static int atmel_ssc_set_dai_fmt(struct snd_soc_dai *cpu_dai,
288 unsigned int fmt)
289{
290 struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
291
292 ssc_p->daifmt = fmt;
293 return 0;
294}
295
296/*
297 * Record SSC clock dividers for use in hw_params().
298 */
299static int atmel_ssc_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
300 int div_id, int div)
301{
302 struct atmel_ssc_info *ssc_p = &ssc_info[cpu_dai->id];
303
304 switch (div_id) {
305 case ATMEL_SSC_CMR_DIV:
306 /*
307 * The same master clock divider is used for both
308 * transmit and receive, so if a value has already
309 * been set, it must match this value.
310 */
311 if (ssc_p->cmr_div == 0)
312 ssc_p->cmr_div = div;
313 else
314 if (div != ssc_p->cmr_div)
315 return -EBUSY;
316 break;
317
318 case ATMEL_SSC_TCMR_PERIOD:
319 ssc_p->tcmr_period = div;
320 break;
321
322 case ATMEL_SSC_RCMR_PERIOD:
323 ssc_p->rcmr_period = div;
324 break;
325
326 default:
327 return -EINVAL;
328 }
329
330 return 0;
331}
332
333/*
334 * Configure the SSC.
335 */
336static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
337 struct snd_pcm_hw_params *params,
338 struct snd_soc_dai *dai)
339{
340 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
341 int id = rtd->dai->cpu_dai->id;
342 struct atmel_ssc_info *ssc_p = &ssc_info[id];
343 struct atmel_pcm_dma_params *dma_params;
344 int dir, channels, bits;
345 u32 tfmr, rfmr, tcmr, rcmr;
346 int start_event;
347 int ret;
348
349 /*
350 * Currently, there is only one set of dma params for
351 * each direction. If more are added, this code will
352 * have to be changed to select the proper set.
353 */
354 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
355 dir = 0;
356 else
357 dir = 1;
358
359 dma_params = &ssc_dma_params[id][dir];
360 dma_params->ssc = ssc_p->ssc;
361 dma_params->substream = substream;
362
363 ssc_p->dma_params[dir] = dma_params;
364
365 /*
366 * The cpu_dai->dma_data field is only used to communicate the
367 * appropriate DMA parameters to the pcm driver hw_params()
368 * function. It should not be used for other purposes
369 * as it is common to all substreams.
370 */
371 rtd->dai->cpu_dai->dma_data = dma_params;
372
373 channels = params_channels(params);
374
375 /*
376 * Determine sample size in bits and the PDC increment.
377 */
378 switch (params_format(params)) {
379 case SNDRV_PCM_FORMAT_S8:
380 bits = 8;
381 dma_params->pdc_xfer_size = 1;
382 break;
383 case SNDRV_PCM_FORMAT_S16_LE:
384 bits = 16;
385 dma_params->pdc_xfer_size = 2;
386 break;
387 case SNDRV_PCM_FORMAT_S24_LE:
388 bits = 24;
389 dma_params->pdc_xfer_size = 4;
390 break;
391 case SNDRV_PCM_FORMAT_S32_LE:
392 bits = 32;
393 dma_params->pdc_xfer_size = 4;
394 break;
395 default:
396 printk(KERN_WARNING "atmel_ssc_dai: unsupported PCM format");
397 return -EINVAL;
398 }
399
400 /*
401 * The SSC only supports up to 16-bit samples in I2S format, due
402 * to the size of the Frame Mode Register FSLEN field.
403 */
404 if ((ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S
405 && bits > 16) {
406 printk(KERN_WARNING
407 "atmel_ssc_dai: sample size %d"
408 "is too large for I2S\n", bits);
409 return -EINVAL;
410 }
411
412 /*
413 * Compute SSC register settings.
414 */
415 switch (ssc_p->daifmt
416 & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) {
417
418 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS:
419 /*
420 * I2S format, SSC provides BCLK and LRC clocks.
421 *
422 * The SSC transmit and receive clocks are generated
423 * from the MCK divider, and the BCLK signal
424 * is output on the SSC TK line.
425 */
426 rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
427 | SSC_BF(RCMR_STTDLY, START_DELAY)
428 | SSC_BF(RCMR_START, SSC_START_FALLING_RF)
429 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
430 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
431 | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
432
433 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
434 | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE)
435 | SSC_BF(RFMR_FSLEN, (bits - 1))
436 | SSC_BF(RFMR_DATNB, (channels - 1))
437 | SSC_BIT(RFMR_MSBF)
438 | SSC_BF(RFMR_LOOP, 0)
439 | SSC_BF(RFMR_DATLEN, (bits - 1));
440
441 tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
442 | SSC_BF(TCMR_STTDLY, START_DELAY)
443 | SSC_BF(TCMR_START, SSC_START_FALLING_RF)
444 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
445 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
446 | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
447
448 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
449 | SSC_BF(TFMR_FSDEN, 0)
450 | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE)
451 | SSC_BF(TFMR_FSLEN, (bits - 1))
452 | SSC_BF(TFMR_DATNB, (channels - 1))
453 | SSC_BIT(TFMR_MSBF)
454 | SSC_BF(TFMR_DATDEF, 0)
455 | SSC_BF(TFMR_DATLEN, (bits - 1));
456 break;
457
458 case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM:
459 /*
460 * I2S format, CODEC supplies BCLK and LRC clocks.
461 *
462 * The SSC transmit clock is obtained from the BCLK signal on
463 * on the TK line, and the SSC receive clock is
464 * generated from the transmit clock.
465 *
466 * For single channel data, one sample is transferred
467 * on the falling edge of the LRC clock.
468 * For two channel data, one sample is
469 * transferred on both edges of the LRC clock.
470 */
471 start_event = ((channels == 1)
472 ? SSC_START_FALLING_RF
473 : SSC_START_EDGE_RF);
474
475 rcmr = SSC_BF(RCMR_PERIOD, 0)
476 | SSC_BF(RCMR_STTDLY, START_DELAY)
477 | SSC_BF(RCMR_START, start_event)
478 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
479 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
480 | SSC_BF(RCMR_CKS, SSC_CKS_CLOCK);
481
482 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
483 | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE)
484 | SSC_BF(RFMR_FSLEN, 0)
485 | SSC_BF(RFMR_DATNB, 0)
486 | SSC_BIT(RFMR_MSBF)
487 | SSC_BF(RFMR_LOOP, 0)
488 | SSC_BF(RFMR_DATLEN, (bits - 1));
489
490 tcmr = SSC_BF(TCMR_PERIOD, 0)
491 | SSC_BF(TCMR_STTDLY, START_DELAY)
492 | SSC_BF(TCMR_START, start_event)
493 | SSC_BF(TCMR_CKI, SSC_CKI_FALLING)
494 | SSC_BF(TCMR_CKO, SSC_CKO_NONE)
495 | SSC_BF(TCMR_CKS, SSC_CKS_PIN);
496
497 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
498 | SSC_BF(TFMR_FSDEN, 0)
499 | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE)
500 | SSC_BF(TFMR_FSLEN, 0)
501 | SSC_BF(TFMR_DATNB, 0)
502 | SSC_BIT(TFMR_MSBF)
503 | SSC_BF(TFMR_DATDEF, 0)
504 | SSC_BF(TFMR_DATLEN, (bits - 1));
505 break;
506
507 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS:
508 /*
509 * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks.
510 *
511 * The SSC transmit and receive clocks are generated from the
512 * MCK divider, and the BCLK signal is output
513 * on the SSC TK line.
514 */
515 rcmr = SSC_BF(RCMR_PERIOD, ssc_p->rcmr_period)
516 | SSC_BF(RCMR_STTDLY, 1)
517 | SSC_BF(RCMR_START, SSC_START_RISING_RF)
518 | SSC_BF(RCMR_CKI, SSC_CKI_RISING)
519 | SSC_BF(RCMR_CKO, SSC_CKO_NONE)
520 | SSC_BF(RCMR_CKS, SSC_CKS_DIV);
521
522 rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
523 | SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE)
524 | SSC_BF(RFMR_FSLEN, 0)
525 | SSC_BF(RFMR_DATNB, (channels - 1))
526 | SSC_BIT(RFMR_MSBF)
527 | SSC_BF(RFMR_LOOP, 0)
528 | SSC_BF(RFMR_DATLEN, (bits - 1));
529
530 tcmr = SSC_BF(TCMR_PERIOD, ssc_p->tcmr_period)
531 | SSC_BF(TCMR_STTDLY, 1)
532 | SSC_BF(TCMR_START, SSC_START_RISING_RF)
533 | SSC_BF(TCMR_CKI, SSC_CKI_RISING)
534 | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS)
535 | SSC_BF(TCMR_CKS, SSC_CKS_DIV);
536
537 tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE)
538 | SSC_BF(TFMR_FSDEN, 0)
539 | SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE)
540 | SSC_BF(TFMR_FSLEN, 0)
541 | SSC_BF(TFMR_DATNB, (channels - 1))
542 | SSC_BIT(TFMR_MSBF)
543 | SSC_BF(TFMR_DATDEF, 0)
544 | SSC_BF(TFMR_DATLEN, (bits - 1));
545 break;
546
547 case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM:
548 default:
549 printk(KERN_WARNING "atmel_ssc_dai: unsupported DAI format 0x%x\n",
550 ssc_p->daifmt);
551 return -EINVAL;
552 break;
553 }
554 pr_debug("atmel_ssc_hw_params: "
555 "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n",
556 rcmr, rfmr, tcmr, tfmr);
557
558 if (!ssc_p->initialized) {
559
560 /* Enable PMC peripheral clock for this SSC */
561 pr_debug("atmel_ssc_dai: Starting clock\n");
562 clk_enable(ssc_p->ssc->clk);
563
564 /* Reset the SSC and its PDC registers */
565 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_SWRST));
566
567 ssc_writel(ssc_p->ssc->regs, PDC_RPR, 0);
568 ssc_writel(ssc_p->ssc->regs, PDC_RCR, 0);
569 ssc_writel(ssc_p->ssc->regs, PDC_RNPR, 0);
570 ssc_writel(ssc_p->ssc->regs, PDC_RNCR, 0);
571
572 ssc_writel(ssc_p->ssc->regs, PDC_TPR, 0);
573 ssc_writel(ssc_p->ssc->regs, PDC_TCR, 0);
574 ssc_writel(ssc_p->ssc->regs, PDC_TNPR, 0);
575 ssc_writel(ssc_p->ssc->regs, PDC_TNCR, 0);
576
577 ret = request_irq(ssc_p->ssc->irq, atmel_ssc_interrupt, 0,
578 ssc_p->name, ssc_p);
579 if (ret < 0) {
580 printk(KERN_WARNING
581 "atmel_ssc_dai: request_irq failure\n");
582 pr_debug("Atmel_ssc_dai: Stoping clock\n");
583 clk_disable(ssc_p->ssc->clk);
584 return ret;
585 }
586
587 ssc_p->initialized = 1;
588 }
589
590 /* set SSC clock mode register */
591 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->cmr_div);
592
593 /* set receive clock mode and format */
594 ssc_writel(ssc_p->ssc->regs, RCMR, rcmr);
595 ssc_writel(ssc_p->ssc->regs, RFMR, rfmr);
596
597 /* set transmit clock mode and format */
598 ssc_writel(ssc_p->ssc->regs, TCMR, tcmr);
599 ssc_writel(ssc_p->ssc->regs, TFMR, tfmr);
600
601 pr_debug("atmel_ssc_dai,hw_params: SSC initialized\n");
602 return 0;
603}
604
605
606static int atmel_ssc_prepare(struct snd_pcm_substream *substream,
607 struct snd_soc_dai *dai)
608{
609 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
610 struct atmel_ssc_info *ssc_p = &ssc_info[rtd->dai->cpu_dai->id];
611 struct atmel_pcm_dma_params *dma_params;
612 int dir;
613
614 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
615 dir = 0;
616 else
617 dir = 1;
618
619 dma_params = ssc_p->dma_params[dir];
620
621 ssc_writel(ssc_p->ssc->regs, CR, dma_params->mask->ssc_enable);
622
623 pr_debug("%s enabled SSC_SR=0x%08x\n",
624 dir ? "receive" : "transmit",
625 ssc_readl(ssc_p->ssc->regs, SR));
626 return 0;
627}
628
629
630#ifdef CONFIG_PM
631static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai)
632{
633 struct atmel_ssc_info *ssc_p;
634
635 if (!cpu_dai->active)
636 return 0;
637
638 ssc_p = &ssc_info[cpu_dai->id];
639
640 /* Save the status register before disabling transmit and receive */
641 ssc_p->ssc_state.ssc_sr = ssc_readl(ssc_p->ssc->regs, SR);
642 ssc_writel(ssc_p->ssc->regs, CR, SSC_BIT(CR_TXDIS) | SSC_BIT(CR_RXDIS));
643
644 /* Save the current interrupt mask, then disable unmasked interrupts */
645 ssc_p->ssc_state.ssc_imr = ssc_readl(ssc_p->ssc->regs, IMR);
646 ssc_writel(ssc_p->ssc->regs, IDR, ssc_p->ssc_state.ssc_imr);
647
648 ssc_p->ssc_state.ssc_cmr = ssc_readl(ssc_p->ssc->regs, CMR);
649 ssc_p->ssc_state.ssc_rcmr = ssc_readl(ssc_p->ssc->regs, RCMR);
650 ssc_p->ssc_state.ssc_rfmr = ssc_readl(ssc_p->ssc->regs, RFMR);
651 ssc_p->ssc_state.ssc_tcmr = ssc_readl(ssc_p->ssc->regs, TCMR);
652 ssc_p->ssc_state.ssc_tfmr = ssc_readl(ssc_p->ssc->regs, TFMR);
653
654 return 0;
655}
656
657
658
659static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai)
660{
661 struct atmel_ssc_info *ssc_p;
662 u32 cr;
663
664 if (!cpu_dai->active)
665 return 0;
666
667 ssc_p = &ssc_info[cpu_dai->id];
668
669 /* restore SSC register settings */
670 ssc_writel(ssc_p->ssc->regs, TFMR, ssc_p->ssc_state.ssc_tfmr);
671 ssc_writel(ssc_p->ssc->regs, TCMR, ssc_p->ssc_state.ssc_tcmr);
672 ssc_writel(ssc_p->ssc->regs, RFMR, ssc_p->ssc_state.ssc_rfmr);
673 ssc_writel(ssc_p->ssc->regs, RCMR, ssc_p->ssc_state.ssc_rcmr);
674 ssc_writel(ssc_p->ssc->regs, CMR, ssc_p->ssc_state.ssc_cmr);
675
676 /* re-enable interrupts */
677 ssc_writel(ssc_p->ssc->regs, IER, ssc_p->ssc_state.ssc_imr);
678
679 /* Re-enable recieve and transmit as appropriate */
680 cr = 0;
681 cr |=
682 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_RXEN)) ? SSC_BIT(CR_RXEN) : 0;
683 cr |=
684 (ssc_p->ssc_state.ssc_sr & SSC_BIT(SR_TXEN)) ? SSC_BIT(CR_TXEN) : 0;
685 ssc_writel(ssc_p->ssc->regs, CR, cr);
686
687 return 0;
688}
689#else /* CONFIG_PM */
690# define atmel_ssc_suspend NULL
691# define atmel_ssc_resume NULL
692#endif /* CONFIG_PM */
693
694
695#define ATMEL_SSC_RATES (SNDRV_PCM_RATE_8000_96000)
696
697#define ATMEL_SSC_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
698 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
699
700struct snd_soc_dai atmel_ssc_dai[NUM_SSC_DEVICES] = {
701 { .name = "atmel-ssc0",
702 .id = 0,
703 .suspend = atmel_ssc_suspend,
704 .resume = atmel_ssc_resume,
705 .playback = {
706 .channels_min = 1,
707 .channels_max = 2,
708 .rates = ATMEL_SSC_RATES,
709 .formats = ATMEL_SSC_FORMATS,},
710 .capture = {
711 .channels_min = 1,
712 .channels_max = 2,
713 .rates = ATMEL_SSC_RATES,
714 .formats = ATMEL_SSC_FORMATS,},
715 .ops = {
716 .startup = atmel_ssc_startup,
717 .shutdown = atmel_ssc_shutdown,
718 .prepare = atmel_ssc_prepare,
719 .hw_params = atmel_ssc_hw_params,
720 .set_fmt = atmel_ssc_set_dai_fmt,
721 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
722 .private_data = &ssc_info[0],
723 },
724#if NUM_SSC_DEVICES == 3
725 { .name = "atmel-ssc1",
726 .id = 1,
727 .suspend = atmel_ssc_suspend,
728 .resume = atmel_ssc_resume,
729 .playback = {
730 .channels_min = 1,
731 .channels_max = 2,
732 .rates = ATMEL_SSC_RATES,
733 .formats = ATMEL_SSC_FORMATS,},
734 .capture = {
735 .channels_min = 1,
736 .channels_max = 2,
737 .rates = ATMEL_SSC_RATES,
738 .formats = ATMEL_SSC_FORMATS,},
739 .ops = {
740 .startup = atmel_ssc_startup,
741 .shutdown = atmel_ssc_shutdown,
742 .prepare = atmel_ssc_prepare,
743 .hw_params = atmel_ssc_hw_params,
744 .set_fmt = atmel_ssc_set_dai_fmt,
745 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
746 .private_data = &ssc_info[1],
747 },
748 { .name = "atmel-ssc2",
749 .id = 2,
750 .suspend = atmel_ssc_suspend,
751 .resume = atmel_ssc_resume,
752 .playback = {
753 .channels_min = 1,
754 .channels_max = 2,
755 .rates = ATMEL_SSC_RATES,
756 .formats = ATMEL_SSC_FORMATS,},
757 .capture = {
758 .channels_min = 1,
759 .channels_max = 2,
760 .rates = ATMEL_SSC_RATES,
761 .formats = ATMEL_SSC_FORMATS,},
762 .ops = {
763 .startup = atmel_ssc_startup,
764 .shutdown = atmel_ssc_shutdown,
765 .prepare = atmel_ssc_prepare,
766 .hw_params = atmel_ssc_hw_params,
767 .set_fmt = atmel_ssc_set_dai_fmt,
768 .set_clkdiv = atmel_ssc_set_dai_clkdiv,},
769 .private_data = &ssc_info[2],
770 },
771#endif
772};
773EXPORT_SYMBOL_GPL(atmel_ssc_dai);
774
775static int __init atmel_ssc_modinit(void)
776{
777 return snd_soc_register_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
778}
779module_init(atmel_ssc_modinit);
780
781static void __exit atmel_ssc_modexit(void)
782{
783 snd_soc_unregister_dais(atmel_ssc_dai, ARRAY_SIZE(atmel_ssc_dai));
784}
785module_exit(atmel_ssc_modexit);
786
787/* Module information */
788MODULE_AUTHOR("Sedji Gaouaou, sedji.gaouaou@atmel.com, www.atmel.com");
789MODULE_DESCRIPTION("ATMEL SSC ASoC Interface");
790MODULE_LICENSE("GPL");
diff --git a/sound/soc/atmel/atmel_ssc_dai.h b/sound/soc/atmel/atmel_ssc_dai.h
new file mode 100644
index 000000000000..a828746e8a2f
--- /dev/null
+++ b/sound/soc/atmel/atmel_ssc_dai.h
@@ -0,0 +1,121 @@
1/*
2 * atmel_ssc_dai.h - ALSA SSC interface for the Atmel SoC
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2008 Atmel
6 *
7 * Author: Sedji Gaouaou <sedji.gaouaou@atmel.com>
8 * ATMEL CORP.
9 *
10 * Based on at91-ssc.c by
11 * Frank Mandarino <fmandarino@endrelia.com>
12 * Based on pxa2xx Platform drivers by
13 * Liam Girdwood <liam.girdwood@wolfsonmicro.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 */
29
30#ifndef _ATMEL_SSC_DAI_H
31#define _ATMEL_SSC_DAI_H
32
33#include <linux/types.h>
34#include <linux/atmel-ssc.h>
35
36#include "atmel-pcm.h"
37
38/* SSC system clock ids */
39#define ATMEL_SYSCLK_MCK 0 /* SSC uses AT91 MCK as system clock */
40
41/* SSC divider ids */
42#define ATMEL_SSC_CMR_DIV 0 /* MCK divider for BCLK */
43#define ATMEL_SSC_TCMR_PERIOD 1 /* BCLK divider for transmit FS */
44#define ATMEL_SSC_RCMR_PERIOD 2 /* BCLK divider for receive FS */
45/*
46 * SSC direction masks
47 */
48#define SSC_DIR_MASK_UNUSED 0
49#define SSC_DIR_MASK_PLAYBACK 1
50#define SSC_DIR_MASK_CAPTURE 2
51
52/*
53 * SSC register values that Atmel left out of <linux/atmel-ssc.h>. These
54 * are expected to be used with SSC_BF
55 */
56/* START bit field values */
57#define SSC_START_CONTINUOUS 0
58#define SSC_START_TX_RX 1
59#define SSC_START_LOW_RF 2
60#define SSC_START_HIGH_RF 3
61#define SSC_START_FALLING_RF 4
62#define SSC_START_RISING_RF 5
63#define SSC_START_LEVEL_RF 6
64#define SSC_START_EDGE_RF 7
65#define SSS_START_COMPARE_0 8
66
67/* CKI bit field values */
68#define SSC_CKI_FALLING 0
69#define SSC_CKI_RISING 1
70
71/* CKO bit field values */
72#define SSC_CKO_NONE 0
73#define SSC_CKO_CONTINUOUS 1
74#define SSC_CKO_TRANSFER 2
75
76/* CKS bit field values */
77#define SSC_CKS_DIV 0
78#define SSC_CKS_CLOCK 1
79#define SSC_CKS_PIN 2
80
81/* FSEDGE bit field values */
82#define SSC_FSEDGE_POSITIVE 0
83#define SSC_FSEDGE_NEGATIVE 1
84
85/* FSOS bit field values */
86#define SSC_FSOS_NONE 0
87#define SSC_FSOS_NEGATIVE 1
88#define SSC_FSOS_POSITIVE 2
89#define SSC_FSOS_LOW 3
90#define SSC_FSOS_HIGH 4
91#define SSC_FSOS_TOGGLE 5
92
93#define START_DELAY 1
94
95struct atmel_ssc_state {
96 u32 ssc_cmr;
97 u32 ssc_rcmr;
98 u32 ssc_rfmr;
99 u32 ssc_tcmr;
100 u32 ssc_tfmr;
101 u32 ssc_sr;
102 u32 ssc_imr;
103};
104
105
106struct atmel_ssc_info {
107 char *name;
108 struct ssc_device *ssc;
109 spinlock_t lock; /* lock for dir_mask */
110 unsigned short dir_mask; /* 0=unused, 1=playback, 2=capture */
111 unsigned short initialized; /* true if SSC has been initialized */
112 unsigned short daifmt;
113 unsigned short cmr_div;
114 unsigned short tcmr_period;
115 unsigned short rcmr_period;
116 struct atmel_pcm_dma_params *dma_params[2];
117 struct atmel_ssc_state ssc_state;
118};
119extern struct snd_soc_dai atmel_ssc_dai[];
120
121#endif /* _AT91_SSC_DAI_H */
diff --git a/sound/soc/at32/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index b1966e4dfcd3..43dd8cee83c6 100644
--- a/sound/soc/at32/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -22,7 +22,6 @@
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
25#include <linux/version.h>
26#include <linux/kernel.h> 25#include <linux/kernel.h>
27#include <linux/errno.h> 26#include <linux/errno.h>
28#include <linux/clk.h> 27#include <linux/clk.h>
@@ -40,8 +39,8 @@
40#include <mach/portmux.h> 39#include <mach/portmux.h>
41 40
42#include "../codecs/wm8510.h" 41#include "../codecs/wm8510.h"
43#include "at32-pcm.h" 42#include "atmel-pcm.h"
44#include "at32-ssc.h" 43#include "atmel_ssc_dai.h"
45 44
46 45
47/*-------------------------------------------------------------------------*\ 46/*-------------------------------------------------------------------------*\
@@ -362,8 +361,9 @@ static struct snd_soc_dai_link playpaq_wm8510_dai = {
362 361
363 362
364 363
365static struct snd_soc_machine snd_soc_machine_playpaq = { 364static struct snd_soc_card snd_soc_playpaq = {
366 .name = "LRS_PlayPaq_WM8510", 365 .name = "LRS_PlayPaq_WM8510",
366 .platform = &at32_soc_platform,
367 .dai_link = &playpaq_wm8510_dai, 367 .dai_link = &playpaq_wm8510_dai,
368 .num_links = 1, 368 .num_links = 1,
369}; 369};
@@ -378,8 +378,7 @@ static struct wm8510_setup_data playpaq_wm8510_setup = {
378 378
379 379
380static struct snd_soc_device playpaq_wm8510_snd_devdata = { 380static struct snd_soc_device playpaq_wm8510_snd_devdata = {
381 .machine = &snd_soc_machine_playpaq, 381 .card = &snd_soc_playpaq,
382 .platform = &at32_soc_platform,
383 .codec_dev = &soc_codec_dev_wm8510, 382 .codec_dev = &soc_codec_dev_wm8510,
384 .codec_data = &playpaq_wm8510_setup, 383 .codec_data = &playpaq_wm8510_setup,
385}; 384};
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
new file mode 100644
index 000000000000..1fb59a9d3719
--- /dev/null
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -0,0 +1,328 @@
1/*
2 * sam9g20_wm8731 -- SoC audio for AT91SAM9G20-based
3 * ATMEL AT91SAM9G20ek board.
4 *
5 * Copyright (C) 2005 SAN People
6 * Copyright (C) 2008 Atmel
7 *
8 * Authors: Sedji Gaouaou <sedji.gaouaou@atmel.com>
9 *
10 * Based on ati_b1_wm8731.c by:
11 * Frank Mandarino <fmandarino@endrelia.com>
12 * Copyright 2006 Endrelia Technologies Inc.
13 * Based on corgi.c by:
14 * Copyright 2005 Wolfson Microelectronics PLC.
15 * Copyright 2005 Openedhand Ltd.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 */
31
32#include <linux/module.h>
33#include <linux/moduleparam.h>
34#include <linux/kernel.h>
35#include <linux/clk.h>
36#include <linux/timer.h>
37#include <linux/interrupt.h>
38#include <linux/platform_device.h>
39
40#include <linux/atmel-ssc.h>
41
42#include <sound/core.h>
43#include <sound/pcm.h>
44#include <sound/pcm_params.h>
45#include <sound/soc.h>
46#include <sound/soc-dapm.h>
47
48#include <mach/hardware.h>
49#include <mach/gpio.h>
50
51#include "../codecs/wm8731.h"
52#include "atmel-pcm.h"
53#include "atmel_ssc_dai.h"
54
55
56static int at91sam9g20ek_startup(struct snd_pcm_substream *substream)
57{
58 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
59 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
60 int ret;
61
62 /* codec system clock is supplied by PCK0, set to 12MHz */
63 ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK,
64 12000000, SND_SOC_CLOCK_IN);
65 if (ret < 0)
66 return ret;
67
68 return 0;
69}
70
71static void at91sam9g20ek_shutdown(struct snd_pcm_substream *substream)
72{
73 struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
74
75 dev_dbg(rtd->socdev->dev, "shutdown");
76}
77
78static int at91sam9g20ek_hw_params(struct snd_pcm_substream *substream,
79 struct snd_pcm_hw_params *params)
80{
81 struct snd_soc_pcm_runtime *rtd = substream->private_data;
82 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
83 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
84 struct atmel_ssc_info *ssc_p = cpu_dai->private_data;
85 struct ssc_device *ssc = ssc_p->ssc;
86 int ret;
87
88 unsigned int rate;
89 int cmr_div, period;
90
91 if (ssc == NULL) {
92 printk(KERN_INFO "at91sam9g20ek_hw_params: ssc is NULL!\n");
93 return -EINVAL;
94 }
95
96 /* set codec DAI configuration */
97 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
98 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
99 if (ret < 0)
100 return ret;
101
102 /* set cpu DAI configuration */
103 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
104 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
105 if (ret < 0)
106 return ret;
107
108 /*
109 * The SSC clock dividers depend on the sample rate. The CMR.DIV
110 * field divides the system master clock MCK to drive the SSC TK
111 * signal which provides the codec BCLK. The TCMR.PERIOD and
112 * RCMR.PERIOD fields further divide the BCLK signal to drive
113 * the SSC TF and RF signals which provide the codec DACLRC and
114 * ADCLRC clocks.
115 *
116 * The dividers were determined through trial and error, where a
117 * CMR.DIV value is chosen such that the resulting BCLK value is
118 * divisible, or almost divisible, by (2 * sample rate), and then
119 * the TCMR.PERIOD or RCMR.PERIOD is BCLK / (2 * sample rate) - 1.
120 */
121 rate = params_rate(params);
122
123 switch (rate) {
124 case 8000:
125 cmr_div = 55; /* BCLK = 133MHz/(2*55) = 1.209MHz */
126 period = 74; /* LRC = BCLK/(2*(74+1)) ~= 8060,6Hz */
127 break;
128 case 11025:
129 cmr_div = 67; /* BCLK = 133MHz/(2*60) = 1.108MHz */
130 period = 45; /* LRC = BCLK/(2*(49+1)) = 11083,3Hz */
131 break;
132 case 16000:
133 cmr_div = 63; /* BCLK = 133MHz/(2*63) = 1.055MHz */
134 period = 32; /* LRC = BCLK/(2*(32+1)) = 15993,2Hz */
135 break;
136 case 22050:
137 cmr_div = 52; /* BCLK = 133MHz/(2*52) = 1.278MHz */
138 period = 28; /* LRC = BCLK/(2*(28+1)) = 22049Hz */
139 break;
140 case 32000:
141 cmr_div = 66; /* BCLK = 133MHz/(2*66) = 1.007MHz */
142 period = 15; /* LRC = BCLK/(2*(15+1)) = 31486,742Hz */
143 break;
144 case 44100:
145 cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */
146 period = 25; /* LRC = BCLK/(2*(25+1)) = 44098Hz */
147 break;
148 case 48000:
149 cmr_div = 33; /* BCLK = 133MHz/(2*33) = 2.015MHz */
150 period = 20; /* LRC = BCLK/(2*(20+1)) = 47979,79Hz */
151 break;
152 case 88200:
153 cmr_div = 29; /* BCLK = 133MHz/(2*29) = 2.293MHz */
154 period = 12; /* LRC = BCLK/(2*(12+1)) = 88196Hz */
155 break;
156 case 96000:
157 cmr_div = 23; /* BCLK = 133MHz/(2*23) = 2.891MHz */
158 period = 14; /* LRC = BCLK/(2*(14+1)) = 96376Hz */
159 break;
160 default:
161 printk(KERN_WARNING "unsupported rate %d"
162 " on at91sam9g20ek board\n", rate);
163 return -EINVAL;
164 }
165
166 /* set the MCK divider for BCLK */
167 ret = snd_soc_dai_set_clkdiv(cpu_dai, ATMEL_SSC_CMR_DIV, cmr_div);
168 if (ret < 0)
169 return ret;
170
171 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
172 /* set the BCLK divider for DACLRC */
173 ret = snd_soc_dai_set_clkdiv(cpu_dai,
174 ATMEL_SSC_TCMR_PERIOD, period);
175 } else {
176 /* set the BCLK divider for ADCLRC */
177 ret = snd_soc_dai_set_clkdiv(cpu_dai,
178 ATMEL_SSC_RCMR_PERIOD, period);
179 }
180 if (ret < 0)
181 return ret;
182
183 return 0;
184}
185
186static struct snd_soc_ops at91sam9g20ek_ops = {
187 .startup = at91sam9g20ek_startup,
188 .hw_params = at91sam9g20ek_hw_params,
189 .shutdown = at91sam9g20ek_shutdown,
190};
191
192
193static const struct snd_soc_dapm_widget at91sam9g20ek_dapm_widgets[] = {
194 SND_SOC_DAPM_MIC("Int Mic", NULL),
195 SND_SOC_DAPM_SPK("Ext Spk", NULL),
196};
197
198static const struct snd_soc_dapm_route intercon[] = {
199
200 /* speaker connected to LHPOUT */
201 {"Ext Spk", NULL, "LHPOUT"},
202
203 /* mic is connected to Mic Jack, with WM8731 Mic Bias */
204 {"MICIN", NULL, "Mic Bias"},
205 {"Mic Bias", NULL, "Int Mic"},
206};
207
208/*
209 * Logic for a wm8731 as connected on a at91sam9g20ek board.
210 */
211static int at91sam9g20ek_wm8731_init(struct snd_soc_codec *codec)
212{
213 printk(KERN_DEBUG
214 "at91sam9g20ek_wm8731 "
215 ": at91sam9g20ek_wm8731_init() called\n");
216
217 /* Add specific widgets */
218 snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets,
219 ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
220 /* Set up specific audio path interconnects */
221 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
222
223 /* not connected */
224 snd_soc_dapm_disable_pin(codec, "RLINEIN");
225 snd_soc_dapm_disable_pin(codec, "LLINEIN");
226
227 /* always connected */
228 snd_soc_dapm_enable_pin(codec, "Int Mic");
229 snd_soc_dapm_enable_pin(codec, "Ext Spk");
230
231 snd_soc_dapm_sync(codec);
232
233 return 0;
234}
235
236static struct snd_soc_dai_link at91sam9g20ek_dai = {
237 .name = "WM8731",
238 .stream_name = "WM8731 PCM",
239 .cpu_dai = &atmel_ssc_dai[0],
240 .codec_dai = &wm8731_dai,
241 .init = at91sam9g20ek_wm8731_init,
242 .ops = &at91sam9g20ek_ops,
243};
244
245static struct snd_soc_card snd_soc_at91sam9g20ek = {
246 .name = "WM8731",
247 .platform = &atmel_soc_platform,
248 .dai_link = &at91sam9g20ek_dai,
249 .num_links = 1,
250};
251
252static struct wm8731_setup_data at91sam9g20ek_wm8731_setup = {
253 .i2c_bus = 0,
254 .i2c_address = 0x1b,
255};
256
257static struct snd_soc_device at91sam9g20ek_snd_devdata = {
258 .card = &snd_soc_at91sam9g20ek,
259 .codec_dev = &soc_codec_dev_wm8731,
260 .codec_data = &at91sam9g20ek_wm8731_setup,
261};
262
263static struct platform_device *at91sam9g20ek_snd_device;
264
265static int __init at91sam9g20ek_init(void)
266{
267 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
268 struct ssc_device *ssc = NULL;
269 int ret;
270
271 /*
272 * Request SSC device
273 */
274 ssc = ssc_request(0);
275 if (IS_ERR(ssc)) {
276 ret = PTR_ERR(ssc);
277 ssc = NULL;
278 goto err_ssc;
279 }
280 ssc_p->ssc = ssc;
281
282 at91sam9g20ek_snd_device = platform_device_alloc("soc-audio", -1);
283 if (!at91sam9g20ek_snd_device) {
284 printk(KERN_DEBUG
285 "platform device allocation failed\n");
286 ret = -ENOMEM;
287 }
288
289 platform_set_drvdata(at91sam9g20ek_snd_device,
290 &at91sam9g20ek_snd_devdata);
291 at91sam9g20ek_snd_devdata.dev = &at91sam9g20ek_snd_device->dev;
292
293 ret = platform_device_add(at91sam9g20ek_snd_device);
294 if (ret) {
295 printk(KERN_DEBUG
296 "platform device allocation failed\n");
297 platform_device_put(at91sam9g20ek_snd_device);
298 }
299
300 return ret;
301
302err_ssc:
303 return ret;
304}
305
306static void __exit at91sam9g20ek_exit(void)
307{
308 struct atmel_ssc_info *ssc_p = at91sam9g20ek_dai.cpu_dai->private_data;
309 struct ssc_device *ssc;
310
311 if (ssc_p != NULL) {
312 ssc = ssc_p->ssc;
313 if (ssc != NULL)
314 ssc_free(ssc);
315 ssc_p->ssc = NULL;
316 }
317
318 platform_device_unregister(at91sam9g20ek_snd_device);
319 at91sam9g20ek_snd_device = NULL;
320}
321
322module_init(at91sam9g20ek_init);
323module_exit(at91sam9g20ek_exit);
324
325/* Module information */
326MODULE_AUTHOR("Sedji Gaouaou <sedji.gaouaou@atmel.com>");
327MODULE_DESCRIPTION("ALSA SoC AT91SAM9G20EK_WM8731");
328MODULE_LICENSE("GPL");
diff --git a/sound/soc/au1x/dbdma2.c b/sound/soc/au1x/dbdma2.c
index 1466d9328800..74c823d60f91 100644
--- a/sound/soc/au1x/dbdma2.c
+++ b/sound/soc/au1x/dbdma2.c
@@ -406,11 +406,12 @@ static int __init au1xpsc_audio_dbdma_init(void)
406{ 406{
407 au1xpsc_audio_pcmdma[PCM_TX] = NULL; 407 au1xpsc_audio_pcmdma[PCM_TX] = NULL;
408 au1xpsc_audio_pcmdma[PCM_RX] = NULL; 408 au1xpsc_audio_pcmdma[PCM_RX] = NULL;
409 return 0; 409 return snd_soc_register_platform(&au1xpsc_soc_platform);
410} 410}
411 411
412static void __exit au1xpsc_audio_dbdma_exit(void) 412static void __exit au1xpsc_audio_dbdma_exit(void)
413{ 413{
414 snd_soc_unregister_platform(&au1xpsc_soc_platform);
414} 415}
415 416
416module_init(au1xpsc_audio_dbdma_init); 417module_init(au1xpsc_audio_dbdma_init);
diff --git a/sound/soc/au1x/psc-ac97.c b/sound/soc/au1x/psc-ac97.c
index 57facbad6825..f0e30aec7f23 100644
--- a/sound/soc/au1x/psc-ac97.c
+++ b/sound/soc/au1x/psc-ac97.c
@@ -160,7 +160,8 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
160EXPORT_SYMBOL_GPL(soc_ac97_ops); 160EXPORT_SYMBOL_GPL(soc_ac97_ops);
161 161
162static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream, 162static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
163 struct snd_pcm_hw_params *params) 163 struct snd_pcm_hw_params *params,
164 struct snd_soc_dai *dai)
164{ 165{
165 /* FIXME */ 166 /* FIXME */
166 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 167 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
@@ -210,7 +211,7 @@ static int au1xpsc_ac97_hw_params(struct snd_pcm_substream *substream,
210} 211}
211 212
212static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream, 213static int au1xpsc_ac97_trigger(struct snd_pcm_substream *substream,
213 int cmd) 214 int cmd, struct snd_soc_dai *dai)
214{ 215{
215 /* FIXME */ 216 /* FIXME */
216 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata; 217 struct au1xpsc_audio_data *pscdata = au1xpsc_ac97_workdata;
@@ -313,8 +314,7 @@ static void au1xpsc_ac97_remove(struct platform_device *pdev,
313 au1xpsc_ac97_workdata = NULL; 314 au1xpsc_ac97_workdata = NULL;
314} 315}
315 316
316static int au1xpsc_ac97_suspend(struct platform_device *pdev, 317static int au1xpsc_ac97_suspend(struct snd_soc_dai *dai)
317 struct snd_soc_dai *dai)
318{ 318{
319 /* save interesting registers and disable PSC */ 319 /* save interesting registers and disable PSC */
320 au1xpsc_ac97_workdata->pm[0] = 320 au1xpsc_ac97_workdata->pm[0] =
@@ -328,8 +328,7 @@ static int au1xpsc_ac97_suspend(struct platform_device *pdev,
328 return 0; 328 return 0;
329} 329}
330 330
331static int au1xpsc_ac97_resume(struct platform_device *pdev, 331static int au1xpsc_ac97_resume(struct snd_soc_dai *dai)
332 struct snd_soc_dai *dai)
333{ 332{
334 /* restore PSC clock config */ 333 /* restore PSC clock config */
335 au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE, 334 au_writel(au1xpsc_ac97_workdata->pm[0] | PSC_SEL_PS_AC97MODE,
@@ -345,7 +344,7 @@ static int au1xpsc_ac97_resume(struct platform_device *pdev,
345 344
346struct snd_soc_dai au1xpsc_ac97_dai = { 345struct snd_soc_dai au1xpsc_ac97_dai = {
347 .name = "au1xpsc_ac97", 346 .name = "au1xpsc_ac97",
348 .type = SND_SOC_DAI_AC97, 347 .ac97_control = 1,
349 .probe = au1xpsc_ac97_probe, 348 .probe = au1xpsc_ac97_probe,
350 .remove = au1xpsc_ac97_remove, 349 .remove = au1xpsc_ac97_remove,
351 .suspend = au1xpsc_ac97_suspend, 350 .suspend = au1xpsc_ac97_suspend,
@@ -372,11 +371,12 @@ EXPORT_SYMBOL_GPL(au1xpsc_ac97_dai);
372static int __init au1xpsc_ac97_init(void) 371static int __init au1xpsc_ac97_init(void)
373{ 372{
374 au1xpsc_ac97_workdata = NULL; 373 au1xpsc_ac97_workdata = NULL;
375 return 0; 374 return snd_soc_register_dai(&au1xpsc_ac97_dai);
376} 375}
377 376
378static void __exit au1xpsc_ac97_exit(void) 377static void __exit au1xpsc_ac97_exit(void)
379{ 378{
379 snd_soc_unregister_dai(&au1xpsc_ac97_dai);
380} 380}
381 381
382module_init(au1xpsc_ac97_init); 382module_init(au1xpsc_ac97_init);
diff --git a/sound/soc/au1x/psc-i2s.c b/sound/soc/au1x/psc-i2s.c
index 9384702c7ebd..f916de4400ed 100644
--- a/sound/soc/au1x/psc-i2s.c
+++ b/sound/soc/au1x/psc-i2s.c
@@ -116,7 +116,8 @@ out:
116} 116}
117 117
118static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream, 118static int au1xpsc_i2s_hw_params(struct snd_pcm_substream *substream,
119 struct snd_pcm_hw_params *params) 119 struct snd_pcm_hw_params *params,
120 struct snd_soc_dai *dai)
120{ 121{
121 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; 122 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
122 123
@@ -240,7 +241,8 @@ static int au1xpsc_i2s_stop(struct au1xpsc_audio_data *pscdata, int stype)
240 return 0; 241 return 0;
241} 242}
242 243
243static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 244static int au1xpsc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
245 struct snd_soc_dai *dai)
244{ 246{
245 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata; 247 struct au1xpsc_audio_data *pscdata = au1xpsc_i2s_workdata;
246 int ret, stype = SUBSTREAM_TYPE(substream); 248 int ret, stype = SUBSTREAM_TYPE(substream);
@@ -337,8 +339,7 @@ static void au1xpsc_i2s_remove(struct platform_device *pdev,
337 au1xpsc_i2s_workdata = NULL; 339 au1xpsc_i2s_workdata = NULL;
338} 340}
339 341
340static int au1xpsc_i2s_suspend(struct platform_device *pdev, 342static int au1xpsc_i2s_suspend(struct snd_soc_dai *cpu_dai)
341 struct snd_soc_dai *cpu_dai)
342{ 343{
343 /* save interesting register and disable PSC */ 344 /* save interesting register and disable PSC */
344 au1xpsc_i2s_workdata->pm[0] = 345 au1xpsc_i2s_workdata->pm[0] =
@@ -352,8 +353,7 @@ static int au1xpsc_i2s_suspend(struct platform_device *pdev,
352 return 0; 353 return 0;
353} 354}
354 355
355static int au1xpsc_i2s_resume(struct platform_device *pdev, 356static int au1xpsc_i2s_resume(struct snd_soc_dai *cpu_dai)
356 struct snd_soc_dai *cpu_dai)
357{ 357{
358 /* select I2S mode and PSC clock */ 358 /* select I2S mode and PSC clock */
359 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata)); 359 au_writel(PSC_CTRL_DISABLE, PSC_CTRL(au1xpsc_i2s_workdata));
@@ -369,7 +369,6 @@ static int au1xpsc_i2s_resume(struct platform_device *pdev,
369 369
370struct snd_soc_dai au1xpsc_i2s_dai = { 370struct snd_soc_dai au1xpsc_i2s_dai = {
371 .name = "au1xpsc_i2s", 371 .name = "au1xpsc_i2s",
372 .type = SND_SOC_DAI_I2S,
373 .probe = au1xpsc_i2s_probe, 372 .probe = au1xpsc_i2s_probe,
374 .remove = au1xpsc_i2s_remove, 373 .remove = au1xpsc_i2s_remove,
375 .suspend = au1xpsc_i2s_suspend, 374 .suspend = au1xpsc_i2s_suspend,
@@ -389,8 +388,6 @@ struct snd_soc_dai au1xpsc_i2s_dai = {
389 .ops = { 388 .ops = {
390 .trigger = au1xpsc_i2s_trigger, 389 .trigger = au1xpsc_i2s_trigger,
391 .hw_params = au1xpsc_i2s_hw_params, 390 .hw_params = au1xpsc_i2s_hw_params,
392 },
393 .dai_ops = {
394 .set_fmt = au1xpsc_i2s_set_fmt, 391 .set_fmt = au1xpsc_i2s_set_fmt,
395 }, 392 },
396}; 393};
@@ -399,11 +396,12 @@ EXPORT_SYMBOL(au1xpsc_i2s_dai);
399static int __init au1xpsc_i2s_init(void) 396static int __init au1xpsc_i2s_init(void)
400{ 397{
401 au1xpsc_i2s_workdata = NULL; 398 au1xpsc_i2s_workdata = NULL;
402 return 0; 399 return snd_soc_register_dai(&au1xpsc_i2s_dai);
403} 400}
404 401
405static void __exit au1xpsc_i2s_exit(void) 402static void __exit au1xpsc_i2s_exit(void)
406{ 403{
404 snd_soc_unregister_dai(&au1xpsc_i2s_dai);
407} 405}
408 406
409module_init(au1xpsc_i2s_init); 407module_init(au1xpsc_i2s_init);
diff --git a/sound/soc/au1x/sample-ac97.c b/sound/soc/au1x/sample-ac97.c
index f75ae7f62c3d..27683eb7905e 100644
--- a/sound/soc/au1x/sample-ac97.c
+++ b/sound/soc/au1x/sample-ac97.c
@@ -42,14 +42,14 @@ static struct snd_soc_dai_link au1xpsc_sample_ac97_dai = {
42 .ops = NULL, 42 .ops = NULL,
43}; 43};
44 44
45static struct snd_soc_machine au1xpsc_sample_ac97_machine = { 45static struct snd_soc_card au1xpsc_sample_ac97_machine = {
46 .name = "Au1xxx PSC AC97 Audio", 46 .name = "Au1xxx PSC AC97 Audio",
47 .dai_link = &au1xpsc_sample_ac97_dai, 47 .dai_link = &au1xpsc_sample_ac97_dai,
48 .num_links = 1, 48 .num_links = 1,
49}; 49};
50 50
51static struct snd_soc_device au1xpsc_sample_ac97_devdata = { 51static struct snd_soc_device au1xpsc_sample_ac97_devdata = {
52 .machine = &au1xpsc_sample_ac97_machine, 52 .card = &au1xpsc_sample_ac97_machine,
53 .platform = &au1xpsc_soc_platform, /* see dbdma2.c */ 53 .platform = &au1xpsc_soc_platform, /* see dbdma2.c */
54 .codec_dev = &soc_codec_dev_ac97, 54 .codec_dev = &soc_codec_dev_ac97,
55}; 55};
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index dc006206f622..0a2f8f9eff53 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -1,6 +1,6 @@
1config SND_BF5XX_I2S 1config SND_BF5XX_I2S
2 tristate "SoC I2S Audio for the ADI BF5xx chip" 2 tristate "SoC I2S Audio for the ADI BF5xx chip"
3 depends on BLACKFIN && SND_SOC 3 depends on BLACKFIN
4 help 4 help
5 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
6 the Blackfin SPORT (synchronous serial ports) interface in I2S 6 the Blackfin SPORT (synchronous serial ports) interface in I2S
@@ -13,7 +13,6 @@ config SND_BF5XX_SOC_SSM2602
13 select SND_BF5XX_SOC_I2S 13 select SND_BF5XX_SOC_I2S
14 select SND_SOC_SSM2602 14 select SND_SOC_SSM2602
15 select I2C 15 select I2C
16 select I2C_BLACKFIN_TWI
17 help 16 help
18 Say Y if you want to add support for SoC audio on BF527-EZKIT. 17 Say Y if you want to add support for SoC audio on BF527-EZKIT.
19 18
@@ -35,7 +34,7 @@ config SND_BFIN_AD73311_SE
35 34
36config SND_BF5XX_AC97 35config SND_BF5XX_AC97
37 tristate "SoC AC97 Audio for the ADI BF5xx chip" 36 tristate "SoC AC97 Audio for the ADI BF5xx chip"
38 depends on BLACKFIN && SND_SOC 37 depends on BLACKFIN
39 help 38 help
40 Say Y or M if you want to add support for codecs attached to 39 Say Y or M if you want to add support for codecs attached to
41 the Blackfin SPORT (synchronous serial ports) interface in slot 16 40 the Blackfin SPORT (synchronous serial ports) interface in slot 16
@@ -47,7 +46,7 @@ config SND_BF5XX_AC97
47 properly with this driver. This driver is known to work with the 46 properly with this driver. This driver is known to work with the
48 Analog Devices line of AC97 codecs. 47 Analog Devices line of AC97 codecs.
49 48
50config SND_MMAP_SUPPORT 49config SND_BF5XX_MMAP_SUPPORT
51 bool "Enable MMAP Support" 50 bool "Enable MMAP Support"
52 depends on SND_BF5XX_AC97 51 depends on SND_BF5XX_AC97
53 default y 52 default y
@@ -55,9 +54,17 @@ config SND_MMAP_SUPPORT
55 Say y if you want AC97 driver to support mmap mode. 54 Say y if you want AC97 driver to support mmap mode.
56 We introduce an intermediate buffer to simulate mmap. 55 We introduce an intermediate buffer to simulate mmap.
57 56
57config SND_BF5XX_MULTICHAN_SUPPORT
58 bool "Enable Multichannel Support"
59 depends on SND_BF5XX_AC97
60 default n
61 help
62 Say y if you want AC97 driver to support up to 5.1 channel audio.
63 this mode will consume much more memory for DMA.
64
58config SND_BF5XX_SOC_SPORT 65config SND_BF5XX_SOC_SPORT
59 tristate 66 tristate
60 67
61config SND_BF5XX_SOC_I2S 68config SND_BF5XX_SOC_I2S
62 tristate 69 tristate
63 select SND_BF5XX_SOC_SPORT 70 select SND_BF5XX_SOC_SPORT
@@ -80,7 +87,7 @@ config SND_BF5XX_SPORT_NUM
80 int "Set a SPORT for Sound chip" 87 int "Set a SPORT for Sound chip"
81 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97) 88 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97)
82 range 0 3 if BF54x 89 range 0 3 if BF54x
83 range 0 1 if (BF53x || BF561) 90 range 0 1 if !BF54x
84 default 0 91 default 0
85 help 92 help
86 Set the correct SPORT for sound chip. 93 Set the correct SPORT for sound chip.
@@ -90,12 +97,13 @@ config SND_BF5XX_HAVE_COLD_RESET
90 depends on SND_BF5XX_AC97 97 depends on SND_BF5XX_AC97
91 default y if BFIN548_EZKIT 98 default y if BFIN548_EZKIT
92 default n if !BFIN548_EZKIT 99 default n if !BFIN548_EZKIT
93 100
94config SND_BF5XX_RESET_GPIO_NUM 101config SND_BF5XX_RESET_GPIO_NUM
95 int "Set a GPIO for cold reset" 102 int "Set a GPIO for cold reset"
96 depends on SND_BF5XX_HAVE_COLD_RESET 103 depends on SND_BF5XX_HAVE_COLD_RESET
97 range 0 159 104 range 0 159
98 default 19 if BFIN548_EZKIT 105 default 19 if BFIN548_EZKIT
99 default 5 if BFIN537_STAMP 106 default 5 if BFIN537_STAMP
107 default 0
100 help 108 help
101 Set the correct GPIO for RESET the sound chip. 109 Set the correct GPIO for RESET the sound chip.
diff --git a/sound/soc/blackfin/bf5xx-ac97-pcm.c b/sound/soc/blackfin/bf5xx-ac97-pcm.c
index 25e50d2ea1ec..8067cfafa3a7 100644
--- a/sound/soc/blackfin/bf5xx-ac97-pcm.c
+++ b/sound/soc/blackfin/bf5xx-ac97-pcm.c
@@ -43,24 +43,34 @@
43#include "bf5xx-ac97.h" 43#include "bf5xx-ac97.h"
44#include "bf5xx-sport.h" 44#include "bf5xx-sport.h"
45 45
46#if defined(CONFIG_SND_MMAP_SUPPORT) 46static unsigned int ac97_chan_mask[] = {
47 SP_FL, /* Mono */
48 SP_STEREO, /* Stereo */
49 SP_2DOT1, /* 2.1*/
50 SP_QUAD,/*Quadraquic*/
51 SP_FL | SP_FR | SP_FC | SP_SL | SP_SR,/*5 channels */
52 SP_5DOT1, /* 5.1 */
53};
54
55#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
47static void bf5xx_mmap_copy(struct snd_pcm_substream *substream, 56static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
48 snd_pcm_uframes_t count) 57 snd_pcm_uframes_t count)
49{ 58{
50 struct snd_pcm_runtime *runtime = substream->runtime; 59 struct snd_pcm_runtime *runtime = substream->runtime;
51 struct sport_device *sport = runtime->private_data; 60 struct sport_device *sport = runtime->private_data;
61 unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
52 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 62 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
53 bf5xx_pcm_to_ac97( 63 bf5xx_pcm_to_ac97((struct ac97_frame *)sport->tx_dma_buf +
54 (struct ac97_frame *)sport->tx_dma_buf + sport->tx_pos, 64 sport->tx_pos, (__u16 *)runtime->dma_area + sport->tx_pos *
55 (__u32 *)runtime->dma_area + sport->tx_pos, count); 65 runtime->channels, count, chan_mask);
56 sport->tx_pos += runtime->period_size; 66 sport->tx_pos += runtime->period_size;
57 if (sport->tx_pos >= runtime->buffer_size) 67 if (sport->tx_pos >= runtime->buffer_size)
58 sport->tx_pos %= runtime->buffer_size; 68 sport->tx_pos %= runtime->buffer_size;
59 sport->tx_delay_pos = sport->tx_pos; 69 sport->tx_delay_pos = sport->tx_pos;
60 } else { 70 } else {
61 bf5xx_ac97_to_pcm( 71 bf5xx_ac97_to_pcm((struct ac97_frame *)sport->rx_dma_buf +
62 (struct ac97_frame *)sport->rx_dma_buf + sport->rx_pos, 72 sport->rx_pos, (__u16 *)runtime->dma_area + sport->rx_pos *
63 (__u32 *)runtime->dma_area + sport->rx_pos, count); 73 runtime->channels, count);
64 sport->rx_pos += runtime->period_size; 74 sport->rx_pos += runtime->period_size;
65 if (sport->rx_pos >= runtime->buffer_size) 75 if (sport->rx_pos >= runtime->buffer_size)
66 sport->rx_pos %= runtime->buffer_size; 76 sport->rx_pos %= runtime->buffer_size;
@@ -71,7 +81,7 @@ static void bf5xx_mmap_copy(struct snd_pcm_substream *substream,
71static void bf5xx_dma_irq(void *data) 81static void bf5xx_dma_irq(void *data)
72{ 82{
73 struct snd_pcm_substream *pcm = data; 83 struct snd_pcm_substream *pcm = data;
74#if defined(CONFIG_SND_MMAP_SUPPORT) 84#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
75 struct snd_pcm_runtime *runtime = pcm->runtime; 85 struct snd_pcm_runtime *runtime = pcm->runtime;
76 struct sport_device *sport = runtime->private_data; 86 struct sport_device *sport = runtime->private_data;
77 bf5xx_mmap_copy(pcm, runtime->period_size); 87 bf5xx_mmap_copy(pcm, runtime->period_size);
@@ -90,17 +100,14 @@ static void bf5xx_dma_irq(void *data)
90 * The total rx/tx buffer is for ac97 frame to hold all pcm data 100 * The total rx/tx buffer is for ac97 frame to hold all pcm data
91 * is 0x20000 * sizeof(struct ac97_frame) / 4. 101 * is 0x20000 * sizeof(struct ac97_frame) / 4.
92 */ 102 */
93#ifdef CONFIG_SND_MMAP_SUPPORT
94static const struct snd_pcm_hardware bf5xx_pcm_hardware = { 103static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
95 .info = SNDRV_PCM_INFO_INTERLEAVED | 104 .info = SNDRV_PCM_INFO_INTERLEAVED |
105#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
96 SNDRV_PCM_INFO_MMAP | 106 SNDRV_PCM_INFO_MMAP |
97 SNDRV_PCM_INFO_MMAP_VALID | 107 SNDRV_PCM_INFO_MMAP_VALID |
98 SNDRV_PCM_INFO_BLOCK_TRANSFER,
99#else
100static const struct snd_pcm_hardware bf5xx_pcm_hardware = {
101 .info = SNDRV_PCM_INFO_INTERLEAVED |
102 SNDRV_PCM_INFO_BLOCK_TRANSFER,
103#endif 108#endif
109 SNDRV_PCM_INFO_BLOCK_TRANSFER,
110
104 .formats = SNDRV_PCM_FMTBIT_S16_LE, 111 .formats = SNDRV_PCM_FMTBIT_S16_LE,
105 .period_bytes_min = 32, 112 .period_bytes_min = 32,
106 .period_bytes_max = 0x10000, 113 .period_bytes_max = 0x10000,
@@ -123,10 +130,20 @@ static int bf5xx_pcm_hw_params(struct snd_pcm_substream *substream,
123 130
124static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream) 131static int bf5xx_pcm_hw_free(struct snd_pcm_substream *substream)
125{ 132{
133#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
126 struct snd_pcm_runtime *runtime = substream->runtime; 134 struct snd_pcm_runtime *runtime = substream->runtime;
135 struct sport_device *sport = runtime->private_data;
127 136
128 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 137 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
129 memset(runtime->dma_area, 0, runtime->buffer_size); 138 sport->once = 0;
139 if (runtime->dma_area)
140 memset(runtime->dma_area, 0, runtime->buffer_size);
141 memset(sport->tx_dma_buf, 0, runtime->buffer_size *
142 sizeof(struct ac97_frame));
143 } else
144 memset(sport->rx_dma_buf, 0, runtime->buffer_size *
145 sizeof(struct ac97_frame));
146#endif
130 snd_pcm_lib_free_pages(substream); 147 snd_pcm_lib_free_pages(substream);
131 return 0; 148 return 0;
132} 149}
@@ -139,7 +156,7 @@ static int bf5xx_pcm_prepare(struct snd_pcm_substream *substream)
139 /* An intermediate buffer is introduced for implementing mmap for 156 /* An intermediate buffer is introduced for implementing mmap for
140 * SPORT working in TMD mode(include AC97). 157 * SPORT working in TMD mode(include AC97).
141 */ 158 */
142#if defined(CONFIG_SND_MMAP_SUPPORT) 159#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
143 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 160 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
144 sport_set_tx_callback(sport, bf5xx_dma_irq, substream); 161 sport_set_tx_callback(sport, bf5xx_dma_irq, substream);
145 sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods, 162 sport_config_tx_dma(sport, sport->tx_dma_buf, runtime->periods,
@@ -173,24 +190,24 @@ static int bf5xx_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
173 switch (cmd) { 190 switch (cmd) {
174 case SNDRV_PCM_TRIGGER_START: 191 case SNDRV_PCM_TRIGGER_START:
175 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 192 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
193#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
176 bf5xx_mmap_copy(substream, runtime->period_size); 194 bf5xx_mmap_copy(substream, runtime->period_size);
177 snd_pcm_period_elapsed(substream);
178 sport->tx_delay_pos = 0; 195 sport->tx_delay_pos = 0;
196#endif
179 sport_tx_start(sport); 197 sport_tx_start(sport);
180 } 198 } else
181 else
182 sport_rx_start(sport); 199 sport_rx_start(sport);
183 break; 200 break;
184 case SNDRV_PCM_TRIGGER_STOP: 201 case SNDRV_PCM_TRIGGER_STOP:
185 case SNDRV_PCM_TRIGGER_SUSPEND: 202 case SNDRV_PCM_TRIGGER_SUSPEND:
186 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 203 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
187 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 204 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
188#if defined(CONFIG_SND_MMAP_SUPPORT) 205#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
189 sport->tx_pos = 0; 206 sport->tx_pos = 0;
190#endif 207#endif
191 sport_tx_stop(sport); 208 sport_tx_stop(sport);
192 } else { 209 } else {
193#if defined(CONFIG_SND_MMAP_SUPPORT) 210#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
194 sport->rx_pos = 0; 211 sport->rx_pos = 0;
195#endif 212#endif
196 sport_rx_stop(sport); 213 sport_rx_stop(sport);
@@ -208,7 +225,7 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream)
208 struct sport_device *sport = runtime->private_data; 225 struct sport_device *sport = runtime->private_data;
209 unsigned int curr; 226 unsigned int curr;
210 227
211#if defined(CONFIG_SND_MMAP_SUPPORT) 228#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
212 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 229 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
213 curr = sport->tx_delay_pos; 230 curr = sport->tx_delay_pos;
214 else 231 else
@@ -249,22 +266,7 @@ static int bf5xx_pcm_open(struct snd_pcm_substream *substream)
249 return ret; 266 return ret;
250} 267}
251 268
252static int bf5xx_pcm_close(struct snd_pcm_substream *substream) 269#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
253{
254 struct snd_pcm_runtime *runtime = substream->runtime;
255 struct sport_device *sport = runtime->private_data;
256
257 pr_debug("%s enter\n", __func__);
258 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
259 sport->once = 0;
260 memset(sport->tx_dma_buf, 0, runtime->buffer_size * sizeof(struct ac97_frame));
261 } else
262 memset(sport->rx_dma_buf, 0, runtime->buffer_size * sizeof(struct ac97_frame));
263
264 return 0;
265}
266
267#ifdef CONFIG_SND_MMAP_SUPPORT
268static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream, 270static int bf5xx_pcm_mmap(struct snd_pcm_substream *substream,
269 struct vm_area_struct *vma) 271 struct vm_area_struct *vma)
270{ 272{
@@ -281,32 +283,29 @@ static int bf5xx_pcm_copy(struct snd_pcm_substream *substream, int channel,
281 void __user *buf, snd_pcm_uframes_t count) 283 void __user *buf, snd_pcm_uframes_t count)
282{ 284{
283 struct snd_pcm_runtime *runtime = substream->runtime; 285 struct snd_pcm_runtime *runtime = substream->runtime;
284 286 unsigned int chan_mask = ac97_chan_mask[runtime->channels - 1];
285 pr_debug("%s copy pos:0x%lx count:0x%lx\n", 287 pr_debug("%s copy pos:0x%lx count:0x%lx\n",
286 substream->stream ? "Capture" : "Playback", pos, count); 288 substream->stream ? "Capture" : "Playback", pos, count);
287 289
288 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 290 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
289 bf5xx_pcm_to_ac97( 291 bf5xx_pcm_to_ac97((struct ac97_frame *)runtime->dma_area + pos,
290 (struct ac97_frame *)runtime->dma_area + pos, 292 (__u16 *)buf, count, chan_mask);
291 buf, count);
292 else 293 else
293 bf5xx_ac97_to_pcm( 294 bf5xx_ac97_to_pcm((struct ac97_frame *)runtime->dma_area + pos,
294 (struct ac97_frame *)runtime->dma_area + pos, 295 (__u16 *)buf, count);
295 buf, count);
296 return 0; 296 return 0;
297} 297}
298#endif 298#endif
299 299
300struct snd_pcm_ops bf5xx_pcm_ac97_ops = { 300struct snd_pcm_ops bf5xx_pcm_ac97_ops = {
301 .open = bf5xx_pcm_open, 301 .open = bf5xx_pcm_open,
302 .close = bf5xx_pcm_close,
303 .ioctl = snd_pcm_lib_ioctl, 302 .ioctl = snd_pcm_lib_ioctl,
304 .hw_params = bf5xx_pcm_hw_params, 303 .hw_params = bf5xx_pcm_hw_params,
305 .hw_free = bf5xx_pcm_hw_free, 304 .hw_free = bf5xx_pcm_hw_free,
306 .prepare = bf5xx_pcm_prepare, 305 .prepare = bf5xx_pcm_prepare,
307 .trigger = bf5xx_pcm_trigger, 306 .trigger = bf5xx_pcm_trigger,
308 .pointer = bf5xx_pcm_pointer, 307 .pointer = bf5xx_pcm_pointer,
309#ifdef CONFIG_SND_MMAP_SUPPORT 308#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
310 .mmap = bf5xx_pcm_mmap, 309 .mmap = bf5xx_pcm_mmap,
311#else 310#else
312 .copy = bf5xx_pcm_copy, 311 .copy = bf5xx_pcm_copy,
@@ -344,7 +343,7 @@ static int bf5xx_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
344 * Need to allocate local buffer when enable 343 * Need to allocate local buffer when enable
345 * MMAP for SPORT working in TMD mode (include AC97). 344 * MMAP for SPORT working in TMD mode (include AC97).
346 */ 345 */
347#if defined(CONFIG_SND_MMAP_SUPPORT) 346#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
348 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 347 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
349 if (!sport_handle->tx_dma_buf) { 348 if (!sport_handle->tx_dma_buf) {
350 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \ 349 sport_handle->tx_dma_buf = dma_alloc_coherent(NULL, \
@@ -381,7 +380,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
381 struct snd_pcm_substream *substream; 380 struct snd_pcm_substream *substream;
382 struct snd_dma_buffer *buf; 381 struct snd_dma_buffer *buf;
383 int stream; 382 int stream;
384#if defined(CONFIG_SND_MMAP_SUPPORT) 383#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
385 size_t size = bf5xx_pcm_hardware.buffer_bytes_max * 384 size_t size = bf5xx_pcm_hardware.buffer_bytes_max *
386 sizeof(struct ac97_frame) / 4; 385 sizeof(struct ac97_frame) / 4;
387#endif 386#endif
@@ -395,7 +394,7 @@ static void bf5xx_pcm_free_dma_buffers(struct snd_pcm *pcm)
395 continue; 394 continue;
396 dma_free_coherent(NULL, buf->bytes, buf->area, 0); 395 dma_free_coherent(NULL, buf->bytes, buf->area, 0);
397 buf->area = NULL; 396 buf->area = NULL;
398#if defined(CONFIG_SND_MMAP_SUPPORT) 397#if defined(CONFIG_SND_BF5XX_MMAP_SUPPORT)
399 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 398 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
400 if (sport_handle->tx_dma_buf) 399 if (sport_handle->tx_dma_buf)
401 dma_free_coherent(NULL, size, \ 400 dma_free_coherent(NULL, size, \
@@ -452,6 +451,18 @@ struct snd_soc_platform bf5xx_ac97_soc_platform = {
452}; 451};
453EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform); 452EXPORT_SYMBOL_GPL(bf5xx_ac97_soc_platform);
454 453
454static int __init bfin_ac97_init(void)
455{
456 return snd_soc_register_platform(&bf5xx_ac97_soc_platform);
457}
458module_init(bfin_ac97_init);
459
460static void __exit bfin_ac97_exit(void)
461{
462 snd_soc_unregister_platform(&bf5xx_ac97_soc_platform);
463}
464module_exit(bfin_ac97_exit);
465
455MODULE_AUTHOR("Cliff Cai"); 466MODULE_AUTHOR("Cliff Cai");
456MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module"); 467MODULE_DESCRIPTION("ADI Blackfin AC97 PCM DMA module");
457MODULE_LICENSE("GPL"); 468MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.c b/sound/soc/blackfin/bf5xx-ac97.c
index 5e5aafb6485f..3be2be60576d 100644
--- a/sound/soc/blackfin/bf5xx-ac97.c
+++ b/sound/soc/blackfin/bf5xx-ac97.c
@@ -54,71 +54,103 @@
54static int *cmd_count; 54static int *cmd_count;
55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM; 55static int sport_num = CONFIG_SND_BF5XX_SPORT_NUM;
56 56
57#if defined(CONFIG_BF54x) 57static u16 sport_req[][7] = {
58 PIN_REQ_SPORT_0,
59#ifdef PIN_REQ_SPORT_1
60 PIN_REQ_SPORT_1,
61#endif
62#ifdef PIN_REQ_SPORT_2
63 PIN_REQ_SPORT_2,
64#endif
65#ifdef PIN_REQ_SPORT_3
66 PIN_REQ_SPORT_3,
67#endif
68 };
69
58static struct sport_param sport_params[4] = { 70static struct sport_param sport_params[4] = {
59 { 71 {
60 .dma_rx_chan = CH_SPORT0_RX, 72 .dma_rx_chan = CH_SPORT0_RX,
61 .dma_tx_chan = CH_SPORT0_TX, 73 .dma_tx_chan = CH_SPORT0_TX,
62 .err_irq = IRQ_SPORT0_ERR, 74 .err_irq = IRQ_SPORT0_ERROR,
63 .regs = (struct sport_register *)SPORT0_TCR1, 75 .regs = (struct sport_register *)SPORT0_TCR1,
64 }, 76 },
77#ifdef PIN_REQ_SPORT_1
65 { 78 {
66 .dma_rx_chan = CH_SPORT1_RX, 79 .dma_rx_chan = CH_SPORT1_RX,
67 .dma_tx_chan = CH_SPORT1_TX, 80 .dma_tx_chan = CH_SPORT1_TX,
68 .err_irq = IRQ_SPORT1_ERR, 81 .err_irq = IRQ_SPORT1_ERROR,
69 .regs = (struct sport_register *)SPORT1_TCR1, 82 .regs = (struct sport_register *)SPORT1_TCR1,
70 }, 83 },
84#endif
85#ifdef PIN_REQ_SPORT_2
71 { 86 {
72 .dma_rx_chan = CH_SPORT2_RX, 87 .dma_rx_chan = CH_SPORT2_RX,
73 .dma_tx_chan = CH_SPORT2_TX, 88 .dma_tx_chan = CH_SPORT2_TX,
74 .err_irq = IRQ_SPORT2_ERR, 89 .err_irq = IRQ_SPORT2_ERROR,
75 .regs = (struct sport_register *)SPORT2_TCR1, 90 .regs = (struct sport_register *)SPORT2_TCR1,
76 }, 91 },
92#endif
93#ifdef PIN_REQ_SPORT_3
77 { 94 {
78 .dma_rx_chan = CH_SPORT3_RX, 95 .dma_rx_chan = CH_SPORT3_RX,
79 .dma_tx_chan = CH_SPORT3_TX, 96 .dma_tx_chan = CH_SPORT3_TX,
80 .err_irq = IRQ_SPORT3_ERR, 97 .err_irq = IRQ_SPORT3_ERROR,
81 .regs = (struct sport_register *)SPORT3_TCR1, 98 .regs = (struct sport_register *)SPORT3_TCR1,
82 } 99 }
83};
84#else
85static struct sport_param sport_params[2] = {
86 {
87 .dma_rx_chan = CH_SPORT0_RX,
88 .dma_tx_chan = CH_SPORT0_TX,
89 .err_irq = IRQ_SPORT0_ERROR,
90 .regs = (struct sport_register *)SPORT0_TCR1,
91 },
92 {
93 .dma_rx_chan = CH_SPORT1_RX,
94 .dma_tx_chan = CH_SPORT1_TX,
95 .err_irq = IRQ_SPORT1_ERROR,
96 .regs = (struct sport_register *)SPORT1_TCR1,
97 }
98};
99#endif 100#endif
101};
100 102
101void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \ 103void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src,
102 size_t count) 104 size_t count, unsigned int chan_mask)
103{ 105{
104 while (count--) { 106 while (count--) {
105 dst->ac97_tag = TAG_VALID | TAG_PCM; 107 dst->ac97_tag = TAG_VALID;
106 (dst++)->ac97_pcm = *src++; 108 if (chan_mask & SP_FL) {
109 dst->ac97_pcm_r = *src++;
110 dst->ac97_tag |= TAG_PCM_RIGHT;
111 }
112 if (chan_mask & SP_FR) {
113 dst->ac97_pcm_l = *src++;
114 dst->ac97_tag |= TAG_PCM_LEFT;
115
116 }
117#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
118 if (chan_mask & SP_SR) {
119 dst->ac97_sl = *src++;
120 dst->ac97_tag |= TAG_PCM_SL;
121 }
122 if (chan_mask & SP_SL) {
123 dst->ac97_sr = *src++;
124 dst->ac97_tag |= TAG_PCM_SR;
125 }
126 if (chan_mask & SP_LFE) {
127 dst->ac97_lfe = *src++;
128 dst->ac97_tag |= TAG_PCM_LFE;
129 }
130 if (chan_mask & SP_FC) {
131 dst->ac97_center = *src++;
132 dst->ac97_tag |= TAG_PCM_CENTER;
133 }
134#endif
135 dst++;
107 } 136 }
108} 137}
109EXPORT_SYMBOL(bf5xx_pcm_to_ac97); 138EXPORT_SYMBOL(bf5xx_pcm_to_ac97);
110 139
111void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \ 140void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst,
112 size_t count) 141 size_t count)
113{ 142{
114 while (count--) 143 while (count--) {
115 *(dst++) = (src++)->ac97_pcm; 144 *(dst++) = src->ac97_pcm_l;
145 *(dst++) = src->ac97_pcm_r;
146 src++;
147 }
116} 148}
117EXPORT_SYMBOL(bf5xx_ac97_to_pcm); 149EXPORT_SYMBOL(bf5xx_ac97_to_pcm);
118 150
119static unsigned int sport_tx_curr_frag(struct sport_device *sport) 151static unsigned int sport_tx_curr_frag(struct sport_device *sport)
120{ 152{
121 return sport->tx_curr_frag = sport_curr_offset_tx(sport) / \ 153 return sport->tx_curr_frag = sport_curr_offset_tx(sport) /
122 sport->tx_fragsize; 154 sport->tx_fragsize;
123} 155}
124 156
@@ -130,7 +162,7 @@ static void enqueue_cmd(struct snd_ac97 *ac97, __u16 addr, __u16 data)
130 162
131 sport_incfrag(sport, &nextfrag, 1); 163 sport_incfrag(sport, &nextfrag, 1);
132 164
133 nextwrite = (struct ac97_frame *)(sport->tx_buf + \ 165 nextwrite = (struct ac97_frame *)(sport->tx_buf +
134 nextfrag * sport->tx_fragsize); 166 nextfrag * sport->tx_fragsize);
135 pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n", 167 pr_debug("sport->tx_buf:%p, nextfrag:0x%x nextwrite:%p, cmd_count:%d\n",
136 sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]); 168 sport->tx_buf, nextfrag, nextwrite, cmd_count[nextfrag]);
@@ -237,8 +269,7 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
237EXPORT_SYMBOL_GPL(soc_ac97_ops); 269EXPORT_SYMBOL_GPL(soc_ac97_ops);
238 270
239#ifdef CONFIG_PM 271#ifdef CONFIG_PM
240static int bf5xx_ac97_suspend(struct platform_device *pdev, 272static int bf5xx_ac97_suspend(struct snd_soc_dai *dai)
241 struct snd_soc_dai *dai)
242{ 273{
243 struct sport_device *sport = 274 struct sport_device *sport =
244 (struct sport_device *)dai->private_data; 275 (struct sport_device *)dai->private_data;
@@ -253,8 +284,7 @@ static int bf5xx_ac97_suspend(struct platform_device *pdev,
253 return 0; 284 return 0;
254} 285}
255 286
256static int bf5xx_ac97_resume(struct platform_device *pdev, 287static int bf5xx_ac97_resume(struct snd_soc_dai *dai)
257 struct snd_soc_dai *dai)
258{ 288{
259 int ret; 289 int ret;
260 struct sport_device *sport = 290 struct sport_device *sport =
@@ -297,20 +327,15 @@ static int bf5xx_ac97_resume(struct platform_device *pdev,
297static int bf5xx_ac97_probe(struct platform_device *pdev, 327static int bf5xx_ac97_probe(struct platform_device *pdev,
298 struct snd_soc_dai *dai) 328 struct snd_soc_dai *dai)
299{ 329{
300 int ret; 330 int ret = 0;
301#if defined(CONFIG_BF54x)
302 u16 sport_req[][7] = {PIN_REQ_SPORT_0, PIN_REQ_SPORT_1,
303 PIN_REQ_SPORT_2, PIN_REQ_SPORT_3};
304#else
305 u16 sport_req[][7] = {PIN_REQ_SPORT_0, PIN_REQ_SPORT_1};
306#endif
307 cmd_count = (int *)get_zeroed_page(GFP_KERNEL); 331 cmd_count = (int *)get_zeroed_page(GFP_KERNEL);
308 if (cmd_count == NULL) 332 if (cmd_count == NULL)
309 return -ENOMEM; 333 return -ENOMEM;
310 334
311 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) { 335 if (peripheral_request_list(&sport_req[sport_num][0], "soc-audio")) {
312 pr_err("Requesting Peripherals failed\n"); 336 pr_err("Requesting Peripherals failed\n");
313 return -EFAULT; 337 ret = -EFAULT;
338 goto peripheral_err;
314 } 339 }
315 340
316#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 341#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
@@ -318,54 +343,54 @@ static int bf5xx_ac97_probe(struct platform_device *pdev,
318 if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) { 343 if (gpio_request(CONFIG_SND_BF5XX_RESET_GPIO_NUM, "SND_AD198x RESET")) {
319 pr_err("Failed to request GPIO_%d for reset\n", 344 pr_err("Failed to request GPIO_%d for reset\n",
320 CONFIG_SND_BF5XX_RESET_GPIO_NUM); 345 CONFIG_SND_BF5XX_RESET_GPIO_NUM);
321 peripheral_free_list(&sport_req[sport_num][0]); 346 ret = -1;
322 return -1; 347 goto gpio_err;
323 } 348 }
324 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1); 349 gpio_direction_output(CONFIG_SND_BF5XX_RESET_GPIO_NUM, 1);
325#endif 350#endif
326 sport_handle = sport_init(&sport_params[sport_num], 2, \ 351 sport_handle = sport_init(&sport_params[sport_num], 2, \
327 sizeof(struct ac97_frame), NULL); 352 sizeof(struct ac97_frame), NULL);
328 if (!sport_handle) { 353 if (!sport_handle) {
329 peripheral_free_list(&sport_req[sport_num][0]); 354 ret = -ENODEV;
330#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 355 goto sport_err;
331 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
332#endif
333 return -ENODEV;
334 } 356 }
335 /*SPORT works in TDM mode to simulate AC97 transfers*/ 357 /*SPORT works in TDM mode to simulate AC97 transfers*/
336 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1); 358 ret = sport_set_multichannel(sport_handle, 16, 0x1F, 1);
337 if (ret) { 359 if (ret) {
338 pr_err("SPORT is busy!\n"); 360 pr_err("SPORT is busy!\n");
339 kfree(sport_handle); 361 ret = -EBUSY;
340 peripheral_free_list(&sport_req[sport_num][0]); 362 goto sport_config_err;
341#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
342 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
343#endif
344 return -EBUSY;
345 } 363 }
346 364
347 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1)); 365 ret = sport_config_rx(sport_handle, IRFS, 0xF, 0, (16*16-1));
348 if (ret) { 366 if (ret) {
349 pr_err("SPORT is busy!\n"); 367 pr_err("SPORT is busy!\n");
350 kfree(sport_handle); 368 ret = -EBUSY;
351 peripheral_free_list(&sport_req[sport_num][0]); 369 goto sport_config_err;
352#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
353 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
354#endif
355 return -EBUSY;
356 } 370 }
357 371
358 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1)); 372 ret = sport_config_tx(sport_handle, ITFS, 0xF, 0, (16*16-1));
359 if (ret) { 373 if (ret) {
360 pr_err("SPORT is busy!\n"); 374 pr_err("SPORT is busy!\n");
361 kfree(sport_handle); 375 ret = -EBUSY;
362 peripheral_free_list(&sport_req[sport_num][0]); 376 goto sport_config_err;
363#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
364 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
365#endif
366 return -EBUSY;
367 } 377 }
378
368 return 0; 379 return 0;
380
381sport_config_err:
382 kfree(sport_handle);
383sport_err:
384#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
385 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
386#endif
387gpio_err:
388 peripheral_free_list(&sport_req[sport_num][0]);
389peripheral_err:
390 free_page((unsigned long)cmd_count);
391 cmd_count = NULL;
392
393 return ret;
369} 394}
370 395
371static void bf5xx_ac97_remove(struct platform_device *pdev, 396static void bf5xx_ac97_remove(struct platform_device *pdev,
@@ -373,6 +398,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
373{ 398{
374 free_page((unsigned long)cmd_count); 399 free_page((unsigned long)cmd_count);
375 cmd_count = NULL; 400 cmd_count = NULL;
401 peripheral_free_list(&sport_req[sport_num][0]);
376#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET 402#ifdef CONFIG_SND_BF5XX_HAVE_COLD_RESET
377 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM); 403 gpio_free(CONFIG_SND_BF5XX_RESET_GPIO_NUM);
378#endif 404#endif
@@ -381,7 +407,7 @@ static void bf5xx_ac97_remove(struct platform_device *pdev,
381struct snd_soc_dai bfin_ac97_dai = { 407struct snd_soc_dai bfin_ac97_dai = {
382 .name = "bf5xx-ac97", 408 .name = "bf5xx-ac97",
383 .id = 0, 409 .id = 0,
384 .type = SND_SOC_DAI_AC97, 410 .ac97_control = 1,
385 .probe = bf5xx_ac97_probe, 411 .probe = bf5xx_ac97_probe,
386 .remove = bf5xx_ac97_remove, 412 .remove = bf5xx_ac97_remove,
387 .suspend = bf5xx_ac97_suspend, 413 .suspend = bf5xx_ac97_suspend,
@@ -389,7 +415,11 @@ struct snd_soc_dai bfin_ac97_dai = {
389 .playback = { 415 .playback = {
390 .stream_name = "AC97 Playback", 416 .stream_name = "AC97 Playback",
391 .channels_min = 2, 417 .channels_min = 2,
418#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
419 .channels_max = 6,
420#else
392 .channels_max = 2, 421 .channels_max = 2,
422#endif
393 .rates = SNDRV_PCM_RATE_48000, 423 .rates = SNDRV_PCM_RATE_48000,
394 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 424 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
395 .capture = { 425 .capture = {
@@ -401,6 +431,18 @@ struct snd_soc_dai bfin_ac97_dai = {
401}; 431};
402EXPORT_SYMBOL_GPL(bfin_ac97_dai); 432EXPORT_SYMBOL_GPL(bfin_ac97_dai);
403 433
434static int __init bfin_ac97_init(void)
435{
436 return snd_soc_register_dai(&bfin_ac97_dai);
437}
438module_init(bfin_ac97_init);
439
440static void __exit bfin_ac97_exit(void)
441{
442 snd_soc_unregister_dai(&bfin_ac97_dai);
443}
444module_exit(bfin_ac97_exit);
445
404MODULE_AUTHOR("Roy Huang"); 446MODULE_AUTHOR("Roy Huang");
405MODULE_DESCRIPTION("AC97 driver for ADI Blackfin"); 447MODULE_DESCRIPTION("AC97 driver for ADI Blackfin");
406MODULE_LICENSE("GPL"); 448MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-ac97.h b/sound/soc/blackfin/bf5xx-ac97.h
index 3f77cc558dc0..3f2a911fe0cb 100644
--- a/sound/soc/blackfin/bf5xx-ac97.h
+++ b/sound/soc/blackfin/bf5xx-ac97.h
@@ -16,21 +16,46 @@ struct ac97_frame {
16 u16 ac97_tag; /* slot 0 */ 16 u16 ac97_tag; /* slot 0 */
17 u16 ac97_addr; /* slot 1 */ 17 u16 ac97_addr; /* slot 1 */
18 u16 ac97_data; /* slot 2 */ 18 u16 ac97_data; /* slot 2 */
19 u32 ac97_pcm; /* slot 3 and 4: left and right pcm data */ 19 u16 ac97_pcm_l; /*slot 3:front left*/
20 u16 ac97_pcm_r; /*slot 4:front left*/
21#if defined(CONFIG_SND_BF5XX_MULTICHAN_SUPPORT)
22 u16 ac97_mdm_l1;
23 u16 ac97_center; /*slot 6:center*/
24 u16 ac97_sl; /*slot 7:surround left*/
25 u16 ac97_sr; /*slot 8:surround right*/
26 u16 ac97_lfe; /*slot 9:lfe*/
27#endif
20} __attribute__ ((packed)); 28} __attribute__ ((packed));
21 29
30/* Speaker location */
31#define SP_FL 0x0001
32#define SP_FR 0x0010
33#define SP_FC 0x0002
34#define SP_LFE 0x0020
35#define SP_SL 0x0004
36#define SP_SR 0x0040
37
38#define SP_STEREO (SP_FL | SP_FR)
39#define SP_2DOT1 (SP_FL | SP_FR | SP_LFE)
40#define SP_QUAD (SP_FL | SP_FR | SP_SL | SP_SR)
41#define SP_5DOT1 (SP_FL | SP_FR | SP_FC | SP_LFE | SP_SL | SP_SR)
42
22#define TAG_VALID 0x8000 43#define TAG_VALID 0x8000
23#define TAG_CMD 0x6000 44#define TAG_CMD 0x6000
24#define TAG_PCM_LEFT 0x1000 45#define TAG_PCM_LEFT 0x1000
25#define TAG_PCM_RIGHT 0x0800 46#define TAG_PCM_RIGHT 0x0800
26#define TAG_PCM (TAG_PCM_LEFT | TAG_PCM_RIGHT) 47#define TAG_PCM_MDM_L1 0x0400
48#define TAG_PCM_CENTER 0x0200
49#define TAG_PCM_SL 0x0100
50#define TAG_PCM_SR 0x0080
51#define TAG_PCM_LFE 0x0040
27 52
28extern struct snd_soc_dai bfin_ac97_dai; 53extern struct snd_soc_dai bfin_ac97_dai;
29 54
30void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u32 *src, \ 55void bf5xx_pcm_to_ac97(struct ac97_frame *dst, const __u16 *src, \
31 size_t count); 56 size_t count, unsigned int chan_mask);
32 57
33void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u32 *dst, \ 58void bf5xx_ac97_to_pcm(const struct ac97_frame *src, __u16 *dst, \
34 size_t count); 59 size_t count);
35 60
36#endif 61#endif
diff --git a/sound/soc/blackfin/bf5xx-ad1980.c b/sound/soc/blackfin/bf5xx-ad1980.c
index 124425d22320..d8f591273778 100644
--- a/sound/soc/blackfin/bf5xx-ad1980.c
+++ b/sound/soc/blackfin/bf5xx-ad1980.c
@@ -43,7 +43,7 @@
43#include "bf5xx-ac97-pcm.h" 43#include "bf5xx-ac97-pcm.h"
44#include "bf5xx-ac97.h" 44#include "bf5xx-ac97.h"
45 45
46static struct snd_soc_machine bf5xx_board; 46static struct snd_soc_card bf5xx_board;
47 47
48static int bf5xx_board_startup(struct snd_pcm_substream *substream) 48static int bf5xx_board_startup(struct snd_pcm_substream *substream)
49{ 49{
@@ -67,15 +67,15 @@ static struct snd_soc_dai_link bf5xx_board_dai = {
67 .ops = &bf5xx_board_ops, 67 .ops = &bf5xx_board_ops,
68}; 68};
69 69
70static struct snd_soc_machine bf5xx_board = { 70static struct snd_soc_card bf5xx_board = {
71 .name = "bf5xx-board", 71 .name = "bf5xx-board",
72 .platform = &bf5xx_ac97_soc_platform,
72 .dai_link = &bf5xx_board_dai, 73 .dai_link = &bf5xx_board_dai,
73 .num_links = 1, 74 .num_links = 1,
74}; 75};
75 76
76static struct snd_soc_device bf5xx_board_snd_devdata = { 77static struct snd_soc_device bf5xx_board_snd_devdata = {
77 .machine = &bf5xx_board, 78 .card = &bf5xx_board,
78 .platform = &bf5xx_ac97_soc_platform,
79 .codec_dev = &soc_codec_dev_ad1980, 79 .codec_dev = &soc_codec_dev_ad1980,
80}; 80};
81 81
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 622c9b909532..7f2a5e199075 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -65,7 +65,7 @@
65 65
66#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE 66#define GPIO_SE CONFIG_SND_BFIN_AD73311_SE
67 67
68static struct snd_soc_machine bf5xx_ad73311; 68static struct snd_soc_card bf5xx_ad73311;
69 69
70static int snd_ad73311_startup(void) 70static int snd_ad73311_startup(void)
71{ 71{
@@ -168,7 +168,7 @@ static int bf5xx_ad73311_hw_params(struct snd_pcm_substream *substream,
168 params_format(params)); 168 params_format(params));
169 169
170 /* set cpu DAI configuration */ 170 /* set cpu DAI configuration */
171 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | 171 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A |
172 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 172 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
173 if (ret < 0) 173 if (ret < 0)
174 return ret; 174 return ret;
@@ -190,16 +190,16 @@ static struct snd_soc_dai_link bf5xx_ad73311_dai = {
190 .ops = &bf5xx_ad73311_ops, 190 .ops = &bf5xx_ad73311_ops,
191}; 191};
192 192
193static struct snd_soc_machine bf5xx_ad73311 = { 193static struct snd_soc_card bf5xx_ad73311 = {
194 .name = "bf5xx_ad73311", 194 .name = "bf5xx_ad73311",
195 .platform = &bf5xx_i2s_soc_platform,
195 .probe = bf5xx_probe, 196 .probe = bf5xx_probe,
196 .dai_link = &bf5xx_ad73311_dai, 197 .dai_link = &bf5xx_ad73311_dai,
197 .num_links = 1, 198 .num_links = 1,
198}; 199};
199 200
200static struct snd_soc_device bf5xx_ad73311_snd_devdata = { 201static struct snd_soc_device bf5xx_ad73311_snd_devdata = {
201 .machine = &bf5xx_ad73311, 202 .card = &bf5xx_ad73311,
202 .platform = &bf5xx_i2s_soc_platform,
203 .codec_dev = &soc_codec_dev_ad73311, 203 .codec_dev = &soc_codec_dev_ad73311,
204}; 204};
205 205
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c
index 61fccf925192..53d290b3ea47 100644
--- a/sound/soc/blackfin/bf5xx-i2s-pcm.c
+++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c
@@ -283,6 +283,18 @@ struct snd_soc_platform bf5xx_i2s_soc_platform = {
283}; 283};
284EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform); 284EXPORT_SYMBOL_GPL(bf5xx_i2s_soc_platform);
285 285
286static int __init bfin_i2s_init(void)
287{
288 return snd_soc_register_platform(&bf5xx_i2s_soc_platform);
289}
290module_init(bfin_i2s_init);
291
292static void __exit bfin_i2s_exit(void)
293{
294 snd_soc_unregister_platform(&bf5xx_i2s_soc_platform);
295}
296module_exit(bfin_i2s_exit);
297
286MODULE_AUTHOR("Cliff Cai"); 298MODULE_AUTHOR("Cliff Cai");
287MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module"); 299MODULE_DESCRIPTION("ADI Blackfin I2S PCM DMA module");
288MODULE_LICENSE("GPL"); 300MODULE_LICENSE("GPL");
diff --git a/sound/soc/blackfin/bf5xx-i2s.c b/sound/soc/blackfin/bf5xx-i2s.c
index e020c160ee44..d1d95d2393fe 100644
--- a/sound/soc/blackfin/bf5xx-i2s.c
+++ b/sound/soc/blackfin/bf5xx-i2s.c
@@ -132,7 +132,8 @@ static int bf5xx_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
132 return ret; 132 return ret;
133} 133}
134 134
135static int bf5xx_i2s_startup(struct snd_pcm_substream *substream) 135static int bf5xx_i2s_startup(struct snd_pcm_substream *substream,
136 struct snd_soc_dai *dai)
136{ 137{
137 pr_debug("%s enter\n", __func__); 138 pr_debug("%s enter\n", __func__);
138 139
@@ -142,7 +143,8 @@ static int bf5xx_i2s_startup(struct snd_pcm_substream *substream)
142} 143}
143 144
144static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream, 145static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
145 struct snd_pcm_hw_params *params) 146 struct snd_pcm_hw_params *params,
147 struct snd_soc_dai *dai)
146{ 148{
147 int ret = 0; 149 int ret = 0;
148 150
@@ -193,7 +195,8 @@ static int bf5xx_i2s_hw_params(struct snd_pcm_substream *substream,
193 return 0; 195 return 0;
194} 196}
195 197
196static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream) 198static void bf5xx_i2s_shutdown(struct snd_pcm_substream *substream,
199 struct snd_soc_dai *dai)
197{ 200{
198 pr_debug("%s enter\n", __func__); 201 pr_debug("%s enter\n", __func__);
199 bf5xx_i2s.counter--; 202 bf5xx_i2s.counter--;
@@ -219,16 +222,14 @@ static int bf5xx_i2s_probe(struct platform_device *pdev,
219 return 0; 222 return 0;
220} 223}
221 224
222static void bf5xx_i2s_remove(struct platform_device *pdev, 225static void bf5xx_i2s_remove(struct snd_soc_dai *dai)
223 struct snd_soc_dai *dai)
224{ 226{
225 pr_debug("%s enter\n", __func__); 227 pr_debug("%s enter\n", __func__);
226 peripheral_free_list(&sport_req[sport_num][0]); 228 peripheral_free_list(&sport_req[sport_num][0]);
227} 229}
228 230
229#ifdef CONFIG_PM 231#ifdef CONFIG_PM
230static int bf5xx_i2s_suspend(struct platform_device *dev, 232static int bf5xx_i2s_suspend(struct snd_soc_dai *dai)
231 struct snd_soc_dai *dai)
232{ 233{
233 struct sport_device *sport = 234 struct sport_device *sport =
234 (struct sport_device *)dai->private_data; 235 (struct sport_device *)dai->private_data;
@@ -289,7 +290,6 @@ static int bf5xx_i2s_resume(struct platform_device *pdev,
289struct snd_soc_dai bf5xx_i2s_dai = { 290struct snd_soc_dai bf5xx_i2s_dai = {
290 .name = "bf5xx-i2s", 291 .name = "bf5xx-i2s",
291 .id = 0, 292 .id = 0,
292 .type = SND_SOC_DAI_I2S,
293 .probe = bf5xx_i2s_probe, 293 .probe = bf5xx_i2s_probe,
294 .remove = bf5xx_i2s_remove, 294 .remove = bf5xx_i2s_remove,
295 .suspend = bf5xx_i2s_suspend, 295 .suspend = bf5xx_i2s_suspend,
@@ -307,13 +307,24 @@ struct snd_soc_dai bf5xx_i2s_dai = {
307 .ops = { 307 .ops = {
308 .startup = bf5xx_i2s_startup, 308 .startup = bf5xx_i2s_startup,
309 .shutdown = bf5xx_i2s_shutdown, 309 .shutdown = bf5xx_i2s_shutdown,
310 .hw_params = bf5xx_i2s_hw_params,}, 310 .hw_params = bf5xx_i2s_hw_params,
311 .dai_ops = {
312 .set_fmt = bf5xx_i2s_set_dai_fmt, 311 .set_fmt = bf5xx_i2s_set_dai_fmt,
313 }, 312 },
314}; 313};
315EXPORT_SYMBOL_GPL(bf5xx_i2s_dai); 314EXPORT_SYMBOL_GPL(bf5xx_i2s_dai);
316 315
316static int __init bfin_i2s_init(void)
317{
318 return snd_soc_register_dai(&bf5xx_i2s_dai);
319}
320module_init(bfin_i2s_init);
321
322static void __exit bfin_i2s_exit(void)
323{
324 snd_soc_unregister_dai(&bf5xx_i2s_dai);
325}
326module_exit(bfin_i2s_exit);
327
317/* Module information */ 328/* Module information */
318MODULE_AUTHOR("Cliff Cai"); 329MODULE_AUTHOR("Cliff Cai");
319MODULE_DESCRIPTION("I2S driver for ADI Blackfin"); 330MODULE_DESCRIPTION("I2S driver for ADI Blackfin");
diff --git a/sound/soc/blackfin/bf5xx-sport.h b/sound/soc/blackfin/bf5xx-sport.h
index fcadcc081f7f..2e63dea73e9c 100644
--- a/sound/soc/blackfin/bf5xx-sport.h
+++ b/sound/soc/blackfin/bf5xx-sport.h
@@ -116,7 +116,7 @@ struct sport_device {
116 void *err_data; 116 void *err_data;
117 unsigned char *tx_dma_buf; 117 unsigned char *tx_dma_buf;
118 unsigned char *rx_dma_buf; 118 unsigned char *rx_dma_buf;
119#ifdef CONFIG_SND_MMAP_SUPPORT 119#ifdef CONFIG_SND_BF5XX_MMAP_SUPPORT
120 dma_addr_t tx_dma_phy; 120 dma_addr_t tx_dma_phy;
121 dma_addr_t rx_dma_phy; 121 dma_addr_t rx_dma_phy;
122 int tx_pos;/*pcm sample count*/ 122 int tx_pos;/*pcm sample count*/
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index e15f67fd7769..bc0cdded7116 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -44,7 +44,7 @@
44#include "bf5xx-i2s-pcm.h" 44#include "bf5xx-i2s-pcm.h"
45#include "bf5xx-i2s.h" 45#include "bf5xx-i2s.h"
46 46
47static struct snd_soc_machine bf5xx_ssm2602; 47static struct snd_soc_card bf5xx_ssm2602;
48 48
49static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream) 49static int bf5xx_ssm2602_startup(struct snd_pcm_substream *substream)
50{ 50{
@@ -92,17 +92,17 @@ static int bf5xx_ssm2602_hw_params(struct snd_pcm_substream *substream,
92 */ 92 */
93 93
94 /* set codec DAI configuration */ 94 /* set codec DAI configuration */
95 ret = codec_dai->dai_ops.set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 95 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
96 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 96 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
97 if (ret < 0) 97 if (ret < 0)
98 return ret; 98 return ret;
99 /* set cpu DAI configuration */ 99 /* set cpu DAI configuration */
100 ret = cpu_dai->dai_ops.set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | 100 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
101 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 101 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
102 if (ret < 0) 102 if (ret < 0)
103 return ret; 103 return ret;
104 104
105 ret = codec_dai->dai_ops.set_sysclk(codec_dai, SSM2602_SYSCLK, clk, 105 ret = snd_soc_dai_set_sysclk(codec_dai, SSM2602_SYSCLK, clk,
106 SND_SOC_CLOCK_IN); 106 SND_SOC_CLOCK_IN);
107 if (ret < 0) 107 if (ret < 0)
108 return ret; 108 return ret;
@@ -135,15 +135,15 @@ static struct ssm2602_setup_data bf5xx_ssm2602_setup = {
135 .i2c_address = 0x1b, 135 .i2c_address = 0x1b,
136}; 136};
137 137
138static struct snd_soc_machine bf5xx_ssm2602 = { 138static struct snd_soc_card bf5xx_ssm2602 = {
139 .name = "bf5xx_ssm2602", 139 .name = "bf5xx_ssm2602",
140 .platform = &bf5xx_i2s_soc_platform,
140 .dai_link = &bf5xx_ssm2602_dai, 141 .dai_link = &bf5xx_ssm2602_dai,
141 .num_links = 1, 142 .num_links = 1,
142}; 143};
143 144
144static struct snd_soc_device bf5xx_ssm2602_snd_devdata = { 145static struct snd_soc_device bf5xx_ssm2602_snd_devdata = {
145 .machine = &bf5xx_ssm2602, 146 .card = &bf5xx_ssm2602,
146 .platform = &bf5xx_i2s_soc_platform,
147 .codec_dev = &soc_codec_dev_ssm2602, 147 .codec_dev = &soc_codec_dev_ssm2602,
148 .codec_data = &bf5xx_ssm2602_setup, 148 .codec_data = &bf5xx_ssm2602_setup,
149}; 149};
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 38a0e3b620a7..c41289b5f586 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -1,31 +1,40 @@
1config SND_SOC_ALL_CODECS 1config SND_SOC_ALL_CODECS
2 tristate "Build all ASoC CODEC drivers" 2 tristate "Build all ASoC CODEC drivers"
3 depends on I2C 3 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
4 select SPI 4 select SND_SOC_AD1980 if SND_SOC_AC97_BUS
5 select SPI_MASTER 5 select SND_SOC_AD73311 if I2C
6 select SND_SOC_AD73311 6 select SND_SOC_AK4535 if I2C
7 select SND_SOC_AK4535 7 select SND_SOC_CS4270 if I2C
8 select SND_SOC_CS4270 8 select SND_SOC_PCM3008
9 select SND_SOC_SSM2602 9 select SND_SOC_SSM2602 if I2C
10 select SND_SOC_TLV320AIC23 10 select SND_SOC_TLV320AIC23 if I2C
11 select SND_SOC_TLV320AIC26 11 select SND_SOC_TLV320AIC26 if SPI_MASTER
12 select SND_SOC_TLV320AIC3X 12 select SND_SOC_TLV320AIC3X if I2C
13 select SND_SOC_UDA1380 13 select SND_SOC_TWL4030 if TWL4030_CORE
14 select SND_SOC_WM8510 14 select SND_SOC_UDA134X
15 select SND_SOC_WM8580 15 select SND_SOC_UDA1380 if I2C
16 select SND_SOC_WM8731 16 select SND_SOC_WM8350 if MFD_WM8350
17 select SND_SOC_WM8750 17 select SND_SOC_WM8510 if (I2C || SPI_MASTER)
18 select SND_SOC_WM8753 18 select SND_SOC_WM8580 if I2C
19 select SND_SOC_WM8900 19 select SND_SOC_WM8728 if (I2C || SPI_MASTER)
20 select SND_SOC_WM8903 20 select SND_SOC_WM8731 if (I2C || SPI_MASTER)
21 select SND_SOC_WM8971 21 select SND_SOC_WM8750 if (I2C || SPI_MASTER)
22 select SND_SOC_WM8990 22 select SND_SOC_WM8753 if (I2C || SPI_MASTER)
23 select SND_SOC_WM8900 if I2C
24 select SND_SOC_WM8903 if I2C
25 select SND_SOC_WM8971 if I2C
26 select SND_SOC_WM8990 if I2C
27 select SND_SOC_WM9712 if SND_SOC_AC97_BUS
28 select SND_SOC_WM9713 if SND_SOC_AC97_BUS
23 help 29 help
24 Normally ASoC codec drivers are only built if a machine driver which 30 Normally ASoC codec drivers are only built if a machine driver which
25 uses them is also built since they are only usable with a machine 31 uses them is also built since they are only usable with a machine
26 driver. Selecting this option will allow these drivers to be built 32 driver. Selecting this option will allow these drivers to be built
27 without an explicit machine driver for test and development purposes. 33 without an explicit machine driver for test and development purposes.
28 34
35 Support for the bus types used to access the codecs to be built must
36 be selected separately.
37
29 If unsure select "N". 38 If unsure select "N".
30 39
31 40
@@ -60,6 +69,12 @@ config SND_SOC_CS4270_VD33_ERRATA
60 bool 69 bool
61 depends on SND_SOC_CS4270 70 depends on SND_SOC_CS4270
62 71
72config SND_SOC_L3
73 tristate
74
75config SND_SOC_PCM3008
76 tristate
77
63config SND_SOC_SSM2602 78config SND_SOC_SSM2602
64 tristate 79 tristate
65 80
@@ -75,15 +90,29 @@ config SND_SOC_TLV320AIC3X
75 tristate 90 tristate
76 depends on I2C 91 depends on I2C
77 92
93config SND_SOC_TWL4030
94 tristate
95 depends on TWL4030_CORE
96
97config SND_SOC_UDA134X
98 tristate
99 select SND_SOC_L3
100
78config SND_SOC_UDA1380 101config SND_SOC_UDA1380
79 tristate 102 tristate
80 103
104config SND_SOC_WM8350
105 tristate
106
81config SND_SOC_WM8510 107config SND_SOC_WM8510
82 tristate 108 tristate
83 109
84config SND_SOC_WM8580 110config SND_SOC_WM8580
85 tristate 111 tristate
86 112
113config SND_SOC_WM8728
114 tristate
115
87config SND_SOC_WM8731 116config SND_SOC_WM8731
88 tristate 117 tristate
89 118
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 90f0a585fc70..c4ddc9aa2bbd 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -3,13 +3,19 @@ snd-soc-ad1980-objs := ad1980.o
3snd-soc-ad73311-objs := ad73311.o 3snd-soc-ad73311-objs := ad73311.o
4snd-soc-ak4535-objs := ak4535.o 4snd-soc-ak4535-objs := ak4535.o
5snd-soc-cs4270-objs := cs4270.o 5snd-soc-cs4270-objs := cs4270.o
6snd-soc-l3-objs := l3.o
7snd-soc-pcm3008-objs := pcm3008.o
6snd-soc-ssm2602-objs := ssm2602.o 8snd-soc-ssm2602-objs := ssm2602.o
7snd-soc-tlv320aic23-objs := tlv320aic23.o 9snd-soc-tlv320aic23-objs := tlv320aic23.o
8snd-soc-tlv320aic26-objs := tlv320aic26.o 10snd-soc-tlv320aic26-objs := tlv320aic26.o
9snd-soc-tlv320aic3x-objs := tlv320aic3x.o 11snd-soc-tlv320aic3x-objs := tlv320aic3x.o
12snd-soc-twl4030-objs := twl4030.o
13snd-soc-uda134x-objs := uda134x.o
10snd-soc-uda1380-objs := uda1380.o 14snd-soc-uda1380-objs := uda1380.o
15snd-soc-wm8350-objs := wm8350.o
11snd-soc-wm8510-objs := wm8510.o 16snd-soc-wm8510-objs := wm8510.o
12snd-soc-wm8580-objs := wm8580.o 17snd-soc-wm8580-objs := wm8580.o
18snd-soc-wm8728-objs := wm8728.o
13snd-soc-wm8731-objs := wm8731.o 19snd-soc-wm8731-objs := wm8731.o
14snd-soc-wm8750-objs := wm8750.o 20snd-soc-wm8750-objs := wm8750.o
15snd-soc-wm8753-objs := wm8753.o 21snd-soc-wm8753-objs := wm8753.o
@@ -25,13 +31,19 @@ obj-$(CONFIG_SND_SOC_AD1980) += snd-soc-ad1980.o
25obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o 31obj-$(CONFIG_SND_SOC_AD73311) += snd-soc-ad73311.o
26obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o 32obj-$(CONFIG_SND_SOC_AK4535) += snd-soc-ak4535.o
27obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 33obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
34obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
35obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
28obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 36obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
29obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 37obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
30obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 38obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
31obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o 39obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
40obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
41obj-$(CONFIG_SND_SOC_UDA134X) += snd-soc-uda134x.o
32obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o 42obj-$(CONFIG_SND_SOC_UDA1380) += snd-soc-uda1380.o
43obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
33obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 44obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
34obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o 45obj-$(CONFIG_SND_SOC_WM8580) += snd-soc-wm8580.o
46obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
35obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 47obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
36obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 48obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
37obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 49obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index bd1ebdc6c86c..fb53e6511af2 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -24,7 +24,8 @@
24 24
25#define AC97_VERSION "0.6" 25#define AC97_VERSION "0.6"
26 26
27static int ac97_prepare(struct snd_pcm_substream *substream) 27static int ac97_prepare(struct snd_pcm_substream *substream,
28 struct snd_soc_dai *dai)
28{ 29{
29 struct snd_pcm_runtime *runtime = substream->runtime; 30 struct snd_pcm_runtime *runtime = substream->runtime;
30 struct snd_soc_pcm_runtime *rtd = substream->private_data; 31 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -42,7 +43,7 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
42 43
43struct snd_soc_dai ac97_dai = { 44struct snd_soc_dai ac97_dai = {
44 .name = "AC97 HiFi", 45 .name = "AC97 HiFi",
45 .type = SND_SOC_DAI_AC97, 46 .ac97_control = 1,
46 .playback = { 47 .playback = {
47 .stream_name = "AC97 Playback", 48 .stream_name = "AC97 Playback",
48 .channels_min = 1, 49 .channels_min = 1,
@@ -113,7 +114,7 @@ static int ac97_soc_probe(struct platform_device *pdev)
113 if (ret < 0) 114 if (ret < 0)
114 goto bus_err; 115 goto bus_err;
115 116
116 ret = snd_soc_register_card(socdev); 117 ret = snd_soc_init_card(socdev);
117 if (ret < 0) 118 if (ret < 0)
118 goto bus_err; 119 goto bus_err;
119 return 0; 120 return 0;
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 1397b8e06c0b..73fdbb4d4a3d 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -85,6 +85,9 @@ SOC_DOUBLE("Line HP Swap Switch", AC97_AD_MISC, 10, 5, 1, 0),
85SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1), 85SOC_DOUBLE("Surround Playback Volume", AC97_SURROUND_MASTER, 8, 0, 31, 1),
86SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1), 86SOC_DOUBLE("Surround Playback Switch", AC97_SURROUND_MASTER, 15, 7, 1, 1),
87 87
88SOC_DOUBLE("Center/LFE Playback Volume", AC97_CENTER_LFE_MASTER, 8, 0, 31, 1),
89SOC_DOUBLE("Center/LFE Playback Switch", AC97_CENTER_LFE_MASTER, 15, 7, 1, 1),
90
88SOC_ENUM("Capture Source", ad1980_cap_src), 91SOC_ENUM("Capture Source", ad1980_cap_src),
89 92
90SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0), 93SOC_SINGLE("Mic Boost Switch", AC97_MIC, 6, 1, 0),
@@ -142,10 +145,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
142 145
143struct snd_soc_dai ad1980_dai = { 146struct snd_soc_dai ad1980_dai = {
144 .name = "AC97", 147 .name = "AC97",
148 .ac97_control = 1,
145 .playback = { 149 .playback = {
146 .stream_name = "Playback", 150 .stream_name = "Playback",
147 .channels_min = 2, 151 .channels_min = 2,
148 .channels_max = 2, 152 .channels_max = 6,
149 .rates = SNDRV_PCM_RATE_48000, 153 .rates = SNDRV_PCM_RATE_48000,
150 .formats = SNDRV_PCM_FMTBIT_S16_LE, }, 154 .formats = SNDRV_PCM_FMTBIT_S16_LE, },
151 .capture = { 155 .capture = {
@@ -192,6 +196,7 @@ static int ad1980_soc_probe(struct platform_device *pdev)
192 struct snd_soc_codec *codec; 196 struct snd_soc_codec *codec;
193 int ret = 0; 197 int ret = 0;
194 u16 vendor_id2; 198 u16 vendor_id2;
199 u16 ext_status;
195 200
196 printk(KERN_INFO "AD1980 SoC Audio Codec\n"); 201 printk(KERN_INFO "AD1980 SoC Audio Codec\n");
197 202
@@ -234,7 +239,7 @@ static int ad1980_soc_probe(struct platform_device *pdev)
234 239
235 ret = ad1980_reset(codec, 0); 240 ret = ad1980_reset(codec, 0);
236 if (ret < 0) { 241 if (ret < 0) {
237 printk(KERN_ERR "AC97 link error\n"); 242 printk(KERN_ERR "Failed to reset AD1980: AC97 link error\n");
238 goto reset_err; 243 goto reset_err;
239 } 244 }
240 245
@@ -253,12 +258,19 @@ static int ad1980_soc_probe(struct platform_device *pdev)
253 "supported\n"); 258 "supported\n");
254 } 259 }
255 260
256 ac97_write(codec, AC97_MASTER, 0x0000); /* unmute line out volume */ 261 /* unmute captures and playbacks volume */
257 ac97_write(codec, AC97_PCM, 0x0000); /* unmute PCM out volume */ 262 ac97_write(codec, AC97_MASTER, 0x0000);
258 ac97_write(codec, AC97_REC_GAIN, 0x0000);/* unmute record volume */ 263 ac97_write(codec, AC97_PCM, 0x0000);
264 ac97_write(codec, AC97_REC_GAIN, 0x0000);
265 ac97_write(codec, AC97_CENTER_LFE_MASTER, 0x0000);
266 ac97_write(codec, AC97_SURROUND_MASTER, 0x0000);
267
268 /*power on LFE/CENTER/Surround DACs*/
269 ext_status = ac97_read(codec, AC97_EXTENDED_STATUS);
270 ac97_write(codec, AC97_EXTENDED_STATUS, ext_status&~0x3800);
259 271
260 ad1980_add_controls(codec); 272 ad1980_add_controls(codec);
261 ret = snd_soc_register_card(socdev); 273 ret = snd_soc_init_card(socdev);
262 if (ret < 0) { 274 if (ret < 0) {
263 printk(KERN_ERR "ad1980: failed to register card\n"); 275 printk(KERN_ERR "ad1980: failed to register card\n");
264 goto reset_err; 276 goto reset_err;
diff --git a/sound/soc/codecs/ad73311.c b/sound/soc/codecs/ad73311.c
index 37af8607b00a..b09289a1e55a 100644
--- a/sound/soc/codecs/ad73311.c
+++ b/sound/soc/codecs/ad73311.c
@@ -8,14 +8,10 @@
8 * under the terms of the GNU General Public License as published by the 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 9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. 10 * option) any later version.
11 *
12 * Revision history
13 * 25th Sep 2008 Initial version.
14 */ 11 */
15 12
16#include <linux/init.h> 13#include <linux/init.h>
17#include <linux/module.h> 14#include <linux/module.h>
18#include <linux/version.h>
19#include <linux/kernel.h> 15#include <linux/kernel.h>
20#include <linux/device.h> 16#include <linux/device.h>
21#include <sound/core.h> 17#include <sound/core.h>
@@ -68,7 +64,7 @@ static int ad73311_soc_probe(struct platform_device *pdev)
68 goto pcm_err; 64 goto pcm_err;
69 } 65 }
70 66
71 ret = snd_soc_register_card(socdev); 67 ret = snd_soc_init_card(socdev);
72 if (ret < 0) { 68 if (ret < 0) {
73 printk(KERN_ERR "ad73311: failed to register card\n"); 69 printk(KERN_ERR "ad73311: failed to register card\n");
74 goto register_err; 70 goto register_err;
@@ -102,6 +98,18 @@ struct snd_soc_codec_device soc_codec_dev_ad73311 = {
102}; 98};
103EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311); 99EXPORT_SYMBOL_GPL(soc_codec_dev_ad73311);
104 100
101static int __init ad73311_init(void)
102{
103 return snd_soc_register_dai(&ad73311_dai);
104}
105module_init(ad73311_init);
106
107static void __exit ad73311_exit(void)
108{
109 snd_soc_unregister_dai(&ad73311_dai);
110}
111module_exit(ad73311_exit);
112
105MODULE_DESCRIPTION("ASoC ad73311 driver"); 113MODULE_DESCRIPTION("ASoC ad73311 driver");
106MODULE_AUTHOR("Cliff Cai "); 114MODULE_AUTHOR("Cliff Cai ");
107MODULE_LICENSE("GPL"); 115MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index 2a89b5888e11..81300d8d42ca 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -339,7 +339,8 @@ static int ak4535_set_dai_sysclk(struct snd_soc_dai *codec_dai,
339} 339}
340 340
341static int ak4535_hw_params(struct snd_pcm_substream *substream, 341static int ak4535_hw_params(struct snd_pcm_substream *substream,
342 struct snd_pcm_hw_params *params) 342 struct snd_pcm_hw_params *params,
343 struct snd_soc_dai *dai)
343{ 344{
344 struct snd_soc_pcm_runtime *rtd = substream->private_data; 345 struct snd_soc_pcm_runtime *rtd = substream->private_data;
345 struct snd_soc_device *socdev = rtd->socdev; 346 struct snd_soc_device *socdev = rtd->socdev;
@@ -451,8 +452,6 @@ struct snd_soc_dai ak4535_dai = {
451 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 452 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
452 .ops = { 453 .ops = {
453 .hw_params = ak4535_hw_params, 454 .hw_params = ak4535_hw_params,
454 },
455 .dai_ops = {
456 .set_fmt = ak4535_set_dai_fmt, 455 .set_fmt = ak4535_set_dai_fmt,
457 .digital_mute = ak4535_mute, 456 .digital_mute = ak4535_mute,
458 .set_sysclk = ak4535_set_dai_sysclk, 457 .set_sysclk = ak4535_set_dai_sysclk,
@@ -513,7 +512,7 @@ static int ak4535_init(struct snd_soc_device *socdev)
513 512
514 ak4535_add_controls(codec); 513 ak4535_add_controls(codec);
515 ak4535_add_widgets(codec); 514 ak4535_add_widgets(codec);
516 ret = snd_soc_register_card(socdev); 515 ret = snd_soc_init_card(socdev);
517 if (ret < 0) { 516 if (ret < 0) {
518 printk(KERN_ERR "ak4535: failed to register card\n"); 517 printk(KERN_ERR "ak4535: failed to register card\n");
519 goto card_err; 518 goto card_err;
@@ -689,6 +688,18 @@ struct snd_soc_codec_device soc_codec_dev_ak4535 = {
689}; 688};
690EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535); 689EXPORT_SYMBOL_GPL(soc_codec_dev_ak4535);
691 690
691static int __init ak4535_modinit(void)
692{
693 return snd_soc_register_dai(&ak4535_dai);
694}
695module_init(ak4535_modinit);
696
697static void __exit ak4535_exit(void)
698{
699 snd_soc_unregister_dai(&ak4535_dai);
700}
701module_exit(ak4535_exit);
702
692MODULE_DESCRIPTION("Soc AK4535 driver"); 703MODULE_DESCRIPTION("Soc AK4535 driver");
693MODULE_AUTHOR("Richard Purdie"); 704MODULE_AUTHOR("Richard Purdie");
694MODULE_LICENSE("GPL"); 705MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 0bbd94501d7e..f1aa0c34421c 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -360,13 +360,14 @@ static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
360/* 360/*
361 * Program the CS4270 with the given hardware parameters. 361 * Program the CS4270 with the given hardware parameters.
362 * 362 *
363 * The .dai_ops functions are used to provide board-specific data, like 363 * The .ops functions are used to provide board-specific data, like
364 * input frequencies, to this driver. This function takes that information, 364 * input frequencies, to this driver. This function takes that information,
365 * combines it with the hardware parameters provided, and programs the 365 * combines it with the hardware parameters provided, and programs the
366 * hardware accordingly. 366 * hardware accordingly.
367 */ 367 */
368static int cs4270_hw_params(struct snd_pcm_substream *substream, 368static int cs4270_hw_params(struct snd_pcm_substream *substream,
369 struct snd_pcm_hw_params *params) 369 struct snd_pcm_hw_params *params,
370 struct snd_soc_dai *dai)
370{ 371{
371 struct snd_soc_pcm_runtime *rtd = substream->private_data; 372 struct snd_soc_pcm_runtime *rtd = substream->private_data;
372 struct snd_soc_device *socdev = rtd->socdev; 373 struct snd_soc_device *socdev = rtd->socdev;
@@ -450,6 +451,19 @@ static int cs4270_hw_params(struct snd_pcm_substream *substream,
450 return ret; 451 return ret;
451 } 452 }
452 453
454 /* Disable automatic volume control. It's enabled by default, and
455 * it causes volume change commands to be delayed, sometimes until
456 * after playback has started.
457 */
458
459 reg = cs4270_read_reg_cache(codec, CS4270_TRANS);
460 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
461 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
462 if (ret < 0) {
463 printk(KERN_ERR "I2C write failed\n");
464 return ret;
465 }
466
453 /* Thaw and power-up the codec */ 467 /* Thaw and power-up the codec */
454 468
455 ret = snd_soc_write(codec, CS4270_PWRCTL, 0); 469 ret = snd_soc_write(codec, CS4270_PWRCTL, 0);
@@ -697,10 +711,10 @@ static int cs4270_probe(struct platform_device *pdev)
697 if (codec->control_data) { 711 if (codec->control_data) {
698 /* Initialize codec ops */ 712 /* Initialize codec ops */
699 cs4270_dai.ops.hw_params = cs4270_hw_params; 713 cs4270_dai.ops.hw_params = cs4270_hw_params;
700 cs4270_dai.dai_ops.set_sysclk = cs4270_set_dai_sysclk; 714 cs4270_dai.ops.set_sysclk = cs4270_set_dai_sysclk;
701 cs4270_dai.dai_ops.set_fmt = cs4270_set_dai_fmt; 715 cs4270_dai.ops.set_fmt = cs4270_set_dai_fmt;
702#ifdef CONFIG_SND_SOC_CS4270_HWMUTE 716#ifdef CONFIG_SND_SOC_CS4270_HWMUTE
703 cs4270_dai.dai_ops.digital_mute = cs4270_mute; 717 cs4270_dai.ops.digital_mute = cs4270_mute;
704#endif 718#endif
705 } else 719 } else
706 printk(KERN_INFO "cs4270: no I2C device found, " 720 printk(KERN_INFO "cs4270: no I2C device found, "
@@ -709,7 +723,7 @@ static int cs4270_probe(struct platform_device *pdev)
709 printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n"); 723 printk(KERN_INFO "cs4270: I2C disabled, using stand-alone mode\n");
710#endif 724#endif
711 725
712 ret = snd_soc_register_card(socdev); 726 ret = snd_soc_init_card(socdev);
713 if (ret < 0) { 727 if (ret < 0) {
714 printk(KERN_ERR "cs4270: failed to register card\n"); 728 printk(KERN_ERR "cs4270: failed to register card\n");
715 goto error_del_driver; 729 goto error_del_driver;
@@ -760,6 +774,18 @@ struct snd_soc_codec_device soc_codec_device_cs4270 = {
760}; 774};
761EXPORT_SYMBOL_GPL(soc_codec_device_cs4270); 775EXPORT_SYMBOL_GPL(soc_codec_device_cs4270);
762 776
777static int __init cs4270_init(void)
778{
779 return snd_soc_register_dai(&cs4270_dai);
780}
781module_init(cs4270_init);
782
783static void __exit cs4270_exit(void)
784{
785 snd_soc_unregister_dai(&cs4270_dai);
786}
787module_exit(cs4270_exit);
788
763MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 789MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
764MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver"); 790MODULE_DESCRIPTION("Cirrus Logic CS4270 ALSA SoC Codec Driver");
765MODULE_LICENSE("GPL"); 791MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/l3.c b/sound/soc/codecs/l3.c
new file mode 100644
index 000000000000..5353af58862c
--- /dev/null
+++ b/sound/soc/codecs/l3.c
@@ -0,0 +1,91 @@
1/*
2 * L3 code
3 *
4 * Copyright (C) 2008, Christian Pellegrin <chripell@evolware.org>
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 *
11 * based on:
12 *
13 * L3 bus algorithm module.
14 *
15 * Copyright (C) 2001 Russell King, All Rights Reserved.
16 *
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/kernel.h>
22#include <linux/delay.h>
23
24#include <sound/l3.h>
25
26/*
27 * Send one byte of data to the chip. Data is latched into the chip on
28 * the rising edge of the clock.
29 */
30static void sendbyte(struct l3_pins *adap, unsigned int byte)
31{
32 int i;
33
34 for (i = 0; i < 8; i++) {
35 adap->setclk(0);
36 udelay(adap->data_hold);
37 adap->setdat(byte & 1);
38 udelay(adap->data_setup);
39 adap->setclk(1);
40 udelay(adap->clock_high);
41 byte >>= 1;
42 }
43}
44
45/*
46 * Send a set of bytes to the chip. We need to pulse the MODE line
47 * between each byte, but never at the start nor at the end of the
48 * transfer.
49 */
50static void sendbytes(struct l3_pins *adap, const u8 *buf,
51 int len)
52{
53 int i;
54
55 for (i = 0; i < len; i++) {
56 if (i) {
57 udelay(adap->mode_hold);
58 adap->setmode(0);
59 udelay(adap->mode);
60 }
61 adap->setmode(1);
62 udelay(adap->mode_setup);
63 sendbyte(adap, buf[i]);
64 }
65}
66
67int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len)
68{
69 adap->setclk(1);
70 adap->setdat(1);
71 adap->setmode(1);
72 udelay(adap->mode);
73
74 adap->setmode(0);
75 udelay(adap->mode_setup);
76 sendbyte(adap, addr);
77 udelay(adap->mode_hold);
78
79 sendbytes(adap, data, len);
80
81 adap->setclk(1);
82 adap->setdat(1);
83 adap->setmode(0);
84
85 return len;
86}
87EXPORT_SYMBOL_GPL(l3_write);
88
89MODULE_DESCRIPTION("L3 bit-banging driver");
90MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>");
91MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm3008.c b/sound/soc/codecs/pcm3008.c
new file mode 100644
index 000000000000..9a3e67e5319c
--- /dev/null
+++ b/sound/soc/codecs/pcm3008.c
@@ -0,0 +1,212 @@
1/*
2 * ALSA Soc PCM3008 codec support
3 *
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
6 *
7 * Based on AC97 Soc codec, original copyright follow:
8 * Copyright 2005 Wolfson Microelectronics PLC.
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 * Generic PCM3008 support.
16 */
17
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/device.h>
21#include <linux/gpio.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/initval.h>
25#include <sound/soc.h>
26
27#include "pcm3008.h"
28
29#define PCM3008_VERSION "0.2"
30
31#define PCM3008_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
32 SNDRV_PCM_RATE_48000)
33
34struct snd_soc_dai pcm3008_dai = {
35 .name = "PCM3008 HiFi",
36 .playback = {
37 .stream_name = "PCM3008 Playback",
38 .channels_min = 1,
39 .channels_max = 2,
40 .rates = PCM3008_RATES,
41 .formats = SNDRV_PCM_FMTBIT_S16_LE,
42 },
43 .capture = {
44 .stream_name = "PCM3008 Capture",
45 .channels_min = 1,
46 .channels_max = 2,
47 .rates = PCM3008_RATES,
48 .formats = SNDRV_PCM_FMTBIT_S16_LE,
49 },
50};
51EXPORT_SYMBOL_GPL(pcm3008_dai);
52
53static void pcm3008_gpio_free(struct pcm3008_setup_data *setup)
54{
55 gpio_free(setup->dem0_pin);
56 gpio_free(setup->dem1_pin);
57 gpio_free(setup->pdad_pin);
58 gpio_free(setup->pdda_pin);
59}
60
61static int pcm3008_soc_probe(struct platform_device *pdev)
62{
63 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
64 struct snd_soc_codec *codec;
65 struct pcm3008_setup_data *setup = socdev->codec_data;
66 int ret = 0;
67
68 printk(KERN_INFO "PCM3008 SoC Audio Codec %s\n", PCM3008_VERSION);
69
70 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
71 if (!socdev->codec)
72 return -ENOMEM;
73
74 codec = socdev->codec;
75 mutex_init(&codec->mutex);
76
77 codec->name = "PCM3008";
78 codec->owner = THIS_MODULE;
79 codec->dai = &pcm3008_dai;
80 codec->num_dai = 1;
81 codec->write = NULL;
82 codec->read = NULL;
83 INIT_LIST_HEAD(&codec->dapm_widgets);
84 INIT_LIST_HEAD(&codec->dapm_paths);
85
86 /* Register PCMs. */
87 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
88 if (ret < 0) {
89 printk(KERN_ERR "pcm3008: failed to create pcms\n");
90 goto pcm_err;
91 }
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
101 * Low Low De-emphasis 44.1 kHz ON
102 * Low High De-emphasis OFF
103 * High Low De-emphasis 48 kHz ON
104 * High High De-emphasis 32 kHz ON
105 */
106
107 /* Configure DEM0 GPIO (turning OFF DAC De-emphasis). */
108 ret = gpio_request(setup->dem0_pin, "codec_dem0");
109 if (ret == 0)
110 ret = gpio_direction_output(setup->dem0_pin, 1);
111 if (ret != 0)
112 goto gpio_err;
113
114 /* Configure DEM1 GPIO (turning OFF DAC De-emphasis). */
115 ret = gpio_request(setup->dem1_pin, "codec_dem1");
116 if (ret == 0)
117 ret = gpio_direction_output(setup->dem1_pin, 0);
118 if (ret != 0)
119 goto gpio_err;
120
121 /* Configure PDAD GPIO. */
122 ret = gpio_request(setup->pdad_pin, "codec_pdad");
123 if (ret == 0)
124 ret = gpio_direction_output(setup->pdad_pin, 1);
125 if (ret != 0)
126 goto gpio_err;
127
128 /* Configure PDDA GPIO. */
129 ret = gpio_request(setup->pdda_pin, "codec_pdda");
130 if (ret == 0)
131 ret = gpio_direction_output(setup->pdda_pin, 1);
132 if (ret != 0)
133 goto gpio_err;
134
135 return ret;
136
137gpio_err:
138 pcm3008_gpio_free(setup);
139card_err:
140 snd_soc_free_pcms(socdev);
141pcm_err:
142 kfree(socdev->codec);
143
144 return ret;
145}
146
147static int pcm3008_soc_remove(struct platform_device *pdev)
148{
149 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
150 struct snd_soc_codec *codec = socdev->codec;
151 struct pcm3008_setup_data *setup = socdev->codec_data;
152
153 if (!codec)
154 return 0;
155
156 pcm3008_gpio_free(setup);
157 snd_soc_free_pcms(socdev);
158 kfree(socdev->codec);
159
160 return 0;
161}
162
163#ifdef CONFIG_PM
164static int pcm3008_soc_suspend(struct platform_device *pdev, pm_message_t msg)
165{
166 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
167 struct pcm3008_setup_data *setup = socdev->codec_data;
168
169 gpio_set_value(setup->pdad_pin, 0);
170 gpio_set_value(setup->pdda_pin, 0);
171
172 return 0;
173}
174
175static int pcm3008_soc_resume(struct platform_device *pdev)
176{
177 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
178 struct pcm3008_setup_data *setup = socdev->codec_data;
179
180 gpio_set_value(setup->pdad_pin, 1);
181 gpio_set_value(setup->pdda_pin, 1);
182
183 return 0;
184}
185#else
186#define pcm3008_soc_suspend NULL
187#define pcm3008_soc_resume NULL
188#endif
189
190struct snd_soc_codec_device soc_codec_dev_pcm3008 = {
191 .probe = pcm3008_soc_probe,
192 .remove = pcm3008_soc_remove,
193 .suspend = pcm3008_soc_suspend,
194 .resume = pcm3008_soc_resume,
195};
196EXPORT_SYMBOL_GPL(soc_codec_dev_pcm3008);
197
198static int __init pcm3008_init(void)
199{
200 return snd_soc_register_dai(&pcm3008_dai);
201}
202module_init(pcm3008_init);
203
204static void __exit pcm3008_exit(void)
205{
206 snd_soc_unregister_dai(&pcm3008_dai);
207}
208module_exit(pcm3008_exit);
209
210MODULE_DESCRIPTION("Soc PCM3008 driver");
211MODULE_AUTHOR("Hugo Villeneuve");
212MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/pcm3008.h b/sound/soc/codecs/pcm3008.h
new file mode 100644
index 000000000000..d04e87d3c060
--- /dev/null
+++ b/sound/soc/codecs/pcm3008.h
@@ -0,0 +1,25 @@
1/*
2 * PCM3008 ALSA SoC Layer
3 *
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
6 *
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
9 * published by the Free Software Foundation.
10 */
11
12#ifndef __LINUX_SND_SOC_PCM3008_H
13#define __LINUX_SND_SOC_PCM3008_H
14
15struct pcm3008_setup_data {
16 unsigned dem0_pin;
17 unsigned dem1_pin;
18 unsigned pdad_pin;
19 unsigned pdda_pin;
20};
21
22extern struct snd_soc_codec_device soc_codec_dev_pcm3008;
23extern struct snd_soc_dai pcm3008_dai;
24
25#endif
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 44ef0dacd564..cac373616768 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -285,16 +285,23 @@ static inline int get_coeff(int mclk, int rate)
285} 285}
286 286
287static int ssm2602_hw_params(struct snd_pcm_substream *substream, 287static int ssm2602_hw_params(struct snd_pcm_substream *substream,
288 struct snd_pcm_hw_params *params) 288 struct snd_pcm_hw_params *params,
289 struct snd_soc_dai *dai)
289{ 290{
290 u16 srate; 291 u16 srate;
291 struct snd_soc_pcm_runtime *rtd = substream->private_data; 292 struct snd_soc_pcm_runtime *rtd = substream->private_data;
292 struct snd_soc_device *socdev = rtd->socdev; 293 struct snd_soc_device *socdev = rtd->socdev;
293 struct snd_soc_codec *codec = socdev->codec; 294 struct snd_soc_codec *codec = socdev->codec;
294 struct ssm2602_priv *ssm2602 = codec->private_data; 295 struct ssm2602_priv *ssm2602 = codec->private_data;
296 struct i2c_client *i2c = codec->control_data;
295 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3; 297 u16 iface = ssm2602_read_reg_cache(codec, SSM2602_IFACE) & 0xfff3;
296 int i = get_coeff(ssm2602->sysclk, params_rate(params)); 298 int i = get_coeff(ssm2602->sysclk, params_rate(params));
297 299
300 if (substream == ssm2602->slave_substream) {
301 dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n");
302 return 0;
303 }
304
298 /*no match is found*/ 305 /*no match is found*/
299 if (i == ARRAY_SIZE(coeff_div)) 306 if (i == ARRAY_SIZE(coeff_div))
300 return -EINVAL; 307 return -EINVAL;
@@ -324,19 +331,26 @@ static int ssm2602_hw_params(struct snd_pcm_substream *substream,
324 return 0; 331 return 0;
325} 332}
326 333
327static int ssm2602_startup(struct snd_pcm_substream *substream) 334static int ssm2602_startup(struct snd_pcm_substream *substream,
335 struct snd_soc_dai *dai)
328{ 336{
329 struct snd_soc_pcm_runtime *rtd = substream->private_data; 337 struct snd_soc_pcm_runtime *rtd = substream->private_data;
330 struct snd_soc_device *socdev = rtd->socdev; 338 struct snd_soc_device *socdev = rtd->socdev;
331 struct snd_soc_codec *codec = socdev->codec; 339 struct snd_soc_codec *codec = socdev->codec;
332 struct ssm2602_priv *ssm2602 = codec->private_data; 340 struct ssm2602_priv *ssm2602 = codec->private_data;
341 struct i2c_client *i2c = codec->control_data;
333 struct snd_pcm_runtime *master_runtime; 342 struct snd_pcm_runtime *master_runtime;
334 343
335 /* The DAI has shared clocks so if we already have a playback or 344 /* The DAI has shared clocks so if we already have a playback or
336 * capture going then constrain this substream to match it. 345 * capture going then constrain this substream to match it.
346 * TODO: the ssm2602 allows pairs of non-matching PB/REC rates
337 */ 347 */
338 if (ssm2602->master_substream) { 348 if (ssm2602->master_substream) {
339 master_runtime = ssm2602->master_substream->runtime; 349 master_runtime = ssm2602->master_substream->runtime;
350 dev_dbg(&i2c->dev, "Constraining to %d bits at %dHz\n",
351 master_runtime->sample_bits,
352 master_runtime->rate);
353
340 snd_pcm_hw_constraint_minmax(substream->runtime, 354 snd_pcm_hw_constraint_minmax(substream->runtime,
341 SNDRV_PCM_HW_PARAM_RATE, 355 SNDRV_PCM_HW_PARAM_RATE,
342 master_runtime->rate, 356 master_runtime->rate,
@@ -354,7 +368,8 @@ static int ssm2602_startup(struct snd_pcm_substream *substream)
354 return 0; 368 return 0;
355} 369}
356 370
357static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream) 371static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream,
372 struct snd_soc_dai *dai)
358{ 373{
359 struct snd_soc_pcm_runtime *rtd = substream->private_data; 374 struct snd_soc_pcm_runtime *rtd = substream->private_data;
360 struct snd_soc_device *socdev = rtd->socdev; 375 struct snd_soc_device *socdev = rtd->socdev;
@@ -365,14 +380,21 @@ static int ssm2602_pcm_prepare(struct snd_pcm_substream *substream)
365 return 0; 380 return 0;
366} 381}
367 382
368static void ssm2602_shutdown(struct snd_pcm_substream *substream) 383static void ssm2602_shutdown(struct snd_pcm_substream *substream,
384 struct snd_soc_dai *dai)
369{ 385{
370 struct snd_soc_pcm_runtime *rtd = substream->private_data; 386 struct snd_soc_pcm_runtime *rtd = substream->private_data;
371 struct snd_soc_device *socdev = rtd->socdev; 387 struct snd_soc_device *socdev = rtd->socdev;
372 struct snd_soc_codec *codec = socdev->codec; 388 struct snd_soc_codec *codec = socdev->codec;
389 struct ssm2602_priv *ssm2602 = codec->private_data;
373 /* deactivate */ 390 /* deactivate */
374 if (!codec->active) 391 if (!codec->active)
375 ssm2602_write(codec, SSM2602_ACTIVE, 0); 392 ssm2602_write(codec, SSM2602_ACTIVE, 0);
393
394 if (ssm2602->master_substream == substream)
395 ssm2602->master_substream = ssm2602->slave_substream;
396
397 ssm2602->slave_substream = NULL;
376} 398}
377 399
378static int ssm2602_mute(struct snd_soc_dai *dai, int mute) 400static int ssm2602_mute(struct snd_soc_dai *dai, int mute)
@@ -432,10 +454,10 @@ static int ssm2602_set_dai_fmt(struct snd_soc_dai *codec_dai,
432 iface |= 0x0001; 454 iface |= 0x0001;
433 break; 455 break;
434 case SND_SOC_DAIFMT_DSP_A: 456 case SND_SOC_DAIFMT_DSP_A:
435 iface |= 0x0003; 457 iface |= 0x0013;
436 break; 458 break;
437 case SND_SOC_DAIFMT_DSP_B: 459 case SND_SOC_DAIFMT_DSP_B:
438 iface |= 0x0013; 460 iface |= 0x0003;
439 break; 461 break;
440 default: 462 default:
441 return -EINVAL; 463 return -EINVAL;
@@ -496,6 +518,9 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
496 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\ 518 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
497 SNDRV_PCM_RATE_96000) 519 SNDRV_PCM_RATE_96000)
498 520
521#define SSM2602_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
522 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
523
499struct snd_soc_dai ssm2602_dai = { 524struct snd_soc_dai ssm2602_dai = {
500 .name = "SSM2602", 525 .name = "SSM2602",
501 .playback = { 526 .playback = {
@@ -503,20 +528,18 @@ struct snd_soc_dai ssm2602_dai = {
503 .channels_min = 2, 528 .channels_min = 2,
504 .channels_max = 2, 529 .channels_max = 2,
505 .rates = SSM2602_RATES, 530 .rates = SSM2602_RATES,
506 .formats = SNDRV_PCM_FMTBIT_S32_LE,}, 531 .formats = SSM2602_FORMATS,},
507 .capture = { 532 .capture = {
508 .stream_name = "Capture", 533 .stream_name = "Capture",
509 .channels_min = 2, 534 .channels_min = 2,
510 .channels_max = 2, 535 .channels_max = 2,
511 .rates = SSM2602_RATES, 536 .rates = SSM2602_RATES,
512 .formats = SNDRV_PCM_FMTBIT_S32_LE,}, 537 .formats = SSM2602_FORMATS,},
513 .ops = { 538 .ops = {
514 .startup = ssm2602_startup, 539 .startup = ssm2602_startup,
515 .prepare = ssm2602_pcm_prepare, 540 .prepare = ssm2602_pcm_prepare,
516 .hw_params = ssm2602_hw_params, 541 .hw_params = ssm2602_hw_params,
517 .shutdown = ssm2602_shutdown, 542 .shutdown = ssm2602_shutdown,
518 },
519 .dai_ops = {
520 .digital_mute = ssm2602_mute, 543 .digital_mute = ssm2602_mute,
521 .set_sysclk = ssm2602_set_dai_sysclk, 544 .set_sysclk = ssm2602_set_dai_sysclk,
522 .set_fmt = ssm2602_set_dai_fmt, 545 .set_fmt = ssm2602_set_dai_fmt,
@@ -601,7 +624,7 @@ static int ssm2602_init(struct snd_soc_device *socdev)
601 624
602 ssm2602_add_controls(codec); 625 ssm2602_add_controls(codec);
603 ssm2602_add_widgets(codec); 626 ssm2602_add_widgets(codec);
604 ret = snd_soc_register_card(socdev); 627 ret = snd_soc_init_card(socdev);
605 if (ret < 0) { 628 if (ret < 0) {
606 pr_err("ssm2602: failed to register card\n"); 629 pr_err("ssm2602: failed to register card\n");
607 goto card_err; 630 goto card_err;
@@ -770,6 +793,18 @@ struct snd_soc_codec_device soc_codec_dev_ssm2602 = {
770}; 793};
771EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602); 794EXPORT_SYMBOL_GPL(soc_codec_dev_ssm2602);
772 795
796static int __init ssm2602_modinit(void)
797{
798 return snd_soc_register_dai(&ssm2602_dai);
799}
800module_init(ssm2602_modinit);
801
802static void __exit ssm2602_exit(void)
803{
804 snd_soc_unregister_dai(&ssm2602_dai);
805}
806module_exit(ssm2602_exit);
807
773MODULE_DESCRIPTION("ASoC ssm2602 driver"); 808MODULE_DESCRIPTION("ASoC ssm2602 driver");
774MODULE_AUTHOR("Cliff Cai"); 809MODULE_AUTHOR("Cliff Cai");
775MODULE_LICENSE("GPL"); 810MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index 44308dac9e18..cfdea007c4cb 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -37,12 +37,6 @@
37 37
38#define AIC23_VERSION "0.1" 38#define AIC23_VERSION "0.1"
39 39
40struct tlv320aic23_srate_reg_info {
41 u32 sample_rate;
42 u8 control; /* SR3, SR2, SR1, SR0 and BOSR */
43 u8 divider; /* if 0 CLKIN = MCLK, if 1 CLKIN = MCLK/2 */
44};
45
46/* 40/*
47 * AIC23 register cache 41 * AIC23 register cache
48 */ 42 */
@@ -261,20 +255,156 @@ static const struct snd_soc_dapm_route intercon[] = {
261 255
262}; 256};
263 257
264/* tlv320aic23 related */ 258/* AIC23 driver data */
265static const struct tlv320aic23_srate_reg_info srate_reg_info[] = { 259struct aic23 {
266 {4000, 0x06, 1}, /* 4000 */ 260 struct snd_soc_codec codec;
267 {8000, 0x06, 0}, /* 8000 */ 261 int mclk;
268 {16000, 0x0C, 1}, /* 16000 */ 262 int requested_adc;
269 {22050, 0x11, 1}, /* 22050 */ 263 int requested_dac;
270 {24000, 0x00, 1}, /* 24000 */ 264};
271 {32000, 0x0C, 0}, /* 32000 */ 265
272 {44100, 0x11, 0}, /* 44100 */ 266/*
273 {48000, 0x00, 0}, /* 48000 */ 267 * Common Crystals used
274 {88200, 0x1F, 0}, /* 88200 */ 268 * 11.2896 Mhz /128 = *88.2k /192 = 58.8k
275 {96000, 0x0E, 0}, /* 96000 */ 269 * 12.0000 Mhz /125 = *96k /136 = 88.235K
270 * 12.2880 Mhz /128 = *96k /192 = 64k
271 * 16.9344 Mhz /128 = 132.3k /192 = *88.2k
272 * 18.4320 Mhz /128 = 144k /192 = *96k
273 */
274
275/*
276 * Normal BOSR 0-256/2 = 128, 1-384/2 = 192
277 * USB BOSR 0-250/2 = 125, 1-272/2 = 136
278 */
279static const int bosr_usb_divisor_table[] = {
280 128, 125, 192, 136
281};
282#define LOWER_GROUP ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<6) | (1<<7))
283#define UPPER_GROUP ((1<<8) | (1<<9) | (1<<10) | (1<<11) | (1<<15))
284static const unsigned short sr_valid_mask[] = {
285 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 0*/
286 LOWER_GROUP|UPPER_GROUP, /* Normal, bosr - 1*/
287 LOWER_GROUP, /* Usb, bosr - 0*/
288 UPPER_GROUP, /* Usb, bosr - 1*/
289};
290/*
291 * Every divisor is a factor of 11*12
292 */
293#define SR_MULT (11*12)
294#define A(x) (x) ? (SR_MULT/x) : 0
295static const unsigned char sr_adc_mult_table[] = {
296 A(2), A(2), A(12), A(12), A(0), A(0), A(3), A(1),
297 A(2), A(2), A(11), A(11), A(0), A(0), A(0), A(1)
298};
299static const unsigned char sr_dac_mult_table[] = {
300 A(2), A(12), A(2), A(12), A(0), A(0), A(3), A(1),
301 A(2), A(11), A(2), A(11), A(0), A(0), A(0), A(1)
276}; 302};
277 303
304static unsigned get_score(int adc, int adc_l, int adc_h, int need_adc,
305 int dac, int dac_l, int dac_h, int need_dac)
306{
307 if ((adc >= adc_l) && (adc <= adc_h) &&
308 (dac >= dac_l) && (dac <= dac_h)) {
309 int diff_adc = need_adc - adc;
310 int diff_dac = need_dac - dac;
311 return abs(diff_adc) + abs(diff_dac);
312 }
313 return UINT_MAX;
314}
315
316static int find_rate(int mclk, u32 need_adc, u32 need_dac)
317{
318 int i, j;
319 int best_i = -1;
320 int best_j = -1;
321 int best_div = 0;
322 unsigned best_score = UINT_MAX;
323 int adc_l, adc_h, dac_l, dac_h;
324
325 need_adc *= SR_MULT;
326 need_dac *= SR_MULT;
327 /*
328 * rates given are +/- 1/32
329 */
330 adc_l = need_adc - (need_adc >> 5);
331 adc_h = need_adc + (need_adc >> 5);
332 dac_l = need_dac - (need_dac >> 5);
333 dac_h = need_dac + (need_dac >> 5);
334 for (i = 0; i < ARRAY_SIZE(bosr_usb_divisor_table); i++) {
335 int base = mclk / bosr_usb_divisor_table[i];
336 int mask = sr_valid_mask[i];
337 for (j = 0; j < ARRAY_SIZE(sr_adc_mult_table);
338 j++, mask >>= 1) {
339 int adc;
340 int dac;
341 int score;
342 if ((mask & 1) == 0)
343 continue;
344 adc = base * sr_adc_mult_table[j];
345 dac = base * sr_dac_mult_table[j];
346 score = get_score(adc, adc_l, adc_h, need_adc,
347 dac, dac_l, dac_h, need_dac);
348 if (best_score > score) {
349 best_score = score;
350 best_i = i;
351 best_j = j;
352 best_div = 0;
353 }
354 score = get_score((adc >> 1), adc_l, adc_h, need_adc,
355 (dac >> 1), dac_l, dac_h, need_dac);
356 /* prefer to have a /2 */
357 if ((score != UINT_MAX) && (best_score >= score)) {
358 best_score = score;
359 best_i = i;
360 best_j = j;
361 best_div = 1;
362 }
363 }
364 }
365 return (best_j << 2) | best_i | (best_div << TLV320AIC23_CLKIN_SHIFT);
366}
367
368#ifdef DEBUG
369static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
370 u32 *sample_rate_adc, u32 *sample_rate_dac)
371{
372 int src = tlv320aic23_read_reg_cache(codec, TLV320AIC23_SRATE);
373 int sr = (src >> 2) & 0x0f;
374 int val = (mclk / bosr_usb_divisor_table[src & 3]);
375 int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
376 int dac = (val * sr_dac_mult_table[sr]) / SR_MULT;
377 if (src & TLV320AIC23_CLKIN_HALF) {
378 adc >>= 1;
379 dac >>= 1;
380 }
381 *sample_rate_adc = adc;
382 *sample_rate_dac = dac;
383}
384#endif
385
386static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
387 u32 sample_rate_adc, u32 sample_rate_dac)
388{
389 /* Search for the right sample rate */
390 int data = find_rate(mclk, sample_rate_adc, sample_rate_dac);
391 if (data < 0) {
392 printk(KERN_ERR "%s:Invalid rate %u,%u requested\n",
393 __func__, sample_rate_adc, sample_rate_dac);
394 return -EINVAL;
395 }
396 tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
397#ifdef DEBUG
398 {
399 u32 adc, dac;
400 get_current_sample_rates(codec, mclk, &adc, &dac);
401 printk(KERN_DEBUG "actual samplerate = %u,%u reg=%x\n",
402 adc, dac, data);
403 }
404#endif
405 return 0;
406}
407
278static int tlv320aic23_add_widgets(struct snd_soc_codec *codec) 408static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
279{ 409{
280 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 410 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets,
@@ -288,32 +418,36 @@ static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
288} 418}
289 419
290static int tlv320aic23_hw_params(struct snd_pcm_substream *substream, 420static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
291 struct snd_pcm_hw_params *params) 421 struct snd_pcm_hw_params *params,
422 struct snd_soc_dai *dai)
292{ 423{
293 struct snd_soc_pcm_runtime *rtd = substream->private_data; 424 struct snd_soc_pcm_runtime *rtd = substream->private_data;
294 struct snd_soc_device *socdev = rtd->socdev; 425 struct snd_soc_device *socdev = rtd->socdev;
295 struct snd_soc_codec *codec = socdev->codec; 426 struct snd_soc_codec *codec = socdev->codec;
296 u16 iface_reg, data; 427 u16 iface_reg;
297 u8 count = 0; 428 int ret;
429 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
430 u32 sample_rate_adc = aic23->requested_adc;
431 u32 sample_rate_dac = aic23->requested_dac;
432 u32 sample_rate = params_rate(params);
433
434 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
435 aic23->requested_dac = sample_rate_dac = sample_rate;
436 if (!sample_rate_adc)
437 sample_rate_adc = sample_rate;
438 } else {
439 aic23->requested_adc = sample_rate_adc = sample_rate;
440 if (!sample_rate_dac)
441 sample_rate_dac = sample_rate;
442 }
443 ret = set_sample_rate_control(codec, aic23->mclk, sample_rate_adc,
444 sample_rate_dac);
445 if (ret < 0)
446 return ret;
298 447
299 iface_reg = 448 iface_reg =
300 tlv320aic23_read_reg_cache(codec, 449 tlv320aic23_read_reg_cache(codec,
301 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2); 450 TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
302
303 /* Search for the right sample rate */
304 /* Verify what happens if the rate is not supported
305 * now it goes to 96Khz */
306 while ((srate_reg_info[count].sample_rate != params_rate(params)) &&
307 (count < ARRAY_SIZE(srate_reg_info))) {
308 count++;
309 }
310
311 data = (srate_reg_info[count].divider << TLV320AIC23_CLKIN_SHIFT) |
312 (srate_reg_info[count]. control << TLV320AIC23_BOSR_SHIFT) |
313 TLV320AIC23_USB_CLK_ON;
314
315 tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
316
317 switch (params_format(params)) { 451 switch (params_format(params)) {
318 case SNDRV_PCM_FORMAT_S16_LE: 452 case SNDRV_PCM_FORMAT_S16_LE:
319 break; 453 break;
@@ -332,7 +466,8 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
332 return 0; 466 return 0;
333} 467}
334 468
335static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream) 469static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
470 struct snd_soc_dai *dai)
336{ 471{
337 struct snd_soc_pcm_runtime *rtd = substream->private_data; 472 struct snd_soc_pcm_runtime *rtd = substream->private_data;
338 struct snd_soc_device *socdev = rtd->socdev; 473 struct snd_soc_device *socdev = rtd->socdev;
@@ -344,17 +479,23 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream)
344 return 0; 479 return 0;
345} 480}
346 481
347static void tlv320aic23_shutdown(struct snd_pcm_substream *substream) 482static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
483 struct snd_soc_dai *dai)
348{ 484{
349 struct snd_soc_pcm_runtime *rtd = substream->private_data; 485 struct snd_soc_pcm_runtime *rtd = substream->private_data;
350 struct snd_soc_device *socdev = rtd->socdev; 486 struct snd_soc_device *socdev = rtd->socdev;
351 struct snd_soc_codec *codec = socdev->codec; 487 struct snd_soc_codec *codec = socdev->codec;
488 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
352 489
353 /* deactivate */ 490 /* deactivate */
354 if (!codec->active) { 491 if (!codec->active) {
355 udelay(50); 492 udelay(50);
356 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0); 493 tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
357 } 494 }
495 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
496 aic23->requested_dac = 0;
497 else
498 aic23->requested_adc = 0;
358} 499}
359 500
360static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute) 501static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
@@ -400,7 +541,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
400 case SND_SOC_DAIFMT_I2S: 541 case SND_SOC_DAIFMT_I2S:
401 iface_reg |= TLV320AIC23_FOR_I2S; 542 iface_reg |= TLV320AIC23_FOR_I2S;
402 break; 543 break;
403 case SND_SOC_DAIFMT_DSP_A: 544 case SND_SOC_DAIFMT_DSP_B:
404 iface_reg |= TLV320AIC23_FOR_DSP; 545 iface_reg |= TLV320AIC23_FOR_DSP;
405 break; 546 break;
406 case SND_SOC_DAIFMT_RIGHT_J: 547 case SND_SOC_DAIFMT_RIGHT_J:
@@ -422,12 +563,9 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
422 int clk_id, unsigned int freq, int dir) 563 int clk_id, unsigned int freq, int dir)
423{ 564{
424 struct snd_soc_codec *codec = codec_dai->codec; 565 struct snd_soc_codec *codec = codec_dai->codec;
425 566 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
426 switch (freq) { 567 aic23->mclk = freq;
427 case 12000000: 568 return 0;
428 return 0;
429 }
430 return -EINVAL;
431} 569}
432 570
433static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, 571static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
@@ -478,12 +616,10 @@ struct snd_soc_dai tlv320aic23_dai = {
478 .prepare = tlv320aic23_pcm_prepare, 616 .prepare = tlv320aic23_pcm_prepare,
479 .hw_params = tlv320aic23_hw_params, 617 .hw_params = tlv320aic23_hw_params,
480 .shutdown = tlv320aic23_shutdown, 618 .shutdown = tlv320aic23_shutdown,
481 }, 619 .digital_mute = tlv320aic23_mute,
482 .dai_ops = { 620 .set_fmt = tlv320aic23_set_dai_fmt,
483 .digital_mute = tlv320aic23_mute, 621 .set_sysclk = tlv320aic23_set_dai_sysclk,
484 .set_fmt = tlv320aic23_set_dai_fmt, 622 }
485 .set_sysclk = tlv320aic23_set_dai_sysclk,
486 }
487}; 623};
488EXPORT_SYMBOL_GPL(tlv320aic23_dai); 624EXPORT_SYMBOL_GPL(tlv320aic23_dai);
489 625
@@ -584,7 +720,7 @@ static int tlv320aic23_init(struct snd_soc_device *socdev)
584 720
585 tlv320aic23_add_controls(codec); 721 tlv320aic23_add_controls(codec);
586 tlv320aic23_add_widgets(codec); 722 tlv320aic23_add_widgets(codec);
587 ret = snd_soc_register_card(socdev); 723 ret = snd_soc_init_card(socdev);
588 if (ret < 0) { 724 if (ret < 0) {
589 printk(KERN_ERR "tlv320aic23: failed to register card\n"); 725 printk(KERN_ERR "tlv320aic23: failed to register card\n");
590 goto card_err; 726 goto card_err;
@@ -659,14 +795,15 @@ static int tlv320aic23_probe(struct platform_device *pdev)
659{ 795{
660 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 796 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
661 struct snd_soc_codec *codec; 797 struct snd_soc_codec *codec;
798 struct aic23 *aic23;
662 int ret = 0; 799 int ret = 0;
663 800
664 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION); 801 printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
665 802
666 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 803 aic23 = kzalloc(sizeof(struct aic23), GFP_KERNEL);
667 if (codec == NULL) 804 if (aic23 == NULL)
668 return -ENOMEM; 805 return -ENOMEM;
669 806 codec = &aic23->codec;
670 socdev->codec = codec; 807 socdev->codec = codec;
671 mutex_init(&codec->mutex); 808 mutex_init(&codec->mutex);
672 INIT_LIST_HEAD(&codec->dapm_widgets); 809 INIT_LIST_HEAD(&codec->dapm_widgets);
@@ -687,6 +824,7 @@ static int tlv320aic23_remove(struct platform_device *pdev)
687{ 824{
688 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 825 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
689 struct snd_soc_codec *codec = socdev->codec; 826 struct snd_soc_codec *codec = socdev->codec;
827 struct aic23 *aic23 = container_of(codec, struct aic23, codec);
690 828
691 if (codec->control_data) 829 if (codec->control_data)
692 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF); 830 tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_OFF);
@@ -697,7 +835,7 @@ static int tlv320aic23_remove(struct platform_device *pdev)
697 i2c_del_driver(&tlv320aic23_i2c_driver); 835 i2c_del_driver(&tlv320aic23_i2c_driver);
698#endif 836#endif
699 kfree(codec->reg_cache); 837 kfree(codec->reg_cache);
700 kfree(codec); 838 kfree(aic23);
701 839
702 return 0; 840 return 0;
703} 841}
@@ -709,6 +847,18 @@ struct snd_soc_codec_device soc_codec_dev_tlv320aic23 = {
709}; 847};
710EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23); 848EXPORT_SYMBOL_GPL(soc_codec_dev_tlv320aic23);
711 849
850static int __init tlv320aic23_modinit(void)
851{
852 return snd_soc_register_dai(&tlv320aic23_dai);
853}
854module_init(tlv320aic23_modinit);
855
856static void __exit tlv320aic23_exit(void)
857{
858 snd_soc_unregister_dai(&tlv320aic23_dai);
859}
860module_exit(tlv320aic23_exit);
861
712MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver"); 862MODULE_DESCRIPTION("ASoC TLV320AIC23 codec driver");
713MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); 863MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
714MODULE_LICENSE("GPL"); 864MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index bed8a9e63ddc..29f2f1a017fd 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -125,7 +125,8 @@ static int aic26_reg_write(struct snd_soc_codec *codec, unsigned int reg,
125 * Digital Audio Interface Operations 125 * Digital Audio Interface Operations
126 */ 126 */
127static int aic26_hw_params(struct snd_pcm_substream *substream, 127static int aic26_hw_params(struct snd_pcm_substream *substream,
128 struct snd_pcm_hw_params *params) 128 struct snd_pcm_hw_params *params,
129 struct snd_soc_dai *dai)
129{ 130{
130 struct snd_soc_pcm_runtime *rtd = substream->private_data; 131 struct snd_soc_pcm_runtime *rtd = substream->private_data;
131 struct snd_soc_device *socdev = rtd->socdev; 132 struct snd_soc_device *socdev = rtd->socdev;
@@ -287,8 +288,6 @@ struct snd_soc_dai aic26_dai = {
287 }, 288 },
288 .ops = { 289 .ops = {
289 .hw_params = aic26_hw_params, 290 .hw_params = aic26_hw_params,
290 },
291 .dai_ops = {
292 .digital_mute = aic26_mute, 291 .digital_mute = aic26_mute,
293 .set_sysclk = aic26_set_sysclk, 292 .set_sysclk = aic26_set_sysclk,
294 .set_fmt = aic26_set_fmt, 293 .set_fmt = aic26_set_fmt,
@@ -360,7 +359,7 @@ static int aic26_probe(struct platform_device *pdev)
360 359
361 /* CODEC is setup, we can register the card now */ 360 /* CODEC is setup, we can register the card now */
362 dev_dbg(&pdev->dev, "Registering card\n"); 361 dev_dbg(&pdev->dev, "Registering card\n");
363 ret = snd_soc_register_card(socdev); 362 ret = snd_soc_init_card(socdev);
364 if (ret < 0) { 363 if (ret < 0) {
365 dev_err(&pdev->dev, "aic26: failed to register card\n"); 364 dev_err(&pdev->dev, "aic26: failed to register card\n");
366 goto card_err; 365 goto card_err;
@@ -427,7 +426,7 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
427static int aic26_spi_probe(struct spi_device *spi) 426static int aic26_spi_probe(struct spi_device *spi)
428{ 427{
429 struct aic26 *aic26; 428 struct aic26 *aic26;
430 int rc, i, reg; 429 int ret, i, reg;
431 430
432 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n"); 431 dev_dbg(&spi->dev, "probing tlv320aic26 spi device\n");
433 432
@@ -457,6 +456,14 @@ static int aic26_spi_probe(struct spi_device *spi)
457 aic26->codec.reg_cache_size = AIC26_NUM_REGS; 456 aic26->codec.reg_cache_size = AIC26_NUM_REGS;
458 aic26->codec.reg_cache = aic26->reg_cache; 457 aic26->codec.reg_cache = aic26->reg_cache;
459 458
459 aic26_dai.dev = &spi->dev;
460 ret = snd_soc_register_dai(&aic26_dai);
461 if (ret != 0) {
462 dev_err(&spi->dev, "Failed to register DAI: %d\n", ret);
463 kfree(aic26);
464 return ret;
465 }
466
460 /* Reset the codec to power on defaults */ 467 /* Reset the codec to power on defaults */
461 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00); 468 aic26_reg_write(&aic26->codec, AIC26_REG_RESET, 0xBB00);
462 469
@@ -475,8 +482,8 @@ static int aic26_spi_probe(struct spi_device *spi)
475 482
476 /* Register the sysfs files for debugging */ 483 /* Register the sysfs files for debugging */
477 /* Create SysFS files */ 484 /* Create SysFS files */
478 rc = device_create_file(&spi->dev, &dev_attr_keyclick); 485 ret = device_create_file(&spi->dev, &dev_attr_keyclick);
479 if (rc) 486 if (ret)
480 dev_info(&spi->dev, "error creating sysfs files\n"); 487 dev_info(&spi->dev, "error creating sysfs files\n");
481 488
482#if defined(CONFIG_SND_SOC_OF_SIMPLE) 489#if defined(CONFIG_SND_SOC_OF_SIMPLE)
@@ -493,6 +500,7 @@ static int aic26_spi_remove(struct spi_device *spi)
493{ 500{
494 struct aic26 *aic26 = dev_get_drvdata(&spi->dev); 501 struct aic26 *aic26 = dev_get_drvdata(&spi->dev);
495 502
503 snd_soc_unregister_dai(&aic26_dai);
496 kfree(aic26); 504 kfree(aic26);
497 505
498 return 0; 506 return 0;
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index cff276ee261e..b47a749c5ea2 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -253,11 +253,17 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
253 253
254 SOC_DOUBLE_R("Line DAC Playback Volume", DACL1_2_LLOPM_VOL, 254 SOC_DOUBLE_R("Line DAC Playback Volume", DACL1_2_LLOPM_VOL,
255 DACR1_2_RLOPM_VOL, 0, 0x7f, 1), 255 DACR1_2_RLOPM_VOL, 0, 0x7f, 1),
256 SOC_DOUBLE_R("Line DAC Playback Switch", LLOPM_CTRL, RLOPM_CTRL, 3, 256 SOC_SINGLE("LineL Playback Switch", LLOPM_CTRL, 3, 0x01, 0),
257 0x01, 0), 257 SOC_SINGLE("LineR Playback Switch", RLOPM_CTRL, 3, 0x01, 0),
258 SOC_DOUBLE_R("Line PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL, 258 SOC_DOUBLE_R("LineL DAC Playback Volume", DACL1_2_LLOPM_VOL,
259 PGAR_2_RLOPM_VOL, 0, 0x7f, 1), 259 DACR1_2_LLOPM_VOL, 0, 0x7f, 1),
260 SOC_DOUBLE_R("Line Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL, 260 SOC_SINGLE("LineL Left PGA Bypass Playback Volume", PGAL_2_LLOPM_VOL,
261 0, 0x7f, 1),
262 SOC_SINGLE("LineR Right PGA Bypass Playback Volume", PGAR_2_RLOPM_VOL,
263 0, 0x7f, 1),
264 SOC_DOUBLE_R("LineL Line2 Bypass Playback Volume", LINE2L_2_LLOPM_VOL,
265 LINE2R_2_LLOPM_VOL, 0, 0x7f, 1),
266 SOC_DOUBLE_R("LineR Line2 Bypass Playback Volume", LINE2L_2_RLOPM_VOL,
261 LINE2R_2_RLOPM_VOL, 0, 0x7f, 1), 267 LINE2R_2_RLOPM_VOL, 0, 0x7f, 1),
262 268
263 SOC_DOUBLE_R("Mono DAC Playback Volume", DACL1_2_MONOLOPM_VOL, 269 SOC_DOUBLE_R("Mono DAC Playback Volume", DACL1_2_MONOLOPM_VOL,
@@ -272,8 +278,12 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
272 DACR1_2_HPROUT_VOL, 0, 0x7f, 1), 278 DACR1_2_HPROUT_VOL, 0, 0x7f, 1),
273 SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3, 279 SOC_DOUBLE_R("HP DAC Playback Switch", HPLOUT_CTRL, HPROUT_CTRL, 3,
274 0x01, 0), 280 0x01, 0),
275 SOC_DOUBLE_R("HP PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL, 281 SOC_DOUBLE_R("HP Right PGA Bypass Playback Volume", PGAR_2_HPLOUT_VOL,
276 PGAR_2_HPROUT_VOL, 0, 0x7f, 1), 282 PGAR_2_HPROUT_VOL, 0, 0x7f, 1),
283 SOC_SINGLE("HPL PGA Bypass Playback Volume", PGAL_2_HPLOUT_VOL,
284 0, 0x7f, 1),
285 SOC_SINGLE("HPR PGA Bypass Playback Volume", PGAL_2_HPROUT_VOL,
286 0, 0x7f, 1),
277 SOC_DOUBLE_R("HP Line2 Bypass Playback Volume", LINE2L_2_HPLOUT_VOL, 287 SOC_DOUBLE_R("HP Line2 Bypass Playback Volume", LINE2L_2_HPLOUT_VOL,
278 LINE2R_2_HPROUT_VOL, 0, 0x7f, 1), 288 LINE2R_2_HPROUT_VOL, 0, 0x7f, 1),
279 289
@@ -281,8 +291,10 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
281 DACR1_2_HPRCOM_VOL, 0, 0x7f, 1), 291 DACR1_2_HPRCOM_VOL, 0, 0x7f, 1),
282 SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3, 292 SOC_DOUBLE_R("HPCOM DAC Playback Switch", HPLCOM_CTRL, HPRCOM_CTRL, 3,
283 0x01, 0), 293 0x01, 0),
284 SOC_DOUBLE_R("HPCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL, 294 SOC_SINGLE("HPLCOM PGA Bypass Playback Volume", PGAL_2_HPLCOM_VOL,
285 PGAR_2_HPRCOM_VOL, 0, 0x7f, 1), 295 0, 0x7f, 1),
296 SOC_SINGLE("HPRCOM PGA Bypass Playback Volume", PGAL_2_HPRCOM_VOL,
297 0, 0x7f, 1),
286 SOC_DOUBLE_R("HPCOM Line2 Bypass Playback Volume", LINE2L_2_HPLCOM_VOL, 298 SOC_DOUBLE_R("HPCOM Line2 Bypass Playback Volume", LINE2L_2_HPLCOM_VOL,
287 LINE2R_2_HPRCOM_VOL, 0, 0x7f, 1), 299 LINE2R_2_HPRCOM_VOL, 0, 0x7f, 1),
288 300
@@ -333,7 +345,8 @@ SOC_DAPM_ENUM("Route", aic3x_enum[RHPCOM_ENUM]);
333 345
334/* Left DAC_L1 Mixer */ 346/* Left DAC_L1 Mixer */
335static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = { 347static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = {
336 SOC_DAPM_SINGLE("Line Switch", DACL1_2_LLOPM_VOL, 7, 1, 0), 348 SOC_DAPM_SINGLE("LineL Switch", DACL1_2_LLOPM_VOL, 7, 1, 0),
349 SOC_DAPM_SINGLE("LineR Switch", DACL1_2_RLOPM_VOL, 7, 1, 0),
337 SOC_DAPM_SINGLE("Mono Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0), 350 SOC_DAPM_SINGLE("Mono Switch", DACL1_2_MONOLOPM_VOL, 7, 1, 0),
338 SOC_DAPM_SINGLE("HP Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0), 351 SOC_DAPM_SINGLE("HP Switch", DACL1_2_HPLOUT_VOL, 7, 1, 0),
339 SOC_DAPM_SINGLE("HPCOM Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0), 352 SOC_DAPM_SINGLE("HPCOM Switch", DACL1_2_HPLCOM_VOL, 7, 1, 0),
@@ -341,7 +354,8 @@ static const struct snd_kcontrol_new aic3x_left_dac_mixer_controls[] = {
341 354
342/* Right DAC_R1 Mixer */ 355/* Right DAC_R1 Mixer */
343static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = { 356static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = {
344 SOC_DAPM_SINGLE("Line Switch", DACR1_2_RLOPM_VOL, 7, 1, 0), 357 SOC_DAPM_SINGLE("LineL Switch", DACR1_2_LLOPM_VOL, 7, 1, 0),
358 SOC_DAPM_SINGLE("LineR Switch", DACR1_2_RLOPM_VOL, 7, 1, 0),
345 SOC_DAPM_SINGLE("Mono Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0), 359 SOC_DAPM_SINGLE("Mono Switch", DACR1_2_MONOLOPM_VOL, 7, 1, 0),
346 SOC_DAPM_SINGLE("HP Switch", DACR1_2_HPROUT_VOL, 7, 1, 0), 360 SOC_DAPM_SINGLE("HP Switch", DACR1_2_HPROUT_VOL, 7, 1, 0),
347 SOC_DAPM_SINGLE("HPCOM Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0), 361 SOC_DAPM_SINGLE("HPCOM Switch", DACR1_2_HPRCOM_VOL, 7, 1, 0),
@@ -350,14 +364,18 @@ static const struct snd_kcontrol_new aic3x_right_dac_mixer_controls[] = {
350/* Left PGA Mixer */ 364/* Left PGA Mixer */
351static const struct snd_kcontrol_new aic3x_left_pga_mixer_controls[] = { 365static const struct snd_kcontrol_new aic3x_left_pga_mixer_controls[] = {
352 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1), 366 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_LADC_CTRL, 3, 1, 1),
367 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_LADC_CTRL, 3, 1, 1),
353 SOC_DAPM_SINGLE_AIC3X("Line2L Switch", LINE2L_2_LADC_CTRL, 3, 1, 1), 368 SOC_DAPM_SINGLE_AIC3X("Line2L Switch", LINE2L_2_LADC_CTRL, 3, 1, 1),
354 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1), 369 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_LADC_CTRL, 4, 1, 1),
370 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_LADC_CTRL, 0, 1, 1),
355}; 371};
356 372
357/* Right PGA Mixer */ 373/* Right PGA Mixer */
358static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = { 374static const struct snd_kcontrol_new aic3x_right_pga_mixer_controls[] = {
359 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1), 375 SOC_DAPM_SINGLE_AIC3X("Line1R Switch", LINE1R_2_RADC_CTRL, 3, 1, 1),
376 SOC_DAPM_SINGLE_AIC3X("Line1L Switch", LINE1L_2_RADC_CTRL, 3, 1, 1),
360 SOC_DAPM_SINGLE_AIC3X("Line2R Switch", LINE2R_2_RADC_CTRL, 3, 1, 1), 377 SOC_DAPM_SINGLE_AIC3X("Line2R Switch", LINE2R_2_RADC_CTRL, 3, 1, 1),
378 SOC_DAPM_SINGLE_AIC3X("Mic3L Switch", MIC3LR_2_RADC_CTRL, 4, 1, 1),
361 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1), 379 SOC_DAPM_SINGLE_AIC3X("Mic3R Switch", MIC3LR_2_RADC_CTRL, 0, 1, 1),
362}; 380};
363 381
@@ -379,34 +397,42 @@ SOC_DAPM_ENUM("Route", aic3x_enum[LINE2R_ENUM]);
379 397
380/* Left PGA Bypass Mixer */ 398/* Left PGA Bypass Mixer */
381static const struct snd_kcontrol_new aic3x_left_pga_bp_mixer_controls[] = { 399static const struct snd_kcontrol_new aic3x_left_pga_bp_mixer_controls[] = {
382 SOC_DAPM_SINGLE("Line Switch", PGAL_2_LLOPM_VOL, 7, 1, 0), 400 SOC_DAPM_SINGLE("LineL Switch", PGAL_2_LLOPM_VOL, 7, 1, 0),
401 SOC_DAPM_SINGLE("LineR Switch", PGAL_2_RLOPM_VOL, 7, 1, 0),
383 SOC_DAPM_SINGLE("Mono Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0), 402 SOC_DAPM_SINGLE("Mono Switch", PGAL_2_MONOLOPM_VOL, 7, 1, 0),
384 SOC_DAPM_SINGLE("HP Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0), 403 SOC_DAPM_SINGLE("HPL Switch", PGAL_2_HPLOUT_VOL, 7, 1, 0),
385 SOC_DAPM_SINGLE("HPCOM Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0), 404 SOC_DAPM_SINGLE("HPR Switch", PGAL_2_HPROUT_VOL, 7, 1, 0),
405 SOC_DAPM_SINGLE("HPLCOM Switch", PGAL_2_HPLCOM_VOL, 7, 1, 0),
406 SOC_DAPM_SINGLE("HPRCOM Switch", PGAL_2_HPRCOM_VOL, 7, 1, 0),
386}; 407};
387 408
388/* Right PGA Bypass Mixer */ 409/* Right PGA Bypass Mixer */
389static const struct snd_kcontrol_new aic3x_right_pga_bp_mixer_controls[] = { 410static const struct snd_kcontrol_new aic3x_right_pga_bp_mixer_controls[] = {
390 SOC_DAPM_SINGLE("Line Switch", PGAR_2_RLOPM_VOL, 7, 1, 0), 411 SOC_DAPM_SINGLE("LineL Switch", PGAR_2_LLOPM_VOL, 7, 1, 0),
412 SOC_DAPM_SINGLE("LineR Switch", PGAR_2_RLOPM_VOL, 7, 1, 0),
391 SOC_DAPM_SINGLE("Mono Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0), 413 SOC_DAPM_SINGLE("Mono Switch", PGAR_2_MONOLOPM_VOL, 7, 1, 0),
392 SOC_DAPM_SINGLE("HP Switch", PGAR_2_HPROUT_VOL, 7, 1, 0), 414 SOC_DAPM_SINGLE("HPL Switch", PGAR_2_HPLOUT_VOL, 7, 1, 0),
393 SOC_DAPM_SINGLE("HPCOM Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0), 415 SOC_DAPM_SINGLE("HPR Switch", PGAR_2_HPROUT_VOL, 7, 1, 0),
416 SOC_DAPM_SINGLE("HPLCOM Switch", PGAR_2_HPLCOM_VOL, 7, 1, 0),
417 SOC_DAPM_SINGLE("HPRCOM Switch", PGAR_2_HPRCOM_VOL, 7, 1, 0),
394}; 418};
395 419
396/* Left Line2 Bypass Mixer */ 420/* Left Line2 Bypass Mixer */
397static const struct snd_kcontrol_new aic3x_left_line2_bp_mixer_controls[] = { 421static const struct snd_kcontrol_new aic3x_left_line2_bp_mixer_controls[] = {
398 SOC_DAPM_SINGLE("Line Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0), 422 SOC_DAPM_SINGLE("LineL Switch", LINE2L_2_LLOPM_VOL, 7, 1, 0),
423 SOC_DAPM_SINGLE("LineR Switch", LINE2L_2_RLOPM_VOL, 7, 1, 0),
399 SOC_DAPM_SINGLE("Mono Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0), 424 SOC_DAPM_SINGLE("Mono Switch", LINE2L_2_MONOLOPM_VOL, 7, 1, 0),
400 SOC_DAPM_SINGLE("HP Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0), 425 SOC_DAPM_SINGLE("HP Switch", LINE2L_2_HPLOUT_VOL, 7, 1, 0),
401 SOC_DAPM_SINGLE("HPCOM Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0), 426 SOC_DAPM_SINGLE("HPLCOM Switch", LINE2L_2_HPLCOM_VOL, 7, 1, 0),
402}; 427};
403 428
404/* Right Line2 Bypass Mixer */ 429/* Right Line2 Bypass Mixer */
405static const struct snd_kcontrol_new aic3x_right_line2_bp_mixer_controls[] = { 430static const struct snd_kcontrol_new aic3x_right_line2_bp_mixer_controls[] = {
406 SOC_DAPM_SINGLE("Line Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0), 431 SOC_DAPM_SINGLE("LineL Switch", LINE2R_2_LLOPM_VOL, 7, 1, 0),
432 SOC_DAPM_SINGLE("LineR Switch", LINE2R_2_RLOPM_VOL, 7, 1, 0),
407 SOC_DAPM_SINGLE("Mono Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0), 433 SOC_DAPM_SINGLE("Mono Switch", LINE2R_2_MONOLOPM_VOL, 7, 1, 0),
408 SOC_DAPM_SINGLE("HP Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0), 434 SOC_DAPM_SINGLE("HP Switch", LINE2R_2_HPROUT_VOL, 7, 1, 0),
409 SOC_DAPM_SINGLE("HPCOM Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0), 435 SOC_DAPM_SINGLE("HPRCOM Switch", LINE2R_2_HPRCOM_VOL, 7, 1, 0),
410}; 436};
411 437
412static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = { 438static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
@@ -439,22 +465,26 @@ static const struct snd_soc_dapm_widget aic3x_dapm_widgets[] = {
439 /* Mono Output */ 465 /* Mono Output */
440 SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0), 466 SND_SOC_DAPM_PGA("Mono Out", MONOLOPM_CTRL, 0, 0, NULL, 0),
441 467
442 /* Left Inputs to Left ADC */ 468 /* Inputs to Left ADC */
443 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0), 469 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", LINE1L_2_LADC_CTRL, 2, 0),
444 SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0, 470 SND_SOC_DAPM_MIXER("Left PGA Mixer", SND_SOC_NOPM, 0, 0,
445 &aic3x_left_pga_mixer_controls[0], 471 &aic3x_left_pga_mixer_controls[0],
446 ARRAY_SIZE(aic3x_left_pga_mixer_controls)), 472 ARRAY_SIZE(aic3x_left_pga_mixer_controls)),
447 SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0, 473 SND_SOC_DAPM_MUX("Left Line1L Mux", SND_SOC_NOPM, 0, 0,
448 &aic3x_left_line1_mux_controls), 474 &aic3x_left_line1_mux_controls),
475 SND_SOC_DAPM_MUX("Left Line1R Mux", SND_SOC_NOPM, 0, 0,
476 &aic3x_left_line1_mux_controls),
449 SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0, 477 SND_SOC_DAPM_MUX("Left Line2L Mux", SND_SOC_NOPM, 0, 0,
450 &aic3x_left_line2_mux_controls), 478 &aic3x_left_line2_mux_controls),
451 479
452 /* Right Inputs to Right ADC */ 480 /* Inputs to Right ADC */
453 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", 481 SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
454 LINE1R_2_RADC_CTRL, 2, 0), 482 LINE1R_2_RADC_CTRL, 2, 0),
455 SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0, 483 SND_SOC_DAPM_MIXER("Right PGA Mixer", SND_SOC_NOPM, 0, 0,
456 &aic3x_right_pga_mixer_controls[0], 484 &aic3x_right_pga_mixer_controls[0],
457 ARRAY_SIZE(aic3x_right_pga_mixer_controls)), 485 ARRAY_SIZE(aic3x_right_pga_mixer_controls)),
486 SND_SOC_DAPM_MUX("Right Line1L Mux", SND_SOC_NOPM, 0, 0,
487 &aic3x_right_line1_mux_controls),
458 SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0, 488 SND_SOC_DAPM_MUX("Right Line1R Mux", SND_SOC_NOPM, 0, 0,
459 &aic3x_right_line1_mux_controls), 489 &aic3x_right_line1_mux_controls),
460 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0, 490 SND_SOC_DAPM_MUX("Right Line2R Mux", SND_SOC_NOPM, 0, 0,
@@ -531,7 +561,8 @@ static const struct snd_soc_dapm_route intercon[] = {
531 {"Left DAC Mux", "DAC_L2", "Left DAC"}, 561 {"Left DAC Mux", "DAC_L2", "Left DAC"},
532 {"Left DAC Mux", "DAC_L3", "Left DAC"}, 562 {"Left DAC Mux", "DAC_L3", "Left DAC"},
533 563
534 {"Left DAC_L1 Mixer", "Line Switch", "Left DAC Mux"}, 564 {"Left DAC_L1 Mixer", "LineL Switch", "Left DAC Mux"},
565 {"Left DAC_L1 Mixer", "LineR Switch", "Left DAC Mux"},
535 {"Left DAC_L1 Mixer", "Mono Switch", "Left DAC Mux"}, 566 {"Left DAC_L1 Mixer", "Mono Switch", "Left DAC Mux"},
536 {"Left DAC_L1 Mixer", "HP Switch", "Left DAC Mux"}, 567 {"Left DAC_L1 Mixer", "HP Switch", "Left DAC Mux"},
537 {"Left DAC_L1 Mixer", "HPCOM Switch", "Left DAC Mux"}, 568 {"Left DAC_L1 Mixer", "HPCOM Switch", "Left DAC Mux"},
@@ -557,7 +588,8 @@ static const struct snd_soc_dapm_route intercon[] = {
557 {"Right DAC Mux", "DAC_R2", "Right DAC"}, 588 {"Right DAC Mux", "DAC_R2", "Right DAC"},
558 {"Right DAC Mux", "DAC_R3", "Right DAC"}, 589 {"Right DAC Mux", "DAC_R3", "Right DAC"},
559 590
560 {"Right DAC_R1 Mixer", "Line Switch", "Right DAC Mux"}, 591 {"Right DAC_R1 Mixer", "LineL Switch", "Right DAC Mux"},
592 {"Right DAC_R1 Mixer", "LineR Switch", "Right DAC Mux"},
561 {"Right DAC_R1 Mixer", "Mono Switch", "Right DAC Mux"}, 593 {"Right DAC_R1 Mixer", "Mono Switch", "Right DAC Mux"},
562 {"Right DAC_R1 Mixer", "HP Switch", "Right DAC Mux"}, 594 {"Right DAC_R1 Mixer", "HP Switch", "Right DAC Mux"},
563 {"Right DAC_R1 Mixer", "HPCOM Switch", "Right DAC Mux"}, 595 {"Right DAC_R1 Mixer", "HPCOM Switch", "Right DAC Mux"},
@@ -592,8 +624,10 @@ static const struct snd_soc_dapm_route intercon[] = {
592 {"Left Line2L Mux", "differential", "LINE2L"}, 624 {"Left Line2L Mux", "differential", "LINE2L"},
593 625
594 {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"}, 626 {"Left PGA Mixer", "Line1L Switch", "Left Line1L Mux"},
627 {"Left PGA Mixer", "Line1R Switch", "Left Line1R Mux"},
595 {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"}, 628 {"Left PGA Mixer", "Line2L Switch", "Left Line2L Mux"},
596 {"Left PGA Mixer", "Mic3L Switch", "MIC3L"}, 629 {"Left PGA Mixer", "Mic3L Switch", "MIC3L"},
630 {"Left PGA Mixer", "Mic3R Switch", "MIC3R"},
597 631
598 {"Left ADC", NULL, "Left PGA Mixer"}, 632 {"Left ADC", NULL, "Left PGA Mixer"},
599 {"Left ADC", NULL, "GPIO1 dmic modclk"}, 633 {"Left ADC", NULL, "GPIO1 dmic modclk"},
@@ -605,18 +639,23 @@ static const struct snd_soc_dapm_route intercon[] = {
605 {"Right Line2R Mux", "single-ended", "LINE2R"}, 639 {"Right Line2R Mux", "single-ended", "LINE2R"},
606 {"Right Line2R Mux", "differential", "LINE2R"}, 640 {"Right Line2R Mux", "differential", "LINE2R"},
607 641
642 {"Right PGA Mixer", "Line1L Switch", "Right Line1L Mux"},
608 {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"}, 643 {"Right PGA Mixer", "Line1R Switch", "Right Line1R Mux"},
609 {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"}, 644 {"Right PGA Mixer", "Line2R Switch", "Right Line2R Mux"},
645 {"Right PGA Mixer", "Mic3L Switch", "MIC3L"},
610 {"Right PGA Mixer", "Mic3R Switch", "MIC3R"}, 646 {"Right PGA Mixer", "Mic3R Switch", "MIC3R"},
611 647
612 {"Right ADC", NULL, "Right PGA Mixer"}, 648 {"Right ADC", NULL, "Right PGA Mixer"},
613 {"Right ADC", NULL, "GPIO1 dmic modclk"}, 649 {"Right ADC", NULL, "GPIO1 dmic modclk"},
614 650
615 /* Left PGA Bypass */ 651 /* Left PGA Bypass */
616 {"Left PGA Bypass Mixer", "Line Switch", "Left PGA Mixer"}, 652 {"Left PGA Bypass Mixer", "LineL Switch", "Left PGA Mixer"},
653 {"Left PGA Bypass Mixer", "LineR Switch", "Left PGA Mixer"},
617 {"Left PGA Bypass Mixer", "Mono Switch", "Left PGA Mixer"}, 654 {"Left PGA Bypass Mixer", "Mono Switch", "Left PGA Mixer"},
618 {"Left PGA Bypass Mixer", "HP Switch", "Left PGA Mixer"}, 655 {"Left PGA Bypass Mixer", "HPL Switch", "Left PGA Mixer"},
619 {"Left PGA Bypass Mixer", "HPCOM Switch", "Left PGA Mixer"}, 656 {"Left PGA Bypass Mixer", "HPR Switch", "Left PGA Mixer"},
657 {"Left PGA Bypass Mixer", "HPLCOM Switch", "Left PGA Mixer"},
658 {"Left PGA Bypass Mixer", "HPRCOM Switch", "Left PGA Mixer"},
620 659
621 {"Left HPCOM Mux", "differential of HPLOUT", "Left PGA Bypass Mixer"}, 660 {"Left HPCOM Mux", "differential of HPLOUT", "Left PGA Bypass Mixer"},
622 {"Left HPCOM Mux", "constant VCM", "Left PGA Bypass Mixer"}, 661 {"Left HPCOM Mux", "constant VCM", "Left PGA Bypass Mixer"},
@@ -627,10 +666,13 @@ static const struct snd_soc_dapm_route intercon[] = {
627 {"Left HP Out", NULL, "Left PGA Bypass Mixer"}, 666 {"Left HP Out", NULL, "Left PGA Bypass Mixer"},
628 667
629 /* Right PGA Bypass */ 668 /* Right PGA Bypass */
630 {"Right PGA Bypass Mixer", "Line Switch", "Right PGA Mixer"}, 669 {"Right PGA Bypass Mixer", "LineL Switch", "Right PGA Mixer"},
670 {"Right PGA Bypass Mixer", "LineR Switch", "Right PGA Mixer"},
631 {"Right PGA Bypass Mixer", "Mono Switch", "Right PGA Mixer"}, 671 {"Right PGA Bypass Mixer", "Mono Switch", "Right PGA Mixer"},
632 {"Right PGA Bypass Mixer", "HP Switch", "Right PGA Mixer"}, 672 {"Right PGA Bypass Mixer", "HPL Switch", "Right PGA Mixer"},
633 {"Right PGA Bypass Mixer", "HPCOM Switch", "Right PGA Mixer"}, 673 {"Right PGA Bypass Mixer", "HPR Switch", "Right PGA Mixer"},
674 {"Right PGA Bypass Mixer", "HPLCOM Switch", "Right PGA Mixer"},
675 {"Right PGA Bypass Mixer", "HPRCOM Switch", "Right PGA Mixer"},
634 676
635 {"Right HPCOM Mux", "differential of HPROUT", "Right PGA Bypass Mixer"}, 677 {"Right HPCOM Mux", "differential of HPROUT", "Right PGA Bypass Mixer"},
636 {"Right HPCOM Mux", "constant VCM", "Right PGA Bypass Mixer"}, 678 {"Right HPCOM Mux", "constant VCM", "Right PGA Bypass Mixer"},
@@ -643,10 +685,11 @@ static const struct snd_soc_dapm_route intercon[] = {
643 {"Right HP Out", NULL, "Right PGA Bypass Mixer"}, 685 {"Right HP Out", NULL, "Right PGA Bypass Mixer"},
644 686
645 /* Left Line2 Bypass */ 687 /* Left Line2 Bypass */
646 {"Left Line2 Bypass Mixer", "Line Switch", "Left Line2L Mux"}, 688 {"Left Line2 Bypass Mixer", "LineL Switch", "Left Line2L Mux"},
689 {"Left Line2 Bypass Mixer", "LineR Switch", "Left Line2L Mux"},
647 {"Left Line2 Bypass Mixer", "Mono Switch", "Left Line2L Mux"}, 690 {"Left Line2 Bypass Mixer", "Mono Switch", "Left Line2L Mux"},
648 {"Left Line2 Bypass Mixer", "HP Switch", "Left Line2L Mux"}, 691 {"Left Line2 Bypass Mixer", "HP Switch", "Left Line2L Mux"},
649 {"Left Line2 Bypass Mixer", "HPCOM Switch", "Left Line2L Mux"}, 692 {"Left Line2 Bypass Mixer", "HPLCOM Switch", "Left Line2L Mux"},
650 693
651 {"Left HPCOM Mux", "differential of HPLOUT", "Left Line2 Bypass Mixer"}, 694 {"Left HPCOM Mux", "differential of HPLOUT", "Left Line2 Bypass Mixer"},
652 {"Left HPCOM Mux", "constant VCM", "Left Line2 Bypass Mixer"}, 695 {"Left HPCOM Mux", "constant VCM", "Left Line2 Bypass Mixer"},
@@ -657,10 +700,11 @@ static const struct snd_soc_dapm_route intercon[] = {
657 {"Left HP Out", NULL, "Left Line2 Bypass Mixer"}, 700 {"Left HP Out", NULL, "Left Line2 Bypass Mixer"},
658 701
659 /* Right Line2 Bypass */ 702 /* Right Line2 Bypass */
660 {"Right Line2 Bypass Mixer", "Line Switch", "Right Line2R Mux"}, 703 {"Right Line2 Bypass Mixer", "LineL Switch", "Right Line2R Mux"},
704 {"Right Line2 Bypass Mixer", "LineR Switch", "Right Line2R Mux"},
661 {"Right Line2 Bypass Mixer", "Mono Switch", "Right Line2R Mux"}, 705 {"Right Line2 Bypass Mixer", "Mono Switch", "Right Line2R Mux"},
662 {"Right Line2 Bypass Mixer", "HP Switch", "Right Line2R Mux"}, 706 {"Right Line2 Bypass Mixer", "HP Switch", "Right Line2R Mux"},
663 {"Right Line2 Bypass Mixer", "HPCOM Switch", "Right Line2R Mux"}, 707 {"Right Line2 Bypass Mixer", "HPRCOM Switch", "Right Line2R Mux"},
664 708
665 {"Right HPCOM Mux", "differential of HPROUT", "Right Line2 Bypass Mixer"}, 709 {"Right HPCOM Mux", "differential of HPROUT", "Right Line2 Bypass Mixer"},
666 {"Right HPCOM Mux", "constant VCM", "Right Line2 Bypass Mixer"}, 710 {"Right HPCOM Mux", "constant VCM", "Right Line2 Bypass Mixer"},
@@ -694,7 +738,8 @@ static int aic3x_add_widgets(struct snd_soc_codec *codec)
694} 738}
695 739
696static int aic3x_hw_params(struct snd_pcm_substream *substream, 740static int aic3x_hw_params(struct snd_pcm_substream *substream,
697 struct snd_pcm_hw_params *params) 741 struct snd_pcm_hw_params *params,
742 struct snd_soc_dai *dai)
698{ 743{
699 struct snd_soc_pcm_runtime *rtd = substream->private_data; 744 struct snd_soc_pcm_runtime *rtd = substream->private_data;
700 struct snd_soc_device *socdev = rtd->socdev; 745 struct snd_soc_device *socdev = rtd->socdev;
@@ -846,6 +891,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
846 struct snd_soc_codec *codec = codec_dai->codec; 891 struct snd_soc_codec *codec = codec_dai->codec;
847 struct aic3x_priv *aic3x = codec->private_data; 892 struct aic3x_priv *aic3x = codec->private_data;
848 u8 iface_areg, iface_breg; 893 u8 iface_areg, iface_breg;
894 int delay = 0;
849 895
850 iface_areg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f; 896 iface_areg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLA) & 0x3f;
851 iface_breg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f; 897 iface_breg = aic3x_read_reg_cache(codec, AIC3X_ASD_INTF_CTRLB) & 0x3f;
@@ -871,6 +917,8 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
871 SND_SOC_DAIFMT_INV_MASK)) { 917 SND_SOC_DAIFMT_INV_MASK)) {
872 case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF): 918 case (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF):
873 break; 919 break;
920 case (SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_IB_NF):
921 delay = 1;
874 case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF): 922 case (SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_IB_NF):
875 iface_breg |= (0x01 << 6); 923 iface_breg |= (0x01 << 6);
876 break; 924 break;
@@ -887,6 +935,7 @@ static int aic3x_set_dai_fmt(struct snd_soc_dai *codec_dai,
887 /* set iface */ 935 /* set iface */
888 aic3x_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg); 936 aic3x_write(codec, AIC3X_ASD_INTF_CTRLA, iface_areg);
889 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg); 937 aic3x_write(codec, AIC3X_ASD_INTF_CTRLB, iface_breg);
938 aic3x_write(codec, AIC3X_ASD_INTF_CTRLC, delay);
890 939
891 return 0; 940 return 0;
892} 941}
@@ -981,14 +1030,41 @@ int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio)
981} 1030}
982EXPORT_SYMBOL_GPL(aic3x_get_gpio); 1031EXPORT_SYMBOL_GPL(aic3x_get_gpio);
983 1032
1033void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
1034 int headset_debounce, int button_debounce)
1035{
1036 u8 val;
1037
1038 val = ((detect & AIC3X_HEADSET_DETECT_MASK)
1039 << AIC3X_HEADSET_DETECT_SHIFT) |
1040 ((headset_debounce & AIC3X_HEADSET_DEBOUNCE_MASK)
1041 << AIC3X_HEADSET_DEBOUNCE_SHIFT) |
1042 ((button_debounce & AIC3X_BUTTON_DEBOUNCE_MASK)
1043 << AIC3X_BUTTON_DEBOUNCE_SHIFT);
1044
1045 if (detect & AIC3X_HEADSET_DETECT_MASK)
1046 val |= AIC3X_HEADSET_DETECT_ENABLED;
1047
1048 aic3x_write(codec, AIC3X_HEADSET_DETECT_CTRL_A, val);
1049}
1050EXPORT_SYMBOL_GPL(aic3x_set_headset_detection);
1051
984int aic3x_headset_detected(struct snd_soc_codec *codec) 1052int aic3x_headset_detected(struct snd_soc_codec *codec)
985{ 1053{
986 u8 val; 1054 u8 val;
987 aic3x_read(codec, AIC3X_RT_IRQ_FLAGS_REG, &val); 1055 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
988 return (val >> 2) & 1; 1056 return (val >> 4) & 1;
989} 1057}
990EXPORT_SYMBOL_GPL(aic3x_headset_detected); 1058EXPORT_SYMBOL_GPL(aic3x_headset_detected);
991 1059
1060int aic3x_button_pressed(struct snd_soc_codec *codec)
1061{
1062 u8 val;
1063 aic3x_read(codec, AIC3X_HEADSET_DETECT_CTRL_B, &val);
1064 return (val >> 5) & 1;
1065}
1066EXPORT_SYMBOL_GPL(aic3x_button_pressed);
1067
992#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000 1068#define AIC3X_RATES SNDRV_PCM_RATE_8000_96000
993#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 1069#define AIC3X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
994 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 1070 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE)
@@ -1009,8 +1085,6 @@ struct snd_soc_dai aic3x_dai = {
1009 .formats = AIC3X_FORMATS,}, 1085 .formats = AIC3X_FORMATS,},
1010 .ops = { 1086 .ops = {
1011 .hw_params = aic3x_hw_params, 1087 .hw_params = aic3x_hw_params,
1012 },
1013 .dai_ops = {
1014 .digital_mute = aic3x_mute, 1088 .digital_mute = aic3x_mute,
1015 .set_sysclk = aic3x_set_dai_sysclk, 1089 .set_sysclk = aic3x_set_dai_sysclk,
1016 .set_fmt = aic3x_set_dai_fmt, 1090 .set_fmt = aic3x_set_dai_fmt,
@@ -1152,7 +1226,7 @@ static int aic3x_init(struct snd_soc_device *socdev)
1152 1226
1153 aic3x_add_controls(codec); 1227 aic3x_add_controls(codec);
1154 aic3x_add_widgets(codec); 1228 aic3x_add_widgets(codec);
1155 ret = snd_soc_register_card(socdev); 1229 ret = snd_soc_init_card(socdev);
1156 if (ret < 0) { 1230 if (ret < 0) {
1157 printk(KERN_ERR "aic3x: failed to register card\n"); 1231 printk(KERN_ERR "aic3x: failed to register card\n");
1158 goto card_err; 1232 goto card_err;
@@ -1341,6 +1415,18 @@ struct snd_soc_codec_device soc_codec_dev_aic3x = {
1341}; 1415};
1342EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x); 1416EXPORT_SYMBOL_GPL(soc_codec_dev_aic3x);
1343 1417
1418static int __init aic3x_modinit(void)
1419{
1420 return snd_soc_register_dai(&aic3x_dai);
1421}
1422module_init(aic3x_modinit);
1423
1424static void __exit aic3x_exit(void)
1425{
1426 snd_soc_unregister_dai(&aic3x_dai);
1427}
1428module_exit(aic3x_exit);
1429
1344MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver"); 1430MODULE_DESCRIPTION("ASoC TLV320AIC3X codec driver");
1345MODULE_AUTHOR("Vladimir Barinov"); 1431MODULE_AUTHOR("Vladimir Barinov");
1346MODULE_LICENSE("GPL"); 1432MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 00a195aa02e4..ac827e578c4d 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -35,11 +35,15 @@
35#define AIC3X_ASD_INTF_CTRLA 8 35#define AIC3X_ASD_INTF_CTRLA 8
36/* Audio serial data interface control register B */ 36/* Audio serial data interface control register B */
37#define AIC3X_ASD_INTF_CTRLB 9 37#define AIC3X_ASD_INTF_CTRLB 9
38/* Audio serial data interface control register C */
39#define AIC3X_ASD_INTF_CTRLC 10
38/* Audio overflow status and PLL R value programming register */ 40/* Audio overflow status and PLL R value programming register */
39#define AIC3X_OVRF_STATUS_AND_PLLR_REG 11 41#define AIC3X_OVRF_STATUS_AND_PLLR_REG 11
40/* Audio codec digital filter control register */ 42/* Audio codec digital filter control register */
41#define AIC3X_CODEC_DFILT_CTRL 12 43#define AIC3X_CODEC_DFILT_CTRL 12
42 44/* Headset/button press detection register */
45#define AIC3X_HEADSET_DETECT_CTRL_A 13
46#define AIC3X_HEADSET_DETECT_CTRL_B 14
43/* ADC PGA Gain control registers */ 47/* ADC PGA Gain control registers */
44#define LADC_VOL 15 48#define LADC_VOL 15
45#define RADC_VOL 16 49#define RADC_VOL 16
@@ -48,7 +52,9 @@
48#define MIC3LR_2_RADC_CTRL 18 52#define MIC3LR_2_RADC_CTRL 18
49/* Line1 Input control registers */ 53/* Line1 Input control registers */
50#define LINE1L_2_LADC_CTRL 19 54#define LINE1L_2_LADC_CTRL 19
55#define LINE1R_2_LADC_CTRL 21
51#define LINE1R_2_RADC_CTRL 22 56#define LINE1R_2_RADC_CTRL 22
57#define LINE1L_2_RADC_CTRL 24
52/* Line2 Input control registers */ 58/* Line2 Input control registers */
53#define LINE2L_2_LADC_CTRL 20 59#define LINE2L_2_LADC_CTRL 20
54#define LINE2R_2_RADC_CTRL 23 60#define LINE2R_2_RADC_CTRL 23
@@ -79,6 +85,8 @@
79#define LINE2L_2_HPLOUT_VOL 45 85#define LINE2L_2_HPLOUT_VOL 45
80#define LINE2R_2_HPROUT_VOL 62 86#define LINE2R_2_HPROUT_VOL 62
81#define PGAL_2_HPLOUT_VOL 46 87#define PGAL_2_HPLOUT_VOL 46
88#define PGAL_2_HPROUT_VOL 60
89#define PGAR_2_HPLOUT_VOL 49
82#define PGAR_2_HPROUT_VOL 63 90#define PGAR_2_HPROUT_VOL 63
83#define DACL1_2_HPLOUT_VOL 47 91#define DACL1_2_HPLOUT_VOL 47
84#define DACR1_2_HPROUT_VOL 64 92#define DACR1_2_HPROUT_VOL 64
@@ -88,6 +96,8 @@
88#define LINE2L_2_HPLCOM_VOL 52 96#define LINE2L_2_HPLCOM_VOL 52
89#define LINE2R_2_HPRCOM_VOL 69 97#define LINE2R_2_HPRCOM_VOL 69
90#define PGAL_2_HPLCOM_VOL 53 98#define PGAL_2_HPLCOM_VOL 53
99#define PGAR_2_HPLCOM_VOL 56
100#define PGAL_2_HPRCOM_VOL 67
91#define PGAR_2_HPRCOM_VOL 70 101#define PGAR_2_HPRCOM_VOL 70
92#define DACL1_2_HPLCOM_VOL 54 102#define DACL1_2_HPLCOM_VOL 54
93#define DACR1_2_HPRCOM_VOL 71 103#define DACR1_2_HPRCOM_VOL 71
@@ -103,11 +113,17 @@
103#define MONOLOPM_CTRL 79 113#define MONOLOPM_CTRL 79
104/* Line Output Plus/Minus control registers */ 114/* Line Output Plus/Minus control registers */
105#define LINE2L_2_LLOPM_VOL 80 115#define LINE2L_2_LLOPM_VOL 80
116#define LINE2L_2_RLOPM_VOL 87
117#define LINE2R_2_LLOPM_VOL 83
106#define LINE2R_2_RLOPM_VOL 90 118#define LINE2R_2_RLOPM_VOL 90
107#define PGAL_2_LLOPM_VOL 81 119#define PGAL_2_LLOPM_VOL 81
120#define PGAL_2_RLOPM_VOL 88
121#define PGAR_2_LLOPM_VOL 84
108#define PGAR_2_RLOPM_VOL 91 122#define PGAR_2_RLOPM_VOL 91
109#define DACL1_2_LLOPM_VOL 82 123#define DACL1_2_LLOPM_VOL 82
124#define DACL1_2_RLOPM_VOL 89
110#define DACR1_2_RLOPM_VOL 92 125#define DACR1_2_RLOPM_VOL 92
126#define DACR1_2_LLOPM_VOL 85
111#define LLOPM_CTRL 86 127#define LLOPM_CTRL 86
112#define RLOPM_CTRL 93 128#define RLOPM_CTRL 93
113/* GPIO/IRQ registers */ 129/* GPIO/IRQ registers */
@@ -221,7 +237,49 @@ enum {
221 237
222void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state); 238void aic3x_set_gpio(struct snd_soc_codec *codec, int gpio, int state);
223int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio); 239int aic3x_get_gpio(struct snd_soc_codec *codec, int gpio);
240
241/* headset detection / button API */
242
243/* The AIC3x supports detection of stereo headsets (GND + left + right signal)
244 * and cellular headsets (GND + speaker output + microphone input).
245 * It is recommended to enable MIC bias for this function to work properly.
246 * For more information, please refer to the datasheet. */
247enum {
248 AIC3X_HEADSET_DETECT_OFF = 0,
249 AIC3X_HEADSET_DETECT_STEREO = 1,
250 AIC3X_HEADSET_DETECT_CELLULAR = 2,
251 AIC3X_HEADSET_DETECT_BOTH = 3
252};
253
254enum {
255 AIC3X_HEADSET_DEBOUNCE_16MS = 0,
256 AIC3X_HEADSET_DEBOUNCE_32MS = 1,
257 AIC3X_HEADSET_DEBOUNCE_64MS = 2,
258 AIC3X_HEADSET_DEBOUNCE_128MS = 3,
259 AIC3X_HEADSET_DEBOUNCE_256MS = 4,
260 AIC3X_HEADSET_DEBOUNCE_512MS = 5
261};
262
263enum {
264 AIC3X_BUTTON_DEBOUNCE_0MS = 0,
265 AIC3X_BUTTON_DEBOUNCE_8MS = 1,
266 AIC3X_BUTTON_DEBOUNCE_16MS = 2,
267 AIC3X_BUTTON_DEBOUNCE_32MS = 3
268};
269
270#define AIC3X_HEADSET_DETECT_ENABLED 0x80
271#define AIC3X_HEADSET_DETECT_SHIFT 5
272#define AIC3X_HEADSET_DETECT_MASK 3
273#define AIC3X_HEADSET_DEBOUNCE_SHIFT 2
274#define AIC3X_HEADSET_DEBOUNCE_MASK 7
275#define AIC3X_BUTTON_DEBOUNCE_SHIFT 0
276#define AIC3X_BUTTON_DEBOUNCE_MASK 3
277
278/* see the enums above for valid parameters to this function */
279void aic3x_set_headset_detection(struct snd_soc_codec *codec, int detect,
280 int headset_debounce, int button_debounce);
224int aic3x_headset_detected(struct snd_soc_codec *codec); 281int aic3x_headset_detected(struct snd_soc_codec *codec);
282int aic3x_button_pressed(struct snd_soc_codec *codec);
225 283
226struct aic3x_setup_data { 284struct aic3x_setup_data {
227 int i2c_bus; 285 int i2c_bus;
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
new file mode 100644
index 000000000000..51848880504a
--- /dev/null
+++ b/sound/soc/codecs/twl4030.c
@@ -0,0 +1,1317 @@
1/*
2 * ALSA SoC TWL4030 codec driver
3 *
4 * Author: Steve Sakoman, <steve@sakoman.com>
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/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/pm.h>
27#include <linux/i2c.h>
28#include <linux/platform_device.h>
29#include <linux/i2c/twl4030.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/pcm_params.h>
33#include <sound/soc.h>
34#include <sound/soc-dapm.h>
35#include <sound/initval.h>
36#include <sound/tlv.h>
37
38#include "twl4030.h"
39
40/*
41 * twl4030 register cache & default register settings
42 */
43static const u8 twl4030_reg[TWL4030_CACHEREGNUM] = {
44 0x00, /* this register not used */
45 0x93, /* REG_CODEC_MODE (0x1) */
46 0xc3, /* REG_OPTION (0x2) */
47 0x00, /* REG_UNKNOWN (0x3) */
48 0x00, /* REG_MICBIAS_CTL (0x4) */
49 0x20, /* REG_ANAMICL (0x5) */
50 0x00, /* REG_ANAMICR (0x6) */
51 0x00, /* REG_AVADC_CTL (0x7) */
52 0x00, /* REG_ADCMICSEL (0x8) */
53 0x00, /* REG_DIGMIXING (0x9) */
54 0x0c, /* REG_ATXL1PGA (0xA) */
55 0x0c, /* REG_ATXR1PGA (0xB) */
56 0x00, /* REG_AVTXL2PGA (0xC) */
57 0x00, /* REG_AVTXR2PGA (0xD) */
58 0x01, /* REG_AUDIO_IF (0xE) */
59 0x00, /* REG_VOICE_IF (0xF) */
60 0x00, /* REG_ARXR1PGA (0x10) */
61 0x00, /* REG_ARXL1PGA (0x11) */
62 0x6c, /* REG_ARXR2PGA (0x12) */
63 0x6c, /* REG_ARXL2PGA (0x13) */
64 0x00, /* REG_VRXPGA (0x14) */
65 0x00, /* REG_VSTPGA (0x15) */
66 0x00, /* REG_VRX2ARXPGA (0x16) */
67 0x0c, /* REG_AVDAC_CTL (0x17) */
68 0x00, /* REG_ARX2VTXPGA (0x18) */
69 0x00, /* REG_ARXL1_APGA_CTL (0x19) */
70 0x00, /* REG_ARXR1_APGA_CTL (0x1A) */
71 0x4b, /* REG_ARXL2_APGA_CTL (0x1B) */
72 0x4b, /* REG_ARXR2_APGA_CTL (0x1C) */
73 0x00, /* REG_ATX2ARXPGA (0x1D) */
74 0x00, /* REG_BT_IF (0x1E) */
75 0x00, /* REG_BTPGA (0x1F) */
76 0x00, /* REG_BTSTPGA (0x20) */
77 0x00, /* REG_EAR_CTL (0x21) */
78 0x24, /* REG_HS_SEL (0x22) */
79 0x0a, /* REG_HS_GAIN_SET (0x23) */
80 0x00, /* REG_HS_POPN_SET (0x24) */
81 0x00, /* REG_PREDL_CTL (0x25) */
82 0x00, /* REG_PREDR_CTL (0x26) */
83 0x00, /* REG_PRECKL_CTL (0x27) */
84 0x00, /* REG_PRECKR_CTL (0x28) */
85 0x00, /* REG_HFL_CTL (0x29) */
86 0x00, /* REG_HFR_CTL (0x2A) */
87 0x00, /* REG_ALC_CTL (0x2B) */
88 0x00, /* REG_ALC_SET1 (0x2C) */
89 0x00, /* REG_ALC_SET2 (0x2D) */
90 0x00, /* REG_BOOST_CTL (0x2E) */
91 0x00, /* REG_SOFTVOL_CTL (0x2F) */
92 0x00, /* REG_DTMF_FREQSEL (0x30) */
93 0x00, /* REG_DTMF_TONEXT1H (0x31) */
94 0x00, /* REG_DTMF_TONEXT1L (0x32) */
95 0x00, /* REG_DTMF_TONEXT2H (0x33) */
96 0x00, /* REG_DTMF_TONEXT2L (0x34) */
97 0x00, /* REG_DTMF_TONOFF (0x35) */
98 0x00, /* REG_DTMF_WANONOFF (0x36) */
99 0x00, /* REG_I2S_RX_SCRAMBLE_H (0x37) */
100 0x00, /* REG_I2S_RX_SCRAMBLE_M (0x38) */
101 0x00, /* REG_I2S_RX_SCRAMBLE_L (0x39) */
102 0x16, /* REG_APLL_CTL (0x3A) */
103 0x00, /* REG_DTMF_CTL (0x3B) */
104 0x00, /* REG_DTMF_PGA_CTL2 (0x3C) */
105 0x00, /* REG_DTMF_PGA_CTL1 (0x3D) */
106 0x00, /* REG_MISC_SET_1 (0x3E) */
107 0x00, /* REG_PCMBTMUX (0x3F) */
108 0x00, /* not used (0x40) */
109 0x00, /* not used (0x41) */
110 0x00, /* not used (0x42) */
111 0x00, /* REG_RX_PATH_SEL (0x43) */
112 0x00, /* REG_VDL_APGA_CTL (0x44) */
113 0x00, /* REG_VIBRA_CTL (0x45) */
114 0x00, /* REG_VIBRA_SET (0x46) */
115 0x00, /* REG_VIBRA_PWM_SET (0x47) */
116 0x00, /* REG_ANAMIC_GAIN (0x48) */
117 0x00, /* REG_MISC_SET_2 (0x49) */
118};
119
120/*
121 * read twl4030 register cache
122 */
123static inline unsigned int twl4030_read_reg_cache(struct snd_soc_codec *codec,
124 unsigned int reg)
125{
126 u8 *cache = codec->reg_cache;
127
128 return cache[reg];
129}
130
131/*
132 * write twl4030 register cache
133 */
134static inline void twl4030_write_reg_cache(struct snd_soc_codec *codec,
135 u8 reg, u8 value)
136{
137 u8 *cache = codec->reg_cache;
138
139 if (reg >= TWL4030_CACHEREGNUM)
140 return;
141 cache[reg] = value;
142}
143
144/*
145 * write to the twl4030 register space
146 */
147static int twl4030_write(struct snd_soc_codec *codec,
148 unsigned int reg, unsigned int value)
149{
150 twl4030_write_reg_cache(codec, reg, value);
151 return twl4030_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg);
152}
153
154static void twl4030_clear_codecpdz(struct snd_soc_codec *codec)
155{
156 u8 mode;
157
158 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
159 twl4030_write(codec, TWL4030_REG_CODEC_MODE,
160 mode & ~TWL4030_CODECPDZ);
161
162 /* REVISIT: this delay is present in TI sample drivers */
163 /* but there seems to be no TRM requirement for it */
164 udelay(10);
165}
166
167static void twl4030_set_codecpdz(struct snd_soc_codec *codec)
168{
169 u8 mode;
170
171 mode = twl4030_read_reg_cache(codec, TWL4030_REG_CODEC_MODE);
172 twl4030_write(codec, TWL4030_REG_CODEC_MODE,
173 mode | TWL4030_CODECPDZ);
174
175 /* REVISIT: this delay is present in TI sample drivers */
176 /* but there seems to be no TRM requirement for it */
177 udelay(10);
178}
179
180static void twl4030_init_chip(struct snd_soc_codec *codec)
181{
182 int i;
183
184 /* clear CODECPDZ prior to setting register defaults */
185 twl4030_clear_codecpdz(codec);
186
187 /* set all audio section registers to reasonable defaults */
188 for (i = TWL4030_REG_OPTION; i <= TWL4030_REG_MISC_SET_2; i++)
189 twl4030_write(codec, i, twl4030_reg[i]);
190
191}
192
193/* Earpiece */
194static const char *twl4030_earpiece_texts[] =
195 {"Off", "DACL1", "DACL2", "Invalid", "DACR1"};
196
197static const struct soc_enum twl4030_earpiece_enum =
198 SOC_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1,
199 ARRAY_SIZE(twl4030_earpiece_texts),
200 twl4030_earpiece_texts);
201
202static const struct snd_kcontrol_new twl4030_dapm_earpiece_control =
203SOC_DAPM_ENUM("Route", twl4030_earpiece_enum);
204
205/* PreDrive Left */
206static const char *twl4030_predrivel_texts[] =
207 {"Off", "DACL1", "DACL2", "Invalid", "DACR2"};
208
209static const struct soc_enum twl4030_predrivel_enum =
210 SOC_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1,
211 ARRAY_SIZE(twl4030_predrivel_texts),
212 twl4030_predrivel_texts);
213
214static const struct snd_kcontrol_new twl4030_dapm_predrivel_control =
215SOC_DAPM_ENUM("Route", twl4030_predrivel_enum);
216
217/* PreDrive Right */
218static const char *twl4030_predriver_texts[] =
219 {"Off", "DACR1", "DACR2", "Invalid", "DACL2"};
220
221static const struct soc_enum twl4030_predriver_enum =
222 SOC_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1,
223 ARRAY_SIZE(twl4030_predriver_texts),
224 twl4030_predriver_texts);
225
226static const struct snd_kcontrol_new twl4030_dapm_predriver_control =
227SOC_DAPM_ENUM("Route", twl4030_predriver_enum);
228
229/* Headset Left */
230static const char *twl4030_hsol_texts[] =
231 {"Off", "DACL1", "DACL2"};
232
233static const struct soc_enum twl4030_hsol_enum =
234 SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 1,
235 ARRAY_SIZE(twl4030_hsol_texts),
236 twl4030_hsol_texts);
237
238static const struct snd_kcontrol_new twl4030_dapm_hsol_control =
239SOC_DAPM_ENUM("Route", twl4030_hsol_enum);
240
241/* Headset Right */
242static const char *twl4030_hsor_texts[] =
243 {"Off", "DACR1", "DACR2"};
244
245static const struct soc_enum twl4030_hsor_enum =
246 SOC_ENUM_SINGLE(TWL4030_REG_HS_SEL, 4,
247 ARRAY_SIZE(twl4030_hsor_texts),
248 twl4030_hsor_texts);
249
250static const struct snd_kcontrol_new twl4030_dapm_hsor_control =
251SOC_DAPM_ENUM("Route", twl4030_hsor_enum);
252
253/* Carkit Left */
254static const char *twl4030_carkitl_texts[] =
255 {"Off", "DACL1", "DACL2"};
256
257static const struct soc_enum twl4030_carkitl_enum =
258 SOC_ENUM_SINGLE(TWL4030_REG_PRECKL_CTL, 1,
259 ARRAY_SIZE(twl4030_carkitl_texts),
260 twl4030_carkitl_texts);
261
262static const struct snd_kcontrol_new twl4030_dapm_carkitl_control =
263SOC_DAPM_ENUM("Route", twl4030_carkitl_enum);
264
265/* Carkit Right */
266static const char *twl4030_carkitr_texts[] =
267 {"Off", "DACR1", "DACR2"};
268
269static const struct soc_enum twl4030_carkitr_enum =
270 SOC_ENUM_SINGLE(TWL4030_REG_PRECKR_CTL, 1,
271 ARRAY_SIZE(twl4030_carkitr_texts),
272 twl4030_carkitr_texts);
273
274static const struct snd_kcontrol_new twl4030_dapm_carkitr_control =
275SOC_DAPM_ENUM("Route", twl4030_carkitr_enum);
276
277/* Handsfree Left */
278static const char *twl4030_handsfreel_texts[] =
279 {"Voice", "DACL1", "DACL2", "DACR2"};
280
281static const struct soc_enum twl4030_handsfreel_enum =
282 SOC_ENUM_SINGLE(TWL4030_REG_HFL_CTL, 0,
283 ARRAY_SIZE(twl4030_handsfreel_texts),
284 twl4030_handsfreel_texts);
285
286static const struct snd_kcontrol_new twl4030_dapm_handsfreel_control =
287SOC_DAPM_ENUM("Route", twl4030_handsfreel_enum);
288
289/* Handsfree Right */
290static const char *twl4030_handsfreer_texts[] =
291 {"Voice", "DACR1", "DACR2", "DACL2"};
292
293static const struct soc_enum twl4030_handsfreer_enum =
294 SOC_ENUM_SINGLE(TWL4030_REG_HFR_CTL, 0,
295 ARRAY_SIZE(twl4030_handsfreer_texts),
296 twl4030_handsfreer_texts);
297
298static const struct snd_kcontrol_new twl4030_dapm_handsfreer_control =
299SOC_DAPM_ENUM("Route", twl4030_handsfreer_enum);
300
301static int outmixer_event(struct snd_soc_dapm_widget *w,
302 struct snd_kcontrol *kcontrol, int event)
303{
304 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
305 int ret = 0;
306 int val;
307
308 switch (e->reg) {
309 case TWL4030_REG_PREDL_CTL:
310 case TWL4030_REG_PREDR_CTL:
311 case TWL4030_REG_EAR_CTL:
312 val = w->value >> e->shift_l;
313 if (val == 3) {
314 printk(KERN_WARNING
315 "Invalid MUX setting for register 0x%02x (%d)\n",
316 e->reg, val);
317 ret = -1;
318 }
319 break;
320 }
321
322 return ret;
323}
324
325static int handsfree_event(struct snd_soc_dapm_widget *w,
326 struct snd_kcontrol *kcontrol, int event)
327{
328 struct soc_enum *e = (struct soc_enum *)w->kcontrols->private_value;
329 unsigned char hs_ctl;
330
331 hs_ctl = twl4030_read_reg_cache(w->codec, e->reg);
332
333 if (hs_ctl & TWL4030_HF_CTL_REF_EN) {
334 hs_ctl |= TWL4030_HF_CTL_RAMP_EN;
335 twl4030_write(w->codec, e->reg, hs_ctl);
336 hs_ctl |= TWL4030_HF_CTL_LOOP_EN;
337 twl4030_write(w->codec, e->reg, hs_ctl);
338 hs_ctl |= TWL4030_HF_CTL_HB_EN;
339 twl4030_write(w->codec, e->reg, hs_ctl);
340 } else {
341 hs_ctl &= ~(TWL4030_HF_CTL_RAMP_EN | TWL4030_HF_CTL_LOOP_EN
342 | TWL4030_HF_CTL_HB_EN);
343 twl4030_write(w->codec, e->reg, hs_ctl);
344 }
345
346 return 0;
347}
348
349/*
350 * Some of the gain controls in TWL (mostly those which are associated with
351 * the outputs) are implemented in an interesting way:
352 * 0x0 : Power down (mute)
353 * 0x1 : 6dB
354 * 0x2 : 0 dB
355 * 0x3 : -6 dB
356 * Inverting not going to help with these.
357 * Custom volsw and volsw_2r get/put functions to handle these gain bits.
358 */
359#define SOC_DOUBLE_TLV_TWL4030(xname, xreg, shift_left, shift_right, xmax,\
360 xinvert, tlv_array) \
361{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
362 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
363 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
364 .tlv.p = (tlv_array), \
365 .info = snd_soc_info_volsw, \
366 .get = snd_soc_get_volsw_twl4030, \
367 .put = snd_soc_put_volsw_twl4030, \
368 .private_value = (unsigned long)&(struct soc_mixer_control) \
369 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
370 .max = xmax, .invert = xinvert} }
371#define SOC_DOUBLE_R_TLV_TWL4030(xname, reg_left, reg_right, xshift, xmax,\
372 xinvert, tlv_array) \
373{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
374 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
375 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
376 .tlv.p = (tlv_array), \
377 .info = snd_soc_info_volsw_2r, \
378 .get = snd_soc_get_volsw_r2_twl4030,\
379 .put = snd_soc_put_volsw_r2_twl4030, \
380 .private_value = (unsigned long)&(struct soc_mixer_control) \
381 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
382 .rshift = xshift, .max = xmax, .invert = xinvert} }
383#define SOC_SINGLE_TLV_TWL4030(xname, xreg, xshift, xmax, xinvert, tlv_array) \
384 SOC_DOUBLE_TLV_TWL4030(xname, xreg, xshift, xshift, xmax, \
385 xinvert, tlv_array)
386
387static int snd_soc_get_volsw_twl4030(struct snd_kcontrol *kcontrol,
388 struct snd_ctl_elem_value *ucontrol)
389{
390 struct soc_mixer_control *mc =
391 (struct soc_mixer_control *)kcontrol->private_value;
392 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
393 unsigned int reg = mc->reg;
394 unsigned int shift = mc->shift;
395 unsigned int rshift = mc->rshift;
396 int max = mc->max;
397 int mask = (1 << fls(max)) - 1;
398
399 ucontrol->value.integer.value[0] =
400 (snd_soc_read(codec, reg) >> shift) & mask;
401 if (ucontrol->value.integer.value[0])
402 ucontrol->value.integer.value[0] =
403 max + 1 - ucontrol->value.integer.value[0];
404
405 if (shift != rshift) {
406 ucontrol->value.integer.value[1] =
407 (snd_soc_read(codec, reg) >> rshift) & mask;
408 if (ucontrol->value.integer.value[1])
409 ucontrol->value.integer.value[1] =
410 max + 1 - ucontrol->value.integer.value[1];
411 }
412
413 return 0;
414}
415
416static int snd_soc_put_volsw_twl4030(struct snd_kcontrol *kcontrol,
417 struct snd_ctl_elem_value *ucontrol)
418{
419 struct soc_mixer_control *mc =
420 (struct soc_mixer_control *)kcontrol->private_value;
421 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
422 unsigned int reg = mc->reg;
423 unsigned int shift = mc->shift;
424 unsigned int rshift = mc->rshift;
425 int max = mc->max;
426 int mask = (1 << fls(max)) - 1;
427 unsigned short val, val2, val_mask;
428
429 val = (ucontrol->value.integer.value[0] & mask);
430
431 val_mask = mask << shift;
432 if (val)
433 val = max + 1 - val;
434 val = val << shift;
435 if (shift != rshift) {
436 val2 = (ucontrol->value.integer.value[1] & mask);
437 val_mask |= mask << rshift;
438 if (val2)
439 val2 = max + 1 - val2;
440 val |= val2 << rshift;
441 }
442 return snd_soc_update_bits(codec, reg, val_mask, val);
443}
444
445static int snd_soc_get_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
446 struct snd_ctl_elem_value *ucontrol)
447{
448 struct soc_mixer_control *mc =
449 (struct soc_mixer_control *)kcontrol->private_value;
450 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
451 unsigned int reg = mc->reg;
452 unsigned int reg2 = mc->rreg;
453 unsigned int shift = mc->shift;
454 int max = mc->max;
455 int mask = (1<<fls(max))-1;
456
457 ucontrol->value.integer.value[0] =
458 (snd_soc_read(codec, reg) >> shift) & mask;
459 ucontrol->value.integer.value[1] =
460 (snd_soc_read(codec, reg2) >> shift) & mask;
461
462 if (ucontrol->value.integer.value[0])
463 ucontrol->value.integer.value[0] =
464 max + 1 - ucontrol->value.integer.value[0];
465 if (ucontrol->value.integer.value[1])
466 ucontrol->value.integer.value[1] =
467 max + 1 - ucontrol->value.integer.value[1];
468
469 return 0;
470}
471
472static int snd_soc_put_volsw_r2_twl4030(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_value *ucontrol)
474{
475 struct soc_mixer_control *mc =
476 (struct soc_mixer_control *)kcontrol->private_value;
477 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
478 unsigned int reg = mc->reg;
479 unsigned int reg2 = mc->rreg;
480 unsigned int shift = mc->shift;
481 int max = mc->max;
482 int mask = (1 << fls(max)) - 1;
483 int err;
484 unsigned short val, val2, val_mask;
485
486 val_mask = mask << shift;
487 val = (ucontrol->value.integer.value[0] & mask);
488 val2 = (ucontrol->value.integer.value[1] & mask);
489
490 if (val)
491 val = max + 1 - val;
492 if (val2)
493 val2 = max + 1 - val2;
494
495 val = val << shift;
496 val2 = val2 << shift;
497
498 err = snd_soc_update_bits(codec, reg, val_mask, val);
499 if (err < 0)
500 return err;
501
502 err = snd_soc_update_bits(codec, reg2, val_mask, val2);
503 return err;
504}
505
506static int twl4030_get_left_input(struct snd_kcontrol *kcontrol,
507 struct snd_ctl_elem_value *ucontrol)
508{
509 struct snd_soc_codec *codec = kcontrol->private_data;
510 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
511 int result = 0;
512
513 /* one bit must be set a time */
514 reg &= TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
515 | TWL4030_MAINMIC_EN;
516 if (reg != 0) {
517 result++;
518 while ((reg & 1) == 0) {
519 result++;
520 reg >>= 1;
521 }
522 }
523
524 ucontrol->value.integer.value[0] = result;
525 return 0;
526}
527
528static int twl4030_put_left_input(struct snd_kcontrol *kcontrol,
529 struct snd_ctl_elem_value *ucontrol)
530{
531 struct snd_soc_codec *codec = kcontrol->private_data;
532 int value = ucontrol->value.integer.value[0];
533 u8 anamicl, micbias, avadc_ctl;
534
535 anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
536 anamicl &= ~(TWL4030_CKMIC_EN | TWL4030_AUXL_EN | TWL4030_HSMIC_EN
537 | TWL4030_MAINMIC_EN);
538 micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
539 micbias &= ~(TWL4030_HSMICBIAS_EN | TWL4030_MICBIAS1_EN);
540 avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);
541
542 switch (value) {
543 case 1:
544 anamicl |= TWL4030_MAINMIC_EN;
545 micbias |= TWL4030_MICBIAS1_EN;
546 break;
547 case 2:
548 anamicl |= TWL4030_HSMIC_EN;
549 micbias |= TWL4030_HSMICBIAS_EN;
550 break;
551 case 3:
552 anamicl |= TWL4030_AUXL_EN;
553 break;
554 case 4:
555 anamicl |= TWL4030_CKMIC_EN;
556 break;
557 default:
558 break;
559 }
560
561 /* If some input is selected, enable amp and ADC */
562 if (value != 0) {
563 anamicl |= TWL4030_MICAMPL_EN;
564 avadc_ctl |= TWL4030_ADCL_EN;
565 } else {
566 anamicl &= ~TWL4030_MICAMPL_EN;
567 avadc_ctl &= ~TWL4030_ADCL_EN;
568 }
569
570 twl4030_write(codec, TWL4030_REG_ANAMICL, anamicl);
571 twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
572 twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);
573
574 return 1;
575}
576
577static int twl4030_get_right_input(struct snd_kcontrol *kcontrol,
578 struct snd_ctl_elem_value *ucontrol)
579{
580 struct snd_soc_codec *codec = kcontrol->private_data;
581 u8 reg = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
582 int value = 0;
583
584 reg &= TWL4030_SUBMIC_EN|TWL4030_AUXR_EN;
585 switch (reg) {
586 case TWL4030_SUBMIC_EN:
587 value = 1;
588 break;
589 case TWL4030_AUXR_EN:
590 value = 2;
591 break;
592 default:
593 break;
594 }
595
596 ucontrol->value.integer.value[0] = value;
597 return 0;
598}
599
600static int twl4030_put_right_input(struct snd_kcontrol *kcontrol,
601 struct snd_ctl_elem_value *ucontrol)
602{
603 struct snd_soc_codec *codec = kcontrol->private_data;
604 int value = ucontrol->value.integer.value[0];
605 u8 anamicr, micbias, avadc_ctl;
606
607 anamicr = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICR);
608 anamicr &= ~(TWL4030_SUBMIC_EN|TWL4030_AUXR_EN);
609 micbias = twl4030_read_reg_cache(codec, TWL4030_REG_MICBIAS_CTL);
610 micbias &= ~TWL4030_MICBIAS2_EN;
611 avadc_ctl = twl4030_read_reg_cache(codec, TWL4030_REG_AVADC_CTL);
612
613 switch (value) {
614 case 1:
615 anamicr |= TWL4030_SUBMIC_EN;
616 micbias |= TWL4030_MICBIAS2_EN;
617 break;
618 case 2:
619 anamicr |= TWL4030_AUXR_EN;
620 break;
621 default:
622 break;
623 }
624
625 if (value != 0) {
626 anamicr |= TWL4030_MICAMPR_EN;
627 avadc_ctl |= TWL4030_ADCR_EN;
628 } else {
629 anamicr &= ~TWL4030_MICAMPR_EN;
630 avadc_ctl &= ~TWL4030_ADCR_EN;
631 }
632
633 twl4030_write(codec, TWL4030_REG_ANAMICR, anamicr);
634 twl4030_write(codec, TWL4030_REG_MICBIAS_CTL, micbias);
635 twl4030_write(codec, TWL4030_REG_AVADC_CTL, avadc_ctl);
636
637 return 1;
638}
639
640static const char *twl4030_left_in_sel[] = {
641 "None",
642 "Main Mic",
643 "Headset Mic",
644 "Line In",
645 "Carkit Mic",
646};
647
648static const char *twl4030_right_in_sel[] = {
649 "None",
650 "Sub Mic",
651 "Line In",
652};
653
654static const struct soc_enum twl4030_left_input_mux =
655 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_left_in_sel),
656 twl4030_left_in_sel);
657
658static const struct soc_enum twl4030_right_input_mux =
659 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(twl4030_right_in_sel),
660 twl4030_right_in_sel);
661
662/*
663 * FGAIN volume control:
664 * from -62 to 0 dB in 1 dB steps (mute instead of -63 dB)
665 */
666static DECLARE_TLV_DB_SCALE(digital_fine_tlv, -6300, 100, 1);
667
668/*
669 * CGAIN volume control:
670 * 0 dB to 12 dB in 6 dB steps
671 * value 2 and 3 means 12 dB
672 */
673static DECLARE_TLV_DB_SCALE(digital_coarse_tlv, 0, 600, 0);
674
675/*
676 * Analog playback gain
677 * -24 dB to 12 dB in 2 dB steps
678 */
679static DECLARE_TLV_DB_SCALE(analog_tlv, -2400, 200, 0);
680
681/*
682 * Gain controls tied to outputs
683 * -6 dB to 6 dB in 6 dB steps (mute instead of -12)
684 */
685static DECLARE_TLV_DB_SCALE(output_tvl, -1200, 600, 1);
686
687/*
688 * Capture gain after the ADCs
689 * from 0 dB to 31 dB in 1 dB steps
690 */
691static DECLARE_TLV_DB_SCALE(digital_capture_tlv, 0, 100, 0);
692
693/*
694 * Gain control for input amplifiers
695 * 0 dB to 30 dB in 6 dB steps
696 */
697static DECLARE_TLV_DB_SCALE(input_gain_tlv, 0, 600, 0);
698
699static const struct snd_kcontrol_new twl4030_snd_controls[] = {
700 /* Common playback gain controls */
701 SOC_DOUBLE_R_TLV("DAC1 Digital Fine Playback Volume",
702 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
703 0, 0x3f, 0, digital_fine_tlv),
704 SOC_DOUBLE_R_TLV("DAC2 Digital Fine Playback Volume",
705 TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
706 0, 0x3f, 0, digital_fine_tlv),
707
708 SOC_DOUBLE_R_TLV("DAC1 Digital Coarse Playback Volume",
709 TWL4030_REG_ARXL1PGA, TWL4030_REG_ARXR1PGA,
710 6, 0x2, 0, digital_coarse_tlv),
711 SOC_DOUBLE_R_TLV("DAC2 Digital Coarse Playback Volume",
712 TWL4030_REG_ARXL2PGA, TWL4030_REG_ARXR2PGA,
713 6, 0x2, 0, digital_coarse_tlv),
714
715 SOC_DOUBLE_R_TLV("DAC1 Analog Playback Volume",
716 TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
717 3, 0x12, 1, analog_tlv),
718 SOC_DOUBLE_R_TLV("DAC2 Analog Playback Volume",
719 TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
720 3, 0x12, 1, analog_tlv),
721 SOC_DOUBLE_R("DAC1 Analog Playback Switch",
722 TWL4030_REG_ARXL1_APGA_CTL, TWL4030_REG_ARXR1_APGA_CTL,
723 1, 1, 0),
724 SOC_DOUBLE_R("DAC2 Analog Playback Switch",
725 TWL4030_REG_ARXL2_APGA_CTL, TWL4030_REG_ARXR2_APGA_CTL,
726 1, 1, 0),
727
728 /* Separate output gain controls */
729 SOC_DOUBLE_R_TLV_TWL4030("PreDriv Playback Volume",
730 TWL4030_REG_PREDL_CTL, TWL4030_REG_PREDR_CTL,
731 4, 3, 0, output_tvl),
732
733 SOC_DOUBLE_TLV_TWL4030("Headset Playback Volume",
734 TWL4030_REG_HS_GAIN_SET, 0, 2, 3, 0, output_tvl),
735
736 SOC_DOUBLE_R_TLV_TWL4030("Carkit Playback Volume",
737 TWL4030_REG_PRECKL_CTL, TWL4030_REG_PRECKR_CTL,
738 4, 3, 0, output_tvl),
739
740 SOC_SINGLE_TLV_TWL4030("Earpiece Playback Volume",
741 TWL4030_REG_EAR_CTL, 4, 3, 0, output_tvl),
742
743 /* Common capture gain controls */
744 SOC_DOUBLE_R_TLV("Capture Volume",
745 TWL4030_REG_ATXL1PGA, TWL4030_REG_ATXR1PGA,
746 0, 0x1f, 0, digital_capture_tlv),
747
748 SOC_DOUBLE_TLV("Input Boost Volume", TWL4030_REG_ANAMIC_GAIN,
749 0, 3, 5, 0, input_gain_tlv),
750
751 /* Input source controls */
752 SOC_ENUM_EXT("Left Input Source", twl4030_left_input_mux,
753 twl4030_get_left_input, twl4030_put_left_input),
754 SOC_ENUM_EXT("Right Input Source", twl4030_right_input_mux,
755 twl4030_get_right_input, twl4030_put_right_input),
756};
757
758/* add non dapm controls */
759static int twl4030_add_controls(struct snd_soc_codec *codec)
760{
761 int err, i;
762
763 for (i = 0; i < ARRAY_SIZE(twl4030_snd_controls); i++) {
764 err = snd_ctl_add(codec->card,
765 snd_soc_cnew(&twl4030_snd_controls[i],
766 codec, NULL));
767 if (err < 0)
768 return err;
769 }
770
771 return 0;
772}
773
774static const struct snd_soc_dapm_widget twl4030_dapm_widgets[] = {
775 SND_SOC_DAPM_INPUT("INL"),
776 SND_SOC_DAPM_INPUT("INR"),
777
778 SND_SOC_DAPM_OUTPUT("OUTL"),
779 SND_SOC_DAPM_OUTPUT("OUTR"),
780 SND_SOC_DAPM_OUTPUT("EARPIECE"),
781 SND_SOC_DAPM_OUTPUT("PREDRIVEL"),
782 SND_SOC_DAPM_OUTPUT("PREDRIVER"),
783 SND_SOC_DAPM_OUTPUT("HSOL"),
784 SND_SOC_DAPM_OUTPUT("HSOR"),
785 SND_SOC_DAPM_OUTPUT("CARKITL"),
786 SND_SOC_DAPM_OUTPUT("CARKITR"),
787 SND_SOC_DAPM_OUTPUT("HFL"),
788 SND_SOC_DAPM_OUTPUT("HFR"),
789
790 /* DACs */
791 SND_SOC_DAPM_DAC("DAC Right1", "Right Front Playback",
792 TWL4030_REG_AVDAC_CTL, 0, 0),
793 SND_SOC_DAPM_DAC("DAC Left1", "Left Front Playback",
794 TWL4030_REG_AVDAC_CTL, 1, 0),
795 SND_SOC_DAPM_DAC("DAC Right2", "Right Rear Playback",
796 TWL4030_REG_AVDAC_CTL, 2, 0),
797 SND_SOC_DAPM_DAC("DAC Left2", "Left Rear Playback",
798 TWL4030_REG_AVDAC_CTL, 3, 0),
799
800 /* Analog PGAs */
801 SND_SOC_DAPM_PGA("ARXR1_APGA", TWL4030_REG_ARXR1_APGA_CTL,
802 0, 0, NULL, 0),
803 SND_SOC_DAPM_PGA("ARXL1_APGA", TWL4030_REG_ARXL1_APGA_CTL,
804 0, 0, NULL, 0),
805 SND_SOC_DAPM_PGA("ARXR2_APGA", TWL4030_REG_ARXR2_APGA_CTL,
806 0, 0, NULL, 0),
807 SND_SOC_DAPM_PGA("ARXL2_APGA", TWL4030_REG_ARXL2_APGA_CTL,
808 0, 0, NULL, 0),
809
810 /* Output MUX controls */
811 /* Earpiece */
812 SND_SOC_DAPM_MUX_E("Earpiece Mux", SND_SOC_NOPM, 0, 0,
813 &twl4030_dapm_earpiece_control, outmixer_event,
814 SND_SOC_DAPM_PRE_REG),
815 /* PreDrivL/R */
816 SND_SOC_DAPM_MUX_E("PredriveL Mux", SND_SOC_NOPM, 0, 0,
817 &twl4030_dapm_predrivel_control, outmixer_event,
818 SND_SOC_DAPM_PRE_REG),
819 SND_SOC_DAPM_MUX_E("PredriveR Mux", SND_SOC_NOPM, 0, 0,
820 &twl4030_dapm_predriver_control, outmixer_event,
821 SND_SOC_DAPM_PRE_REG),
822 /* HeadsetL/R */
823 SND_SOC_DAPM_MUX("HeadsetL Mux", SND_SOC_NOPM, 0, 0,
824 &twl4030_dapm_hsol_control),
825 SND_SOC_DAPM_MUX("HeadsetR Mux", SND_SOC_NOPM, 0, 0,
826 &twl4030_dapm_hsor_control),
827 /* CarkitL/R */
828 SND_SOC_DAPM_MUX("CarkitL Mux", SND_SOC_NOPM, 0, 0,
829 &twl4030_dapm_carkitl_control),
830 SND_SOC_DAPM_MUX("CarkitR Mux", SND_SOC_NOPM, 0, 0,
831 &twl4030_dapm_carkitr_control),
832 /* HandsfreeL/R */
833 SND_SOC_DAPM_MUX_E("HandsfreeL Mux", TWL4030_REG_HFL_CTL, 5, 0,
834 &twl4030_dapm_handsfreel_control, handsfree_event,
835 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
836 SND_SOC_DAPM_MUX_E("HandsfreeR Mux", TWL4030_REG_HFR_CTL, 5, 0,
837 &twl4030_dapm_handsfreer_control, handsfree_event,
838 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
839
840 SND_SOC_DAPM_ADC("ADCL", "Left Capture", SND_SOC_NOPM, 0, 0),
841 SND_SOC_DAPM_ADC("ADCR", "Right Capture", SND_SOC_NOPM, 0, 0),
842};
843
844static const struct snd_soc_dapm_route intercon[] = {
845 {"ARXL1_APGA", NULL, "DAC Left1"},
846 {"ARXR1_APGA", NULL, "DAC Right1"},
847 {"ARXL2_APGA", NULL, "DAC Left2"},
848 {"ARXR2_APGA", NULL, "DAC Right2"},
849
850 /* Internal playback routings */
851 /* Earpiece */
852 {"Earpiece Mux", "DACL1", "ARXL1_APGA"},
853 {"Earpiece Mux", "DACL2", "ARXL2_APGA"},
854 {"Earpiece Mux", "DACR1", "ARXR1_APGA"},
855 /* PreDrivL */
856 {"PredriveL Mux", "DACL1", "ARXL1_APGA"},
857 {"PredriveL Mux", "DACL2", "ARXL2_APGA"},
858 {"PredriveL Mux", "DACR2", "ARXR2_APGA"},
859 /* PreDrivR */
860 {"PredriveR Mux", "DACR1", "ARXR1_APGA"},
861 {"PredriveR Mux", "DACR2", "ARXR2_APGA"},
862 {"PredriveR Mux", "DACL2", "ARXL2_APGA"},
863 /* HeadsetL */
864 {"HeadsetL Mux", "DACL1", "ARXL1_APGA"},
865 {"HeadsetL Mux", "DACL2", "ARXL2_APGA"},
866 /* HeadsetR */
867 {"HeadsetR Mux", "DACR1", "ARXR1_APGA"},
868 {"HeadsetR Mux", "DACR2", "ARXR2_APGA"},
869 /* CarkitL */
870 {"CarkitL Mux", "DACL1", "ARXL1_APGA"},
871 {"CarkitL Mux", "DACL2", "ARXL2_APGA"},
872 /* CarkitR */
873 {"CarkitR Mux", "DACR1", "ARXR1_APGA"},
874 {"CarkitR Mux", "DACR2", "ARXR2_APGA"},
875 /* HandsfreeL */
876 {"HandsfreeL Mux", "DACL1", "ARXL1_APGA"},
877 {"HandsfreeL Mux", "DACL2", "ARXL2_APGA"},
878 {"HandsfreeL Mux", "DACR2", "ARXR2_APGA"},
879 /* HandsfreeR */
880 {"HandsfreeR Mux", "DACR1", "ARXR1_APGA"},
881 {"HandsfreeR Mux", "DACR2", "ARXR2_APGA"},
882 {"HandsfreeR Mux", "DACL2", "ARXL2_APGA"},
883
884 /* outputs */
885 {"OUTL", NULL, "ARXL2_APGA"},
886 {"OUTR", NULL, "ARXR2_APGA"},
887 {"EARPIECE", NULL, "Earpiece Mux"},
888 {"PREDRIVEL", NULL, "PredriveL Mux"},
889 {"PREDRIVER", NULL, "PredriveR Mux"},
890 {"HSOL", NULL, "HeadsetL Mux"},
891 {"HSOR", NULL, "HeadsetR Mux"},
892 {"CARKITL", NULL, "CarkitL Mux"},
893 {"CARKITR", NULL, "CarkitR Mux"},
894 {"HFL", NULL, "HandsfreeL Mux"},
895 {"HFR", NULL, "HandsfreeR Mux"},
896
897 /* inputs */
898 {"ADCL", NULL, "INL"},
899 {"ADCR", NULL, "INR"},
900};
901
902static int twl4030_add_widgets(struct snd_soc_codec *codec)
903{
904 snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets,
905 ARRAY_SIZE(twl4030_dapm_widgets));
906
907 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
908
909 snd_soc_dapm_new_widgets(codec);
910 return 0;
911}
912
913static void twl4030_power_up(struct snd_soc_codec *codec)
914{
915 u8 anamicl, regmisc1, byte, popn;
916 int i = 0;
917
918 /* set CODECPDZ to turn on codec */
919 twl4030_set_codecpdz(codec);
920
921 /* initiate offset cancellation */
922 anamicl = twl4030_read_reg_cache(codec, TWL4030_REG_ANAMICL);
923 twl4030_write(codec, TWL4030_REG_ANAMICL,
924 anamicl | TWL4030_CNCL_OFFSET_START);
925
926 /* wait for offset cancellation to complete */
927 do {
928 /* this takes a little while, so don't slam i2c */
929 udelay(2000);
930 twl4030_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
931 TWL4030_REG_ANAMICL);
932 } while ((i++ < 100) &&
933 ((byte & TWL4030_CNCL_OFFSET_START) ==
934 TWL4030_CNCL_OFFSET_START));
935
936 /* anti-pop when changing analog gain */
937 regmisc1 = twl4030_read_reg_cache(codec, TWL4030_REG_MISC_SET_1);
938 twl4030_write(codec, TWL4030_REG_MISC_SET_1,
939 regmisc1 | TWL4030_SMOOTH_ANAVOL_EN);
940
941 /* toggle CODECPDZ as per TRM */
942 twl4030_clear_codecpdz(codec);
943 twl4030_set_codecpdz(codec);
944
945 /* program anti-pop with bias ramp delay */
946 popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
947 popn &= TWL4030_RAMP_DELAY;
948 popn |= TWL4030_RAMP_DELAY_645MS;
949 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
950 popn |= TWL4030_VMID_EN;
951 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
952
953 /* enable anti-pop ramp */
954 popn |= TWL4030_RAMP_EN;
955 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
956}
957
958static void twl4030_power_down(struct snd_soc_codec *codec)
959{
960 u8 popn;
961
962 /* disable anti-pop ramp */
963 popn = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
964 popn &= ~TWL4030_RAMP_EN;
965 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
966
967 /* disable bias out */
968 popn &= ~TWL4030_VMID_EN;
969 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, popn);
970
971 /* power down */
972 twl4030_clear_codecpdz(codec);
973}
974
975static int twl4030_set_bias_level(struct snd_soc_codec *codec,
976 enum snd_soc_bias_level level)
977{
978 switch (level) {
979 case SND_SOC_BIAS_ON:
980 twl4030_power_up(codec);
981 break;
982 case SND_SOC_BIAS_PREPARE:
983 /* TODO: develop a twl4030_prepare function */
984 break;
985 case SND_SOC_BIAS_STANDBY:
986 /* TODO: develop a twl4030_standby function */
987 twl4030_power_down(codec);
988 break;
989 case SND_SOC_BIAS_OFF:
990 twl4030_power_down(codec);
991 break;
992 }
993 codec->bias_level = level;
994
995 return 0;
996}
997
998static int twl4030_hw_params(struct snd_pcm_substream *substream,
999 struct snd_pcm_hw_params *params,
1000 struct snd_soc_dai *dai)
1001{
1002 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1003 struct snd_soc_device *socdev = rtd->socdev;
1004 struct snd_soc_codec *codec = socdev->codec;
1005 u8 mode, old_mode, format, old_format;
1006
1007
1008 /* bit rate */
1009 old_mode = twl4030_read_reg_cache(codec,
1010 TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
1011 mode = old_mode & ~TWL4030_APLL_RATE;
1012
1013 switch (params_rate(params)) {
1014 case 8000:
1015 mode |= TWL4030_APLL_RATE_8000;
1016 break;
1017 case 11025:
1018 mode |= TWL4030_APLL_RATE_11025;
1019 break;
1020 case 12000:
1021 mode |= TWL4030_APLL_RATE_12000;
1022 break;
1023 case 16000:
1024 mode |= TWL4030_APLL_RATE_16000;
1025 break;
1026 case 22050:
1027 mode |= TWL4030_APLL_RATE_22050;
1028 break;
1029 case 24000:
1030 mode |= TWL4030_APLL_RATE_24000;
1031 break;
1032 case 32000:
1033 mode |= TWL4030_APLL_RATE_32000;
1034 break;
1035 case 44100:
1036 mode |= TWL4030_APLL_RATE_44100;
1037 break;
1038 case 48000:
1039 mode |= TWL4030_APLL_RATE_48000;
1040 break;
1041 default:
1042 printk(KERN_ERR "TWL4030 hw params: unknown rate %d\n",
1043 params_rate(params));
1044 return -EINVAL;
1045 }
1046
1047 if (mode != old_mode) {
1048 /* change rate and set CODECPDZ */
1049 twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
1050 twl4030_set_codecpdz(codec);
1051 }
1052
1053 /* sample size */
1054 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1055 format = old_format;
1056 format &= ~TWL4030_DATA_WIDTH;
1057 switch (params_format(params)) {
1058 case SNDRV_PCM_FORMAT_S16_LE:
1059 format |= TWL4030_DATA_WIDTH_16S_16W;
1060 break;
1061 case SNDRV_PCM_FORMAT_S24_LE:
1062 format |= TWL4030_DATA_WIDTH_32S_24W;
1063 break;
1064 default:
1065 printk(KERN_ERR "TWL4030 hw params: unknown format %d\n",
1066 params_format(params));
1067 return -EINVAL;
1068 }
1069
1070 if (format != old_format) {
1071
1072 /* clear CODECPDZ before changing format (codec requirement) */
1073 twl4030_clear_codecpdz(codec);
1074
1075 /* change format */
1076 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1077
1078 /* set CODECPDZ afterwards */
1079 twl4030_set_codecpdz(codec);
1080 }
1081 return 0;
1082}
1083
1084static int twl4030_set_dai_sysclk(struct snd_soc_dai *codec_dai,
1085 int clk_id, unsigned int freq, int dir)
1086{
1087 struct snd_soc_codec *codec = codec_dai->codec;
1088 u8 infreq;
1089
1090 switch (freq) {
1091 case 19200000:
1092 infreq = TWL4030_APLL_INFREQ_19200KHZ;
1093 break;
1094 case 26000000:
1095 infreq = TWL4030_APLL_INFREQ_26000KHZ;
1096 break;
1097 case 38400000:
1098 infreq = TWL4030_APLL_INFREQ_38400KHZ;
1099 break;
1100 default:
1101 printk(KERN_ERR "TWL4030 set sysclk: unknown rate %d\n",
1102 freq);
1103 return -EINVAL;
1104 }
1105
1106 infreq |= TWL4030_APLL_EN;
1107 twl4030_write(codec, TWL4030_REG_APLL_CTL, infreq);
1108
1109 return 0;
1110}
1111
1112static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
1113 unsigned int fmt)
1114{
1115 struct snd_soc_codec *codec = codec_dai->codec;
1116 u8 old_format, format;
1117
1118 /* get format */
1119 old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
1120 format = old_format;
1121
1122 /* set master/slave audio interface */
1123 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1124 case SND_SOC_DAIFMT_CBM_CFM:
1125 format &= ~(TWL4030_AIF_SLAVE_EN);
1126 format &= ~(TWL4030_CLK256FS_EN);
1127 break;
1128 case SND_SOC_DAIFMT_CBS_CFS:
1129 format |= TWL4030_AIF_SLAVE_EN;
1130 format |= TWL4030_CLK256FS_EN;
1131 break;
1132 default:
1133 return -EINVAL;
1134 }
1135
1136 /* interface format */
1137 format &= ~TWL4030_AIF_FORMAT;
1138 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1139 case SND_SOC_DAIFMT_I2S:
1140 format |= TWL4030_AIF_FORMAT_CODEC;
1141 break;
1142 default:
1143 return -EINVAL;
1144 }
1145
1146 if (format != old_format) {
1147
1148 /* clear CODECPDZ before changing format (codec requirement) */
1149 twl4030_clear_codecpdz(codec);
1150
1151 /* change format */
1152 twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
1153
1154 /* set CODECPDZ afterwards */
1155 twl4030_set_codecpdz(codec);
1156 }
1157
1158 return 0;
1159}
1160
1161#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
1162#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
1163
1164struct snd_soc_dai twl4030_dai = {
1165 .name = "twl4030",
1166 .playback = {
1167 .stream_name = "Playback",
1168 .channels_min = 2,
1169 .channels_max = 2,
1170 .rates = TWL4030_RATES,
1171 .formats = TWL4030_FORMATS,},
1172 .capture = {
1173 .stream_name = "Capture",
1174 .channels_min = 2,
1175 .channels_max = 2,
1176 .rates = TWL4030_RATES,
1177 .formats = TWL4030_FORMATS,},
1178 .ops = {
1179 .hw_params = twl4030_hw_params,
1180 .set_sysclk = twl4030_set_dai_sysclk,
1181 .set_fmt = twl4030_set_dai_fmt,
1182 }
1183};
1184EXPORT_SYMBOL_GPL(twl4030_dai);
1185
1186static int twl4030_suspend(struct platform_device *pdev, pm_message_t state)
1187{
1188 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1189 struct snd_soc_codec *codec = socdev->codec;
1190
1191 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
1192
1193 return 0;
1194}
1195
1196static int twl4030_resume(struct platform_device *pdev)
1197{
1198 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1199 struct snd_soc_codec *codec = socdev->codec;
1200
1201 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1202 twl4030_set_bias_level(codec, codec->suspend_bias_level);
1203 return 0;
1204}
1205
1206/*
1207 * initialize the driver
1208 * register the mixer and dsp interfaces with the kernel
1209 */
1210
1211static int twl4030_init(struct snd_soc_device *socdev)
1212{
1213 struct snd_soc_codec *codec = socdev->codec;
1214 int ret = 0;
1215
1216 printk(KERN_INFO "TWL4030 Audio Codec init \n");
1217
1218 codec->name = "twl4030";
1219 codec->owner = THIS_MODULE;
1220 codec->read = twl4030_read_reg_cache;
1221 codec->write = twl4030_write;
1222 codec->set_bias_level = twl4030_set_bias_level;
1223 codec->dai = &twl4030_dai;
1224 codec->num_dai = 1;
1225 codec->reg_cache_size = sizeof(twl4030_reg);
1226 codec->reg_cache = kmemdup(twl4030_reg, sizeof(twl4030_reg),
1227 GFP_KERNEL);
1228 if (codec->reg_cache == NULL)
1229 return -ENOMEM;
1230
1231 /* register pcms */
1232 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1233 if (ret < 0) {
1234 printk(KERN_ERR "twl4030: failed to create pcms\n");
1235 goto pcm_err;
1236 }
1237
1238 twl4030_init_chip(codec);
1239
1240 /* power on device */
1241 twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1242
1243 twl4030_add_controls(codec);
1244 twl4030_add_widgets(codec);
1245
1246 ret = snd_soc_init_card(socdev);
1247 if (ret < 0) {
1248 printk(KERN_ERR "twl4030: failed to register card\n");
1249 goto card_err;
1250 }
1251
1252 return ret;
1253
1254card_err:
1255 snd_soc_free_pcms(socdev);
1256 snd_soc_dapm_free(socdev);
1257pcm_err:
1258 kfree(codec->reg_cache);
1259 return ret;
1260}
1261
1262static struct snd_soc_device *twl4030_socdev;
1263
1264static int twl4030_probe(struct platform_device *pdev)
1265{
1266 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1267 struct snd_soc_codec *codec;
1268
1269 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
1270 if (codec == NULL)
1271 return -ENOMEM;
1272
1273 socdev->codec = codec;
1274 mutex_init(&codec->mutex);
1275 INIT_LIST_HEAD(&codec->dapm_widgets);
1276 INIT_LIST_HEAD(&codec->dapm_paths);
1277
1278 twl4030_socdev = socdev;
1279 twl4030_init(socdev);
1280
1281 return 0;
1282}
1283
1284static int twl4030_remove(struct platform_device *pdev)
1285{
1286 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1287 struct snd_soc_codec *codec = socdev->codec;
1288
1289 printk(KERN_INFO "TWL4030 Audio Codec remove\n");
1290 kfree(codec);
1291
1292 return 0;
1293}
1294
1295struct snd_soc_codec_device soc_codec_dev_twl4030 = {
1296 .probe = twl4030_probe,
1297 .remove = twl4030_remove,
1298 .suspend = twl4030_suspend,
1299 .resume = twl4030_resume,
1300};
1301EXPORT_SYMBOL_GPL(soc_codec_dev_twl4030);
1302
1303static int __init twl4030_modinit(void)
1304{
1305 return snd_soc_register_dai(&twl4030_dai);
1306}
1307module_init(twl4030_modinit);
1308
1309static void __exit twl4030_exit(void)
1310{
1311 snd_soc_unregister_dai(&twl4030_dai);
1312}
1313module_exit(twl4030_exit);
1314
1315MODULE_DESCRIPTION("ASoC TWL4030 codec driver");
1316MODULE_AUTHOR("Steve Sakoman");
1317MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/twl4030.h b/sound/soc/codecs/twl4030.h
new file mode 100644
index 000000000000..54615c76802b
--- /dev/null
+++ b/sound/soc/codecs/twl4030.h
@@ -0,0 +1,219 @@
1/*
2 * ALSA SoC TWL4030 codec driver
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
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#ifndef __TWL4030_AUDIO_H__
23#define __TWL4030_AUDIO_H__
24
25#define TWL4030_REG_CODEC_MODE 0x1
26#define TWL4030_REG_OPTION 0x2
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
96#define TWL4030_CACHEREGNUM (TWL4030_REG_MISC_SET_2 + 1)
97
98/* Bitfield Definitions */
99
100/* TWL4030_CODEC_MODE (0x01) Fields */
101
102#define TWL4030_APLL_RATE 0xF0
103#define TWL4030_APLL_RATE_8000 0x00
104#define TWL4030_APLL_RATE_11025 0x10
105#define TWL4030_APLL_RATE_12000 0x20
106#define TWL4030_APLL_RATE_16000 0x40
107#define TWL4030_APLL_RATE_22050 0x50
108#define TWL4030_APLL_RATE_24000 0x60
109#define TWL4030_APLL_RATE_32000 0x80
110#define TWL4030_APLL_RATE_44100 0x90
111#define TWL4030_APLL_RATE_48000 0xA0
112#define TWL4030_SEL_16K 0x04
113#define TWL4030_CODECPDZ 0x02
114#define TWL4030_OPT_MODE 0x01
115
116/* TWL4030_REG_MICBIAS_CTL (0x04) Fields */
117
118#define TWL4030_MICBIAS2_CTL 0x40
119#define TWL4030_MICBIAS1_CTL 0x20
120#define TWL4030_HSMICBIAS_EN 0x04
121#define TWL4030_MICBIAS2_EN 0x02
122#define TWL4030_MICBIAS1_EN 0x01
123
124/* ANAMICL (0x05) Fields */
125
126#define TWL4030_CNCL_OFFSET_START 0x80
127#define TWL4030_OFFSET_CNCL_SEL 0x60
128#define TWL4030_OFFSET_CNCL_SEL_ARX1 0x00
129#define TWL4030_OFFSET_CNCL_SEL_ARX2 0x20
130#define TWL4030_OFFSET_CNCL_SEL_VRX 0x40
131#define TWL4030_OFFSET_CNCL_SEL_ALL 0x60
132#define TWL4030_MICAMPL_EN 0x10
133#define TWL4030_CKMIC_EN 0x08
134#define TWL4030_AUXL_EN 0x04
135#define TWL4030_HSMIC_EN 0x02
136#define TWL4030_MAINMIC_EN 0x01
137
138/* ANAMICR (0x06) Fields */
139
140#define TWL4030_MICAMPR_EN 0x10
141#define TWL4030_AUXR_EN 0x04
142#define TWL4030_SUBMIC_EN 0x01
143
144/* AVADC_CTL (0x07) Fields */
145
146#define TWL4030_ADCL_EN 0x08
147#define TWL4030_AVADC_CLK_PRIORITY 0x04
148#define TWL4030_ADCR_EN 0x02
149
150/* AUDIO_IF (0x0E) Fields */
151
152#define TWL4030_AIF_SLAVE_EN 0x80
153#define TWL4030_DATA_WIDTH 0x60
154#define TWL4030_DATA_WIDTH_16S_16W 0x00
155#define TWL4030_DATA_WIDTH_32S_16W 0x40
156#define TWL4030_DATA_WIDTH_32S_24W 0x60
157#define TWL4030_AIF_FORMAT 0x18
158#define TWL4030_AIF_FORMAT_CODEC 0x00
159#define TWL4030_AIF_FORMAT_LEFT 0x08
160#define TWL4030_AIF_FORMAT_RIGHT 0x10
161#define TWL4030_AIF_FORMAT_TDM 0x18
162#define TWL4030_AIF_TRI_EN 0x04
163#define TWL4030_CLK256FS_EN 0x02
164#define TWL4030_AIF_EN 0x01
165
166/* HS_GAIN_SET (0x23) Fields */
167
168#define TWL4030_HSR_GAIN 0x0C
169#define TWL4030_HSR_GAIN_PWR_DOWN 0x00
170#define TWL4030_HSR_GAIN_PLUS_6DB 0x04
171#define TWL4030_HSR_GAIN_0DB 0x08
172#define TWL4030_HSR_GAIN_MINUS_6DB 0x0C
173#define TWL4030_HSL_GAIN 0x03
174#define TWL4030_HSL_GAIN_PWR_DOWN 0x00
175#define TWL4030_HSL_GAIN_PLUS_6DB 0x01
176#define TWL4030_HSL_GAIN_0DB 0x02
177#define TWL4030_HSL_GAIN_MINUS_6DB 0x03
178
179/* HS_POPN_SET (0x24) Fields */
180
181#define TWL4030_VMID_EN 0x40
182#define TWL4030_EXTMUTE 0x20
183#define TWL4030_RAMP_DELAY 0x1C
184#define TWL4030_RAMP_DELAY_20MS 0x00
185#define TWL4030_RAMP_DELAY_40MS 0x04
186#define TWL4030_RAMP_DELAY_81MS 0x08
187#define TWL4030_RAMP_DELAY_161MS 0x0C
188#define TWL4030_RAMP_DELAY_323MS 0x10
189#define TWL4030_RAMP_DELAY_645MS 0x14
190#define TWL4030_RAMP_DELAY_1291MS 0x18
191#define TWL4030_RAMP_DELAY_2581MS 0x1C
192#define TWL4030_RAMP_EN 0x02
193
194/* HFL_CTL (0x29, 0x2A) Fields */
195#define TWL4030_HF_CTL_HB_EN 0x04
196#define TWL4030_HF_CTL_LOOP_EN 0x08
197#define TWL4030_HF_CTL_RAMP_EN 0x10
198#define TWL4030_HF_CTL_REF_EN 0x20
199
200/* APLL_CTL (0x3A) Fields */
201
202#define TWL4030_APLL_EN 0x10
203#define TWL4030_APLL_INFREQ 0x0F
204#define TWL4030_APLL_INFREQ_19200KHZ 0x05
205#define TWL4030_APLL_INFREQ_26000KHZ 0x06
206#define TWL4030_APLL_INFREQ_38400KHZ 0x0F
207
208/* REG_MISC_SET_1 (0x3E) Fields */
209
210#define TWL4030_CLK64_EN 0x80
211#define TWL4030_SCRAMBLE_EN 0x40
212#define TWL4030_FMLOOP_EN 0x20
213#define TWL4030_SMOOTH_ANAVOL_EN 0x02
214#define TWL4030_DIGMIC_LR_SWAP_EN 0x01
215
216extern struct snd_soc_dai twl4030_dai;
217extern struct snd_soc_codec_device soc_codec_dev_twl4030;
218
219#endif /* End of __TWL4030_AUDIO_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
new file mode 100644
index 000000000000..a2c5064a774b
--- /dev/null
+++ b/sound/soc/codecs/uda134x.c
@@ -0,0 +1,668 @@
1/*
2 * uda134x.c -- UDA134X ALSA SoC Codec driver
3 *
4 * Modifications by Christian Pellegrin <chripell@evolware.org>
5 *
6 * Copyright 2007 Dension Audio Systems Ltd.
7 * Author: Zoltan Devai
8 *
9 * Based on the WM87xx drivers by Liam Girdwood and Richard Purdie
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/module.h>
17#include <linux/delay.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/initval.h>
23
24#include <sound/uda134x.h>
25#include <sound/l3.h>
26
27#include "uda134x.h"
28
29
30#define POWER_OFF_ON_STANDBY 1
31/*
32 ALSA SOC usually puts the device in standby mode when it's not used
33 for sometime. If you define POWER_OFF_ON_STANDBY the driver will
34 turn off the ADC/DAC when this callback is invoked and turn it back
35 on when needed. Unfortunately this will result in a very light bump
36 (it can be audible only with good earphones). If this bothers you
37 just comment this line, you will have slightly higher power
38 consumption . Please note that sending the L3 command for ADC is
39 enough to make the bump, so it doesn't make difference if you
40 completely take off power from the codec.
41 */
42
43#define UDA134X_RATES SNDRV_PCM_RATE_8000_48000
44#define UDA134X_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
45 SNDRV_PCM_FMTBIT_S18_3LE | SNDRV_PCM_FMTBIT_S20_3LE)
46
47struct uda134x_priv {
48 int sysclk;
49 int dai_fmt;
50
51 struct snd_pcm_substream *master_substream;
52 struct snd_pcm_substream *slave_substream;
53};
54
55/* In-data addresses are hard-coded into the reg-cache values */
56static const char uda134x_reg[UDA134X_REGS_NUM] = {
57 /* Extended address registers */
58 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
59 /* Status, data regs */
60 0x00, 0x83, 0x00, 0x40, 0x80, 0x00,
61};
62
63/*
64 * The codec has no support for reading its registers except for peak level...
65 */
66static inline unsigned int uda134x_read_reg_cache(struct snd_soc_codec *codec,
67 unsigned int reg)
68{
69 u8 *cache = codec->reg_cache;
70
71 if (reg >= UDA134X_REGS_NUM)
72 return -1;
73 return cache[reg];
74}
75
76/*
77 * Write the register cache
78 */
79static inline void uda134x_write_reg_cache(struct snd_soc_codec *codec,
80 u8 reg, unsigned int value)
81{
82 u8 *cache = codec->reg_cache;
83
84 if (reg >= UDA134X_REGS_NUM)
85 return;
86 cache[reg] = value;
87}
88
89/*
90 * Write to the uda134x registers
91 *
92 */
93static int uda134x_write(struct snd_soc_codec *codec, unsigned int reg,
94 unsigned int value)
95{
96 int ret;
97 u8 addr;
98 u8 data = value;
99 struct uda134x_platform_data *pd = codec->control_data;
100
101 pr_debug("%s reg: %02X, value:%02X\n", __func__, reg, value);
102
103 if (reg >= UDA134X_REGS_NUM) {
104 printk(KERN_ERR "%s unkown register: reg: %d",
105 __func__, reg);
106 return -EINVAL;
107 }
108
109 uda134x_write_reg_cache(codec, reg, value);
110
111 switch (reg) {
112 case UDA134X_STATUS0:
113 case UDA134X_STATUS1:
114 addr = UDA134X_STATUS_ADDR;
115 break;
116 case UDA134X_DATA000:
117 case UDA134X_DATA001:
118 case UDA134X_DATA010:
119 addr = UDA134X_DATA0_ADDR;
120 break;
121 case UDA134X_DATA1:
122 addr = UDA134X_DATA1_ADDR;
123 break;
124 default:
125 /* It's an extended address register */
126 addr = (reg | UDA134X_EXTADDR_PREFIX);
127
128 ret = l3_write(&pd->l3,
129 UDA134X_DATA0_ADDR, &addr, 1);
130 if (ret != 1)
131 return -EIO;
132
133 addr = UDA134X_DATA0_ADDR;
134 data = (value | UDA134X_EXTDATA_PREFIX);
135 break;
136 }
137
138 ret = l3_write(&pd->l3,
139 addr, &data, 1);
140 if (ret != 1)
141 return -EIO;
142
143 return 0;
144}
145
146static inline void uda134x_reset(struct snd_soc_codec *codec)
147{
148 u8 reset_reg = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
149 uda134x_write(codec, UDA134X_STATUS0, reset_reg | (1<<6));
150 msleep(1);
151 uda134x_write(codec, UDA134X_STATUS0, reset_reg & ~(1<<6));
152}
153
154static int uda134x_mute(struct snd_soc_dai *dai, int mute)
155{
156 struct snd_soc_codec *codec = dai->codec;
157 u8 mute_reg = uda134x_read_reg_cache(codec, UDA134X_DATA010);
158
159 pr_debug("%s mute: %d\n", __func__, mute);
160
161 if (mute)
162 mute_reg |= (1<<2);
163 else
164 mute_reg &= ~(1<<2);
165
166 uda134x_write(codec, UDA134X_DATA010, mute_reg & ~(1<<2));
167
168 return 0;
169}
170
171static int uda134x_startup(struct snd_pcm_substream *substream,
172 struct snd_soc_dai *dai)
173{
174 struct snd_soc_pcm_runtime *rtd = substream->private_data;
175 struct snd_soc_device *socdev = rtd->socdev;
176 struct snd_soc_codec *codec = socdev->codec;
177 struct uda134x_priv *uda134x = codec->private_data;
178 struct snd_pcm_runtime *master_runtime;
179
180 if (uda134x->master_substream) {
181 master_runtime = uda134x->master_substream->runtime;
182
183 pr_debug("%s constraining to %d bits at %d\n", __func__,
184 master_runtime->sample_bits,
185 master_runtime->rate);
186
187 snd_pcm_hw_constraint_minmax(substream->runtime,
188 SNDRV_PCM_HW_PARAM_RATE,
189 master_runtime->rate,
190 master_runtime->rate);
191
192 snd_pcm_hw_constraint_minmax(substream->runtime,
193 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
194 master_runtime->sample_bits,
195 master_runtime->sample_bits);
196
197 uda134x->slave_substream = substream;
198 } else
199 uda134x->master_substream = substream;
200
201 return 0;
202}
203
204static void uda134x_shutdown(struct snd_pcm_substream *substream,
205 struct snd_soc_dai *dai)
206{
207 struct snd_soc_pcm_runtime *rtd = substream->private_data;
208 struct snd_soc_device *socdev = rtd->socdev;
209 struct snd_soc_codec *codec = socdev->codec;
210 struct uda134x_priv *uda134x = codec->private_data;
211
212 if (uda134x->master_substream == substream)
213 uda134x->master_substream = uda134x->slave_substream;
214
215 uda134x->slave_substream = NULL;
216}
217
218static int uda134x_hw_params(struct snd_pcm_substream *substream,
219 struct snd_pcm_hw_params *params,
220 struct snd_soc_dai *dai)
221{
222 struct snd_soc_pcm_runtime *rtd = substream->private_data;
223 struct snd_soc_device *socdev = rtd->socdev;
224 struct snd_soc_codec *codec = socdev->codec;
225 struct uda134x_priv *uda134x = codec->private_data;
226 u8 hw_params;
227
228 if (substream == uda134x->slave_substream) {
229 pr_debug("%s ignoring hw_params for slave substream\n",
230 __func__);
231 return 0;
232 }
233
234 hw_params = uda134x_read_reg_cache(codec, UDA134X_STATUS0);
235 hw_params &= STATUS0_SYSCLK_MASK;
236 hw_params &= STATUS0_DAIFMT_MASK;
237
238 pr_debug("%s sysclk: %d, rate:%d\n", __func__,
239 uda134x->sysclk, params_rate(params));
240
241 /* set SYSCLK / fs ratio */
242 switch (uda134x->sysclk / params_rate(params)) {
243 case 512:
244 break;
245 case 384:
246 hw_params |= (1<<4);
247 break;
248 case 256:
249 hw_params |= (1<<5);
250 break;
251 default:
252 printk(KERN_ERR "%s unsupported fs\n", __func__);
253 return -EINVAL;
254 }
255
256 pr_debug("%s dai_fmt: %d, params_format:%d\n", __func__,
257 uda134x->dai_fmt, params_format(params));
258
259 /* set DAI format and word length */
260 switch (uda134x->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
261 case SND_SOC_DAIFMT_I2S:
262 break;
263 case SND_SOC_DAIFMT_RIGHT_J:
264 switch (params_format(params)) {
265 case SNDRV_PCM_FORMAT_S16_LE:
266 hw_params |= (1<<1);
267 break;
268 case SNDRV_PCM_FORMAT_S18_3LE:
269 hw_params |= (1<<2);
270 break;
271 case SNDRV_PCM_FORMAT_S20_3LE:
272 hw_params |= ((1<<2) | (1<<1));
273 break;
274 default:
275 printk(KERN_ERR "%s unsupported format (right)\n",
276 __func__);
277 return -EINVAL;
278 }
279 break;
280 case SND_SOC_DAIFMT_LEFT_J:
281 hw_params |= (1<<3);
282 break;
283 default:
284 printk(KERN_ERR "%s unsupported format\n", __func__);
285 return -EINVAL;
286 }
287
288 uda134x_write(codec, UDA134X_STATUS0, hw_params);
289
290 return 0;
291}
292
293static int uda134x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
294 int clk_id, unsigned int freq, int dir)
295{
296 struct snd_soc_codec *codec = codec_dai->codec;
297 struct uda134x_priv *uda134x = codec->private_data;
298
299 pr_debug("%s clk_id: %d, freq: %d, dir: %d\n", __func__,
300 clk_id, freq, dir);
301
302 /* Anything between 256fs*8Khz and 512fs*48Khz should be acceptable
303 because the codec is slave. Of course limitations of the clock
304 master (the IIS controller) apply.
305 We'll error out on set_hw_params if it's not OK */
306 if ((freq >= (256 * 8000)) && (freq <= (512 * 48000))) {
307 uda134x->sysclk = freq;
308 return 0;
309 }
310
311 printk(KERN_ERR "%s unsupported sysclk\n", __func__);
312 return -EINVAL;
313}
314
315static int uda134x_set_dai_fmt(struct snd_soc_dai *codec_dai,
316 unsigned int fmt)
317{
318 struct snd_soc_codec *codec = codec_dai->codec;
319 struct uda134x_priv *uda134x = codec->private_data;
320
321 pr_debug("%s fmt: %08X\n", __func__, fmt);
322
323 /* codec supports only full slave mode */
324 if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBS_CFS) {
325 printk(KERN_ERR "%s unsupported slave mode\n", __func__);
326 return -EINVAL;
327 }
328
329 /* no support for clock inversion */
330 if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF) {
331 printk(KERN_ERR "%s unsupported clock inversion\n", __func__);
332 return -EINVAL;
333 }
334
335 /* We can't setup DAI format here as it depends on the word bit num */
336 /* so let's just store the value for later */
337 uda134x->dai_fmt = fmt;
338
339 return 0;
340}
341
342static int uda134x_set_bias_level(struct snd_soc_codec *codec,
343 enum snd_soc_bias_level level)
344{
345 u8 reg;
346 struct uda134x_platform_data *pd = codec->control_data;
347 int i;
348 u8 *cache = codec->reg_cache;
349
350 pr_debug("%s bias level %d\n", __func__, level);
351
352 switch (level) {
353 case SND_SOC_BIAS_ON:
354 /* ADC, DAC on */
355 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
356 uda134x_write(codec, UDA134X_STATUS1, reg | 0x03);
357 break;
358 case SND_SOC_BIAS_PREPARE:
359 /* power on */
360 if (pd->power) {
361 pd->power(1);
362 /* Sync reg_cache with the hardware */
363 for (i = 0; i < ARRAY_SIZE(uda134x_reg); i++)
364 codec->write(codec, i, *cache++);
365 }
366 break;
367 case SND_SOC_BIAS_STANDBY:
368 /* ADC, DAC power off */
369 reg = uda134x_read_reg_cache(codec, UDA134X_STATUS1);
370 uda134x_write(codec, UDA134X_STATUS1, reg & ~(0x03));
371 break;
372 case SND_SOC_BIAS_OFF:
373 /* power off */
374 if (pd->power)
375 pd->power(0);
376 break;
377 }
378 codec->bias_level = level;
379 return 0;
380}
381
382static const char *uda134x_dsp_setting[] = {"Flat", "Minimum1",
383 "Minimum2", "Maximum"};
384static const char *uda134x_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
385static const char *uda134x_mixmode[] = {"Differential", "Analog1",
386 "Analog2", "Both"};
387
388static const struct soc_enum uda134x_mixer_enum[] = {
389SOC_ENUM_SINGLE(UDA134X_DATA010, 0, 0x04, uda134x_dsp_setting),
390SOC_ENUM_SINGLE(UDA134X_DATA010, 3, 0x04, uda134x_deemph),
391SOC_ENUM_SINGLE(UDA134X_EA010, 0, 0x04, uda134x_mixmode),
392};
393
394static const struct snd_kcontrol_new uda1341_snd_controls[] = {
395SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
396SOC_SINGLE("Capture Volume", UDA134X_EA010, 2, 0x07, 0),
397SOC_SINGLE("Analog1 Volume", UDA134X_EA000, 0, 0x1F, 1),
398SOC_SINGLE("Analog2 Volume", UDA134X_EA001, 0, 0x1F, 1),
399
400SOC_SINGLE("Mic Sensitivity", UDA134X_EA010, 2, 7, 0),
401SOC_SINGLE("Mic Volume", UDA134X_EA101, 0, 0x1F, 0),
402
403SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
404SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
405
406SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
407SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
408SOC_ENUM("Input Mux", uda134x_mixer_enum[2]),
409
410SOC_SINGLE("AGC Switch", UDA134X_EA100, 4, 1, 0),
411SOC_SINGLE("AGC Target Volume", UDA134X_EA110, 0, 0x03, 1),
412SOC_SINGLE("AGC Timing", UDA134X_EA110, 2, 0x07, 0),
413
414SOC_SINGLE("DAC +6dB Switch", UDA134X_STATUS1, 6, 1, 0),
415SOC_SINGLE("ADC +6dB Switch", UDA134X_STATUS1, 5, 1, 0),
416SOC_SINGLE("ADC Polarity Switch", UDA134X_STATUS1, 4, 1, 0),
417SOC_SINGLE("DAC Polarity Switch", UDA134X_STATUS1, 3, 1, 0),
418SOC_SINGLE("Double Speed Playback Switch", UDA134X_STATUS1, 2, 1, 0),
419SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
420};
421
422static const struct snd_kcontrol_new uda1340_snd_controls[] = {
423SOC_SINGLE("Master Playback Volume", UDA134X_DATA000, 0, 0x3F, 1),
424
425SOC_SINGLE("Tone Control - Bass", UDA134X_DATA001, 2, 0xF, 0),
426SOC_SINGLE("Tone Control - Treble", UDA134X_DATA001, 0, 3, 0),
427
428SOC_ENUM("Sound Processing Filter", uda134x_mixer_enum[0]),
429SOC_ENUM("PCM Playback De-emphasis", uda134x_mixer_enum[1]),
430
431SOC_SINGLE("DC Filter Enable Switch", UDA134X_STATUS0, 0, 1, 0),
432};
433
434static int uda134x_add_controls(struct snd_soc_codec *codec)
435{
436 int err, i, n;
437 const struct snd_kcontrol_new *ctrls;
438 struct uda134x_platform_data *pd = codec->control_data;
439
440 switch (pd->model) {
441 case UDA134X_UDA1340:
442 case UDA134X_UDA1344:
443 n = ARRAY_SIZE(uda1340_snd_controls);
444 ctrls = uda1340_snd_controls;
445 break;
446 case UDA134X_UDA1341:
447 n = ARRAY_SIZE(uda1341_snd_controls);
448 ctrls = uda1341_snd_controls;
449 break;
450 default:
451 printk(KERN_ERR "%s unkown codec type: %d",
452 __func__, pd->model);
453 return -EINVAL;
454 }
455
456 for (i = 0; i < n; i++) {
457 err = snd_ctl_add(codec->card,
458 snd_soc_cnew(&ctrls[i],
459 codec, NULL));
460 if (err < 0)
461 return err;
462 }
463
464 return 0;
465}
466
467struct snd_soc_dai uda134x_dai = {
468 .name = "UDA134X",
469 /* playback capabilities */
470 .playback = {
471 .stream_name = "Playback",
472 .channels_min = 1,
473 .channels_max = 2,
474 .rates = UDA134X_RATES,
475 .formats = UDA134X_FORMATS,
476 },
477 /* capture capabilities */
478 .capture = {
479 .stream_name = "Capture",
480 .channels_min = 1,
481 .channels_max = 2,
482 .rates = UDA134X_RATES,
483 .formats = UDA134X_FORMATS,
484 },
485 /* pcm operations */
486 .ops = {
487 .startup = uda134x_startup,
488 .shutdown = uda134x_shutdown,
489 .hw_params = uda134x_hw_params,
490 .digital_mute = uda134x_mute,
491 .set_sysclk = uda134x_set_dai_sysclk,
492 .set_fmt = uda134x_set_dai_fmt,
493 }
494};
495EXPORT_SYMBOL(uda134x_dai);
496
497
498static int uda134x_soc_probe(struct platform_device *pdev)
499{
500 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
501 struct snd_soc_codec *codec;
502 struct uda134x_priv *uda134x;
503 void *codec_setup_data = socdev->codec_data;
504 int ret = -ENOMEM;
505 struct uda134x_platform_data *pd;
506
507 printk(KERN_INFO "UDA134X SoC Audio Codec\n");
508
509 if (!codec_setup_data) {
510 printk(KERN_ERR "UDA134X SoC codec: "
511 "missing L3 bitbang function\n");
512 return -ENODEV;
513 }
514
515 pd = codec_setup_data;
516 switch (pd->model) {
517 case UDA134X_UDA1340:
518 case UDA134X_UDA1341:
519 case UDA134X_UDA1344:
520 break;
521 default:
522 printk(KERN_ERR "UDA134X SoC codec: "
523 "unsupported model %d\n",
524 pd->model);
525 return -EINVAL;
526 }
527
528 socdev->codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
529 if (socdev->codec == NULL)
530 return ret;
531
532 codec = socdev->codec;
533
534 uda134x = kzalloc(sizeof(struct uda134x_priv), GFP_KERNEL);
535 if (uda134x == NULL)
536 goto priv_err;
537 codec->private_data = uda134x;
538
539 codec->reg_cache = kmemdup(uda134x_reg, sizeof(uda134x_reg),
540 GFP_KERNEL);
541 if (codec->reg_cache == NULL)
542 goto reg_err;
543
544 mutex_init(&codec->mutex);
545
546 codec->reg_cache_size = sizeof(uda134x_reg);
547 codec->reg_cache_step = 1;
548
549 codec->name = "UDA134X";
550 codec->owner = THIS_MODULE;
551 codec->dai = &uda134x_dai;
552 codec->num_dai = 1;
553 codec->read = uda134x_read_reg_cache;
554 codec->write = uda134x_write;
555#ifdef POWER_OFF_ON_STANDBY
556 codec->set_bias_level = uda134x_set_bias_level;
557#endif
558 INIT_LIST_HEAD(&codec->dapm_widgets);
559 INIT_LIST_HEAD(&codec->dapm_paths);
560
561 codec->control_data = codec_setup_data;
562
563 if (pd->power)
564 pd->power(1);
565
566 uda134x_reset(codec);
567
568 /* register pcms */
569 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
570 if (ret < 0) {
571 printk(KERN_ERR "UDA134X: failed to register pcms\n");
572 goto pcm_err;
573 }
574
575 ret = uda134x_add_controls(codec);
576 if (ret < 0) {
577 printk(KERN_ERR "UDA134X: failed to register controls\n");
578 goto pcm_err;
579 }
580
581 ret = snd_soc_init_card(socdev);
582 if (ret < 0) {
583 printk(KERN_ERR "UDA134X: failed to register card\n");
584 goto card_err;
585 }
586
587 return 0;
588
589card_err:
590 snd_soc_free_pcms(socdev);
591 snd_soc_dapm_free(socdev);
592pcm_err:
593 kfree(codec->reg_cache);
594reg_err:
595 kfree(codec->private_data);
596priv_err:
597 kfree(codec);
598 return ret;
599}
600
601/* power down chip */
602static int uda134x_soc_remove(struct platform_device *pdev)
603{
604 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
605 struct snd_soc_codec *codec = socdev->codec;
606
607 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
608 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
609
610 snd_soc_free_pcms(socdev);
611 snd_soc_dapm_free(socdev);
612
613 kfree(codec->private_data);
614 kfree(codec->reg_cache);
615 kfree(codec);
616
617 return 0;
618}
619
620#if defined(CONFIG_PM)
621static int uda134x_soc_suspend(struct platform_device *pdev,
622 pm_message_t state)
623{
624 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
625 struct snd_soc_codec *codec = socdev->codec;
626
627 uda134x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
628 uda134x_set_bias_level(codec, SND_SOC_BIAS_OFF);
629 return 0;
630}
631
632static int uda134x_soc_resume(struct platform_device *pdev)
633{
634 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
635 struct snd_soc_codec *codec = socdev->codec;
636
637 uda134x_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
638 uda134x_set_bias_level(codec, SND_SOC_BIAS_ON);
639 return 0;
640}
641#else
642#define uda134x_soc_suspend NULL
643#define uda134x_soc_resume NULL
644#endif /* CONFIG_PM */
645
646struct snd_soc_codec_device soc_codec_dev_uda134x = {
647 .probe = uda134x_soc_probe,
648 .remove = uda134x_soc_remove,
649 .suspend = uda134x_soc_suspend,
650 .resume = uda134x_soc_resume,
651};
652EXPORT_SYMBOL_GPL(soc_codec_dev_uda134x);
653
654static int __init uda134x_init(void)
655{
656 return snd_soc_register_dai(&uda134x_dai);
657}
658module_init(uda134x_init);
659
660static void __exit uda134x_exit(void)
661{
662 snd_soc_unregister_dai(&uda134x_dai);
663}
664module_exit(uda134x_exit);
665
666MODULE_DESCRIPTION("UDA134X ALSA soc codec driver");
667MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
668MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/uda134x.h b/sound/soc/codecs/uda134x.h
new file mode 100644
index 000000000000..94f440490b31
--- /dev/null
+++ b/sound/soc/codecs/uda134x.h
@@ -0,0 +1,36 @@
1#ifndef _UDA134X_CODEC_H
2#define _UDA134X_CODEC_H
3
4#define UDA134X_L3ADDR 5
5#define UDA134X_DATA0_ADDR ((UDA134X_L3ADDR << 2) | 0)
6#define UDA134X_DATA1_ADDR ((UDA134X_L3ADDR << 2) | 1)
7#define UDA134X_STATUS_ADDR ((UDA134X_L3ADDR << 2) | 2)
8
9#define UDA134X_EXTADDR_PREFIX 0xC0
10#define UDA134X_EXTDATA_PREFIX 0xE0
11
12/* UDA134X registers */
13#define UDA134X_EA000 0
14#define UDA134X_EA001 1
15#define UDA134X_EA010 2
16#define UDA134X_EA011 3
17#define UDA134X_EA100 4
18#define UDA134X_EA101 5
19#define UDA134X_EA110 6
20#define UDA134X_EA111 7
21#define UDA134X_STATUS0 8
22#define UDA134X_STATUS1 9
23#define UDA134X_DATA000 10
24#define UDA134X_DATA001 11
25#define UDA134X_DATA010 12
26#define UDA134X_DATA1 13
27
28#define UDA134X_REGS_NUM 14
29
30#define STATUS0_DAIFMT_MASK (~(7<<1))
31#define STATUS0_SYSCLK_MASK (~(3<<4))
32
33extern struct snd_soc_dai uda134x_dai;
34extern struct snd_soc_codec_device soc_codec_dev_uda134x;
35
36#endif
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index a69ee72a7af5..e6bf0844fbf3 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -407,7 +407,8 @@ static int uda1380_set_dai_fmt(struct snd_soc_dai *codec_dai,
407 * when the DAI is being clocked by the CPU DAI. It's up to the 407 * when the DAI is being clocked by the CPU DAI. It's up to the
408 * machine and cpu DAI driver to do this before we are called. 408 * machine and cpu DAI driver to do this before we are called.
409 */ 409 */
410static int uda1380_pcm_prepare(struct snd_pcm_substream *substream) 410static int uda1380_pcm_prepare(struct snd_pcm_substream *substream,
411 struct snd_soc_dai *dai)
411{ 412{
412 struct snd_soc_pcm_runtime *rtd = substream->private_data; 413 struct snd_soc_pcm_runtime *rtd = substream->private_data;
413 struct snd_soc_device *socdev = rtd->socdev; 414 struct snd_soc_device *socdev = rtd->socdev;
@@ -439,7 +440,8 @@ static int uda1380_pcm_prepare(struct snd_pcm_substream *substream)
439} 440}
440 441
441static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream, 442static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
442 struct snd_pcm_hw_params *params) 443 struct snd_pcm_hw_params *params,
444 struct snd_soc_dai *dai)
443{ 445{
444 struct snd_soc_pcm_runtime *rtd = substream->private_data; 446 struct snd_soc_pcm_runtime *rtd = substream->private_data;
445 struct snd_soc_device *socdev = rtd->socdev; 447 struct snd_soc_device *socdev = rtd->socdev;
@@ -477,7 +479,8 @@ static int uda1380_pcm_hw_params(struct snd_pcm_substream *substream,
477 return 0; 479 return 0;
478} 480}
479 481
480static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream) 482static void uda1380_pcm_shutdown(struct snd_pcm_substream *substream,
483 struct snd_soc_dai *dai)
481{ 484{
482 struct snd_soc_pcm_runtime *rtd = substream->private_data; 485 struct snd_soc_pcm_runtime *rtd = substream->private_data;
483 struct snd_soc_device *socdev = rtd->socdev; 486 struct snd_soc_device *socdev = rtd->socdev;
@@ -560,8 +563,6 @@ struct snd_soc_dai uda1380_dai[] = {
560 .hw_params = uda1380_pcm_hw_params, 563 .hw_params = uda1380_pcm_hw_params,
561 .shutdown = uda1380_pcm_shutdown, 564 .shutdown = uda1380_pcm_shutdown,
562 .prepare = uda1380_pcm_prepare, 565 .prepare = uda1380_pcm_prepare,
563 },
564 .dai_ops = {
565 .digital_mute = uda1380_mute, 566 .digital_mute = uda1380_mute,
566 .set_fmt = uda1380_set_dai_fmt, 567 .set_fmt = uda1380_set_dai_fmt,
567 }, 568 },
@@ -579,8 +580,6 @@ struct snd_soc_dai uda1380_dai[] = {
579 .hw_params = uda1380_pcm_hw_params, 580 .hw_params = uda1380_pcm_hw_params,
580 .shutdown = uda1380_pcm_shutdown, 581 .shutdown = uda1380_pcm_shutdown,
581 .prepare = uda1380_pcm_prepare, 582 .prepare = uda1380_pcm_prepare,
582 },
583 .dai_ops = {
584 .digital_mute = uda1380_mute, 583 .digital_mute = uda1380_mute,
585 .set_fmt = uda1380_set_dai_fmt, 584 .set_fmt = uda1380_set_dai_fmt,
586 }, 585 },
@@ -598,8 +597,6 @@ struct snd_soc_dai uda1380_dai[] = {
598 .hw_params = uda1380_pcm_hw_params, 597 .hw_params = uda1380_pcm_hw_params,
599 .shutdown = uda1380_pcm_shutdown, 598 .shutdown = uda1380_pcm_shutdown,
600 .prepare = uda1380_pcm_prepare, 599 .prepare = uda1380_pcm_prepare,
601 },
602 .dai_ops = {
603 .set_fmt = uda1380_set_dai_fmt, 600 .set_fmt = uda1380_set_dai_fmt,
604 }, 601 },
605}, 602},
@@ -680,7 +677,7 @@ static int uda1380_init(struct snd_soc_device *socdev, int dac_clk)
680 /* uda1380 init */ 677 /* uda1380 init */
681 uda1380_add_controls(codec); 678 uda1380_add_controls(codec);
682 uda1380_add_widgets(codec); 679 uda1380_add_widgets(codec);
683 ret = snd_soc_register_card(socdev); 680 ret = snd_soc_init_card(socdev);
684 if (ret < 0) { 681 if (ret < 0) {
685 pr_err("uda1380: failed to register card\n"); 682 pr_err("uda1380: failed to register card\n");
686 goto card_err; 683 goto card_err;
@@ -844,6 +841,18 @@ struct snd_soc_codec_device soc_codec_dev_uda1380 = {
844}; 841};
845EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380); 842EXPORT_SYMBOL_GPL(soc_codec_dev_uda1380);
846 843
844static int __init uda1380_modinit(void)
845{
846 return snd_soc_register_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
847}
848module_init(uda1380_modinit);
849
850static void __exit uda1380_exit(void)
851{
852 snd_soc_unregister_dais(uda1380_dai, ARRAY_SIZE(uda1380_dai));
853}
854module_exit(uda1380_exit);
855
847MODULE_AUTHOR("Giorgio Padrin"); 856MODULE_AUTHOR("Giorgio Padrin");
848MODULE_DESCRIPTION("Audio support for codec Philips UDA1380"); 857MODULE_DESCRIPTION("Audio support for codec Philips UDA1380");
849MODULE_LICENSE("GPL"); 858MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
new file mode 100644
index 000000000000..e3989d406f54
--- /dev/null
+++ b/sound/soc/codecs/wm8350.c
@@ -0,0 +1,1583 @@
1/*
2 * wm8350.c -- WM8350 ALSA SoC audio driver
3 *
4 * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
5 *
6 * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
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
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/platform_device.h>
19#include <linux/mfd/wm8350/audio.h>
20#include <linux/mfd/wm8350/core.h>
21#include <linux/regulator/consumer.h>
22#include <sound/core.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h>
28#include <sound/tlv.h>
29
30#include "wm8350.h"
31
32#define WM8350_OUTn_0dB 0x39
33
34#define WM8350_RAMP_NONE 0
35#define WM8350_RAMP_UP 1
36#define WM8350_RAMP_DOWN 2
37
38/* We only include the analogue supplies here; the digital supplies
39 * need to be available well before this driver can be probed.
40 */
41static const char *supply_names[] = {
42 "AVDD",
43 "HPVDD",
44};
45
46struct wm8350_output {
47 u16 active;
48 u16 left_vol;
49 u16 right_vol;
50 u16 ramp;
51 u16 mute;
52};
53
54struct wm8350_data {
55 struct snd_soc_codec codec;
56 struct wm8350_output out1;
57 struct wm8350_output out2;
58 struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)];
59};
60
61static unsigned int wm8350_codec_cache_read(struct snd_soc_codec *codec,
62 unsigned int reg)
63{
64 struct wm8350 *wm8350 = codec->control_data;
65 return wm8350->reg_cache[reg];
66}
67
68static unsigned int wm8350_codec_read(struct snd_soc_codec *codec,
69 unsigned int reg)
70{
71 struct wm8350 *wm8350 = codec->control_data;
72 return wm8350_reg_read(wm8350, reg);
73}
74
75static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg,
76 unsigned int value)
77{
78 struct wm8350 *wm8350 = codec->control_data;
79 return wm8350_reg_write(wm8350, reg, value);
80}
81
82/*
83 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
84 */
85static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec)
86{
87 struct wm8350_data *wm8350_data = codec->private_data;
88 struct wm8350_output *out1 = &wm8350_data->out1;
89 struct wm8350 *wm8350 = codec->control_data;
90 int left_complete = 0, right_complete = 0;
91 u16 reg, val;
92
93 /* left channel */
94 reg = wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME);
95 val = (reg & WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
96
97 if (out1->ramp == WM8350_RAMP_UP) {
98 /* ramp step up */
99 if (val < out1->left_vol) {
100 val++;
101 reg &= ~WM8350_OUT1L_VOL_MASK;
102 wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
103 reg | (val << WM8350_OUT1L_VOL_SHIFT));
104 } else
105 left_complete = 1;
106 } else if (out1->ramp == WM8350_RAMP_DOWN) {
107 /* ramp step down */
108 if (val > 0) {
109 val--;
110 reg &= ~WM8350_OUT1L_VOL_MASK;
111 wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME,
112 reg | (val << WM8350_OUT1L_VOL_SHIFT));
113 } else
114 left_complete = 1;
115 } else
116 return 1;
117
118 /* right channel */
119 reg = wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME);
120 val = (reg & WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
121 if (out1->ramp == WM8350_RAMP_UP) {
122 /* ramp step up */
123 if (val < out1->right_vol) {
124 val++;
125 reg &= ~WM8350_OUT1R_VOL_MASK;
126 wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
127 reg | (val << WM8350_OUT1R_VOL_SHIFT));
128 } else
129 right_complete = 1;
130 } else if (out1->ramp == WM8350_RAMP_DOWN) {
131 /* ramp step down */
132 if (val > 0) {
133 val--;
134 reg &= ~WM8350_OUT1R_VOL_MASK;
135 wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME,
136 reg | (val << WM8350_OUT1R_VOL_SHIFT));
137 } else
138 right_complete = 1;
139 }
140
141 /* only hit the update bit if either volume has changed this step */
142 if (!left_complete || !right_complete)
143 wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME, WM8350_OUT1_VU);
144
145 return left_complete & right_complete;
146}
147
148/*
149 * Ramp OUT2 PGA volume to minimise pops at stream startup and shutdown.
150 */
151static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
152{
153 struct wm8350_data *wm8350_data = codec->private_data;
154 struct wm8350_output *out2 = &wm8350_data->out2;
155 struct wm8350 *wm8350 = codec->control_data;
156 int left_complete = 0, right_complete = 0;
157 u16 reg, val;
158
159 /* left channel */
160 reg = wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME);
161 val = (reg & WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
162 if (out2->ramp == WM8350_RAMP_UP) {
163 /* ramp step up */
164 if (val < out2->left_vol) {
165 val++;
166 reg &= ~WM8350_OUT2L_VOL_MASK;
167 wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
168 reg | (val << WM8350_OUT1L_VOL_SHIFT));
169 } else
170 left_complete = 1;
171 } else if (out2->ramp == WM8350_RAMP_DOWN) {
172 /* ramp step down */
173 if (val > 0) {
174 val--;
175 reg &= ~WM8350_OUT2L_VOL_MASK;
176 wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME,
177 reg | (val << WM8350_OUT1L_VOL_SHIFT));
178 } else
179 left_complete = 1;
180 } else
181 return 1;
182
183 /* right channel */
184 reg = wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME);
185 val = (reg & WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
186 if (out2->ramp == WM8350_RAMP_UP) {
187 /* ramp step up */
188 if (val < out2->right_vol) {
189 val++;
190 reg &= ~WM8350_OUT2R_VOL_MASK;
191 wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
192 reg | (val << WM8350_OUT1R_VOL_SHIFT));
193 } else
194 right_complete = 1;
195 } else if (out2->ramp == WM8350_RAMP_DOWN) {
196 /* ramp step down */
197 if (val > 0) {
198 val--;
199 reg &= ~WM8350_OUT2R_VOL_MASK;
200 wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME,
201 reg | (val << WM8350_OUT1R_VOL_SHIFT));
202 } else
203 right_complete = 1;
204 }
205
206 /* only hit the update bit if either volume has changed this step */
207 if (!left_complete || !right_complete)
208 wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME, WM8350_OUT2_VU);
209
210 return left_complete & right_complete;
211}
212
213/*
214 * This work ramps both output PGAs at stream start/stop time to
215 * minimise pop associated with DAPM power switching.
216 * It's best to enable Zero Cross when ramping occurs to minimise any
217 * zipper noises.
218 */
219static void wm8350_pga_work(struct work_struct *work)
220{
221 struct snd_soc_codec *codec =
222 container_of(work, struct snd_soc_codec, delayed_work.work);
223 struct wm8350_data *wm8350_data = codec->private_data;
224 struct wm8350_output *out1 = &wm8350_data->out1,
225 *out2 = &wm8350_data->out2;
226 int i, out1_complete, out2_complete;
227
228 /* do we need to ramp at all ? */
229 if (out1->ramp == WM8350_RAMP_NONE && out2->ramp == WM8350_RAMP_NONE)
230 return;
231
232 /* PGA volumes have 6 bits of resolution to ramp */
233 for (i = 0; i <= 63; i++) {
234 out1_complete = 1, out2_complete = 1;
235 if (out1->ramp != WM8350_RAMP_NONE)
236 out1_complete = wm8350_out1_ramp_step(codec);
237 if (out2->ramp != WM8350_RAMP_NONE)
238 out2_complete = wm8350_out2_ramp_step(codec);
239
240 /* ramp finished ? */
241 if (out1_complete && out2_complete)
242 break;
243
244 /* we need to delay longer on the up ramp */
245 if (out1->ramp == WM8350_RAMP_UP ||
246 out2->ramp == WM8350_RAMP_UP) {
247 /* delay is longer over 0dB as increases are larger */
248 if (i >= WM8350_OUTn_0dB)
249 schedule_timeout_interruptible(msecs_to_jiffies
250 (2));
251 else
252 schedule_timeout_interruptible(msecs_to_jiffies
253 (1));
254 } else
255 udelay(50); /* doesn't matter if we delay longer */
256 }
257
258 out1->ramp = WM8350_RAMP_NONE;
259 out2->ramp = WM8350_RAMP_NONE;
260}
261
262/*
263 * WM8350 Controls
264 */
265
266static int pga_event(struct snd_soc_dapm_widget *w,
267 struct snd_kcontrol *kcontrol, int event)
268{
269 struct snd_soc_codec *codec = w->codec;
270 struct wm8350_data *wm8350_data = codec->private_data;
271 struct wm8350_output *out;
272
273 switch (w->shift) {
274 case 0:
275 case 1:
276 out = &wm8350_data->out1;
277 break;
278 case 2:
279 case 3:
280 out = &wm8350_data->out2;
281 break;
282
283 default:
284 BUG();
285 return -1;
286 }
287
288 switch (event) {
289 case SND_SOC_DAPM_POST_PMU:
290 out->ramp = WM8350_RAMP_UP;
291 out->active = 1;
292
293 if (!delayed_work_pending(&codec->delayed_work))
294 schedule_delayed_work(&codec->delayed_work,
295 msecs_to_jiffies(1));
296 break;
297
298 case SND_SOC_DAPM_PRE_PMD:
299 out->ramp = WM8350_RAMP_DOWN;
300 out->active = 0;
301
302 if (!delayed_work_pending(&codec->delayed_work))
303 schedule_delayed_work(&codec->delayed_work,
304 msecs_to_jiffies(1));
305 break;
306 }
307
308 return 0;
309}
310
311static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
312 struct snd_ctl_elem_value *ucontrol)
313{
314 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
315 struct wm8350_data *wm8350_priv = codec->private_data;
316 struct wm8350_output *out = NULL;
317 struct soc_mixer_control *mc =
318 (struct soc_mixer_control *)kcontrol->private_value;
319 int ret;
320 unsigned int reg = mc->reg;
321 u16 val;
322
323 /* For OUT1 and OUT2 we shadow the values and only actually write
324 * them out when active in order to ensure the amplifier comes on
325 * as quietly as possible. */
326 switch (reg) {
327 case WM8350_LOUT1_VOLUME:
328 out = &wm8350_priv->out1;
329 break;
330 case WM8350_LOUT2_VOLUME:
331 out = &wm8350_priv->out2;
332 break;
333 default:
334 break;
335 }
336
337 if (out) {
338 out->left_vol = ucontrol->value.integer.value[0];
339 out->right_vol = ucontrol->value.integer.value[1];
340 if (!out->active)
341 return 1;
342 }
343
344 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
345 if (ret < 0)
346 return ret;
347
348 /* now hit the volume update bits (always bit 8) */
349 val = wm8350_codec_read(codec, reg);
350 wm8350_codec_write(codec, reg, val | WM8350_OUT1_VU);
351 return 1;
352}
353
354static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol,
355 struct snd_ctl_elem_value *ucontrol)
356{
357 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
358 struct wm8350_data *wm8350_priv = codec->private_data;
359 struct wm8350_output *out1 = &wm8350_priv->out1;
360 struct wm8350_output *out2 = &wm8350_priv->out2;
361 struct soc_mixer_control *mc =
362 (struct soc_mixer_control *)kcontrol->private_value;
363 unsigned int reg = mc->reg;
364
365 /* If these are cached registers use the cache */
366 switch (reg) {
367 case WM8350_LOUT1_VOLUME:
368 ucontrol->value.integer.value[0] = out1->left_vol;
369 ucontrol->value.integer.value[1] = out1->right_vol;
370 return 0;
371
372 case WM8350_LOUT2_VOLUME:
373 ucontrol->value.integer.value[0] = out2->left_vol;
374 ucontrol->value.integer.value[1] = out2->right_vol;
375 return 0;
376
377 default:
378 break;
379 }
380
381 return snd_soc_get_volsw_2r(kcontrol, ucontrol);
382}
383
384/* double control with volume update */
385#define SOC_WM8350_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
386 xinvert, tlv_array) \
387{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
388 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
389 SNDRV_CTL_ELEM_ACCESS_READWRITE | \
390 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
391 .tlv.p = (tlv_array), \
392 .info = snd_soc_info_volsw_2r, \
393 .get = wm8350_get_volsw_2r, .put = wm8350_put_volsw_2r_vu, \
394 .private_value = (unsigned long)&(struct soc_mixer_control) \
395 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
396 .rshift = xshift, .max = xmax, .invert = xinvert}, }
397
398static const char *wm8350_deemp[] = { "None", "32kHz", "44.1kHz", "48kHz" };
399static const char *wm8350_pol[] = { "Normal", "Inv R", "Inv L", "Inv L & R" };
400static const char *wm8350_dacmutem[] = { "Normal", "Soft" };
401static const char *wm8350_dacmutes[] = { "Fast", "Slow" };
402static const char *wm8350_dacfilter[] = { "Normal", "Sloping" };
403static const char *wm8350_adcfilter[] = { "None", "High Pass" };
404static const char *wm8350_adchp[] = { "44.1kHz", "8kHz", "16kHz", "32kHz" };
405static const char *wm8350_lr[] = { "Left", "Right" };
406
407static const struct soc_enum wm8350_enum[] = {
408 SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 4, 4, wm8350_deemp),
409 SOC_ENUM_SINGLE(WM8350_DAC_CONTROL, 0, 4, wm8350_pol),
410 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 14, 2, wm8350_dacmutem),
411 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 13, 2, wm8350_dacmutes),
412 SOC_ENUM_SINGLE(WM8350_DAC_MUTE_VOLUME, 12, 2, wm8350_dacfilter),
413 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 15, 2, wm8350_adcfilter),
414 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 8, 4, wm8350_adchp),
415 SOC_ENUM_SINGLE(WM8350_ADC_CONTROL, 0, 4, wm8350_pol),
416 SOC_ENUM_SINGLE(WM8350_INPUT_MIXER_VOLUME, 15, 2, wm8350_lr),
417};
418
419static DECLARE_TLV_DB_LINEAR(pre_amp_tlv, -1200, 3525);
420static DECLARE_TLV_DB_LINEAR(out_pga_tlv, -5700, 600);
421static DECLARE_TLV_DB_SCALE(dac_pcm_tlv, -7163, 36, 1);
422static DECLARE_TLV_DB_SCALE(adc_pcm_tlv, -12700, 50, 1);
423static DECLARE_TLV_DB_SCALE(out_mix_tlv, -1500, 300, 1);
424
425static const unsigned int capture_sd_tlv[] = {
426 TLV_DB_RANGE_HEAD(2),
427 0, 12, TLV_DB_SCALE_ITEM(-3600, 300, 1),
428 13, 15, TLV_DB_SCALE_ITEM(0, 0, 0),
429};
430
431static const struct snd_kcontrol_new wm8350_snd_controls[] = {
432 SOC_ENUM("Playback Deemphasis", wm8350_enum[0]),
433 SOC_ENUM("Playback DAC Inversion", wm8350_enum[1]),
434 SOC_WM8350_DOUBLE_R_TLV("Playback PCM Volume",
435 WM8350_DAC_DIGITAL_VOLUME_L,
436 WM8350_DAC_DIGITAL_VOLUME_R,
437 0, 255, 0, dac_pcm_tlv),
438 SOC_ENUM("Playback PCM Mute Function", wm8350_enum[2]),
439 SOC_ENUM("Playback PCM Mute Speed", wm8350_enum[3]),
440 SOC_ENUM("Playback PCM Filter", wm8350_enum[4]),
441 SOC_ENUM("Capture PCM Filter", wm8350_enum[5]),
442 SOC_ENUM("Capture PCM HP Filter", wm8350_enum[6]),
443 SOC_ENUM("Capture ADC Inversion", wm8350_enum[7]),
444 SOC_WM8350_DOUBLE_R_TLV("Capture PCM Volume",
445 WM8350_ADC_DIGITAL_VOLUME_L,
446 WM8350_ADC_DIGITAL_VOLUME_R,
447 0, 255, 0, adc_pcm_tlv),
448 SOC_DOUBLE_TLV("Capture Sidetone Volume",
449 WM8350_ADC_DIVIDER,
450 8, 4, 15, 1, capture_sd_tlv),
451 SOC_WM8350_DOUBLE_R_TLV("Capture Volume",
452 WM8350_LEFT_INPUT_VOLUME,
453 WM8350_RIGHT_INPUT_VOLUME,
454 2, 63, 0, pre_amp_tlv),
455 SOC_DOUBLE_R("Capture ZC Switch",
456 WM8350_LEFT_INPUT_VOLUME,
457 WM8350_RIGHT_INPUT_VOLUME, 13, 1, 0),
458 SOC_SINGLE_TLV("Left Input Left Sidetone Volume",
459 WM8350_OUTPUT_LEFT_MIXER_VOLUME, 1, 7, 0, out_mix_tlv),
460 SOC_SINGLE_TLV("Left Input Right Sidetone Volume",
461 WM8350_OUTPUT_LEFT_MIXER_VOLUME,
462 5, 7, 0, out_mix_tlv),
463 SOC_SINGLE_TLV("Left Input Bypass Volume",
464 WM8350_OUTPUT_LEFT_MIXER_VOLUME,
465 9, 7, 0, out_mix_tlv),
466 SOC_SINGLE_TLV("Right Input Left Sidetone Volume",
467 WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
468 1, 7, 0, out_mix_tlv),
469 SOC_SINGLE_TLV("Right Input Right Sidetone Volume",
470 WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
471 5, 7, 0, out_mix_tlv),
472 SOC_SINGLE_TLV("Right Input Bypass Volume",
473 WM8350_OUTPUT_RIGHT_MIXER_VOLUME,
474 13, 7, 0, out_mix_tlv),
475 SOC_SINGLE("Left Input Mixer +20dB Switch",
476 WM8350_INPUT_MIXER_VOLUME_L, 0, 1, 0),
477 SOC_SINGLE("Right Input Mixer +20dB Switch",
478 WM8350_INPUT_MIXER_VOLUME_R, 0, 1, 0),
479 SOC_SINGLE_TLV("Out4 Capture Volume",
480 WM8350_INPUT_MIXER_VOLUME,
481 1, 7, 0, out_mix_tlv),
482 SOC_WM8350_DOUBLE_R_TLV("Out1 Playback Volume",
483 WM8350_LOUT1_VOLUME,
484 WM8350_ROUT1_VOLUME,
485 2, 63, 0, out_pga_tlv),
486 SOC_DOUBLE_R("Out1 Playback ZC Switch",
487 WM8350_LOUT1_VOLUME,
488 WM8350_ROUT1_VOLUME, 13, 1, 0),
489 SOC_WM8350_DOUBLE_R_TLV("Out2 Playback Volume",
490 WM8350_LOUT2_VOLUME,
491 WM8350_ROUT2_VOLUME,
492 2, 63, 0, out_pga_tlv),
493 SOC_DOUBLE_R("Out2 Playback ZC Switch", WM8350_LOUT2_VOLUME,
494 WM8350_ROUT2_VOLUME, 13, 1, 0),
495 SOC_SINGLE("Out2 Right Invert Switch", WM8350_ROUT2_VOLUME, 10, 1, 0),
496 SOC_SINGLE_TLV("Out2 Beep Volume", WM8350_BEEP_VOLUME,
497 5, 7, 0, out_mix_tlv),
498
499 SOC_DOUBLE_R("Out1 Playback Switch",
500 WM8350_LOUT1_VOLUME,
501 WM8350_ROUT1_VOLUME,
502 14, 1, 1),
503 SOC_DOUBLE_R("Out2 Playback Switch",
504 WM8350_LOUT2_VOLUME,
505 WM8350_ROUT2_VOLUME,
506 14, 1, 1),
507};
508
509/*
510 * DAPM Controls
511 */
512
513/* Left Playback Mixer */
514static const struct snd_kcontrol_new wm8350_left_play_mixer_controls[] = {
515 SOC_DAPM_SINGLE("Playback Switch",
516 WM8350_LEFT_MIXER_CONTROL, 11, 1, 0),
517 SOC_DAPM_SINGLE("Left Bypass Switch",
518 WM8350_LEFT_MIXER_CONTROL, 2, 1, 0),
519 SOC_DAPM_SINGLE("Right Playback Switch",
520 WM8350_LEFT_MIXER_CONTROL, 12, 1, 0),
521 SOC_DAPM_SINGLE("Left Sidetone Switch",
522 WM8350_LEFT_MIXER_CONTROL, 0, 1, 0),
523 SOC_DAPM_SINGLE("Right Sidetone Switch",
524 WM8350_LEFT_MIXER_CONTROL, 1, 1, 0),
525};
526
527/* Right Playback Mixer */
528static const struct snd_kcontrol_new wm8350_right_play_mixer_controls[] = {
529 SOC_DAPM_SINGLE("Playback Switch",
530 WM8350_RIGHT_MIXER_CONTROL, 12, 1, 0),
531 SOC_DAPM_SINGLE("Right Bypass Switch",
532 WM8350_RIGHT_MIXER_CONTROL, 3, 1, 0),
533 SOC_DAPM_SINGLE("Left Playback Switch",
534 WM8350_RIGHT_MIXER_CONTROL, 11, 1, 0),
535 SOC_DAPM_SINGLE("Left Sidetone Switch",
536 WM8350_RIGHT_MIXER_CONTROL, 0, 1, 0),
537 SOC_DAPM_SINGLE("Right Sidetone Switch",
538 WM8350_RIGHT_MIXER_CONTROL, 1, 1, 0),
539};
540
541/* Out4 Mixer */
542static const struct snd_kcontrol_new wm8350_out4_mixer_controls[] = {
543 SOC_DAPM_SINGLE("Right Playback Switch",
544 WM8350_OUT4_MIXER_CONTROL, 12, 1, 0),
545 SOC_DAPM_SINGLE("Left Playback Switch",
546 WM8350_OUT4_MIXER_CONTROL, 11, 1, 0),
547 SOC_DAPM_SINGLE("Right Capture Switch",
548 WM8350_OUT4_MIXER_CONTROL, 9, 1, 0),
549 SOC_DAPM_SINGLE("Out3 Playback Switch",
550 WM8350_OUT4_MIXER_CONTROL, 2, 1, 0),
551 SOC_DAPM_SINGLE("Right Mixer Switch",
552 WM8350_OUT4_MIXER_CONTROL, 1, 1, 0),
553 SOC_DAPM_SINGLE("Left Mixer Switch",
554 WM8350_OUT4_MIXER_CONTROL, 0, 1, 0),
555};
556
557/* Out3 Mixer */
558static const struct snd_kcontrol_new wm8350_out3_mixer_controls[] = {
559 SOC_DAPM_SINGLE("Left Playback Switch",
560 WM8350_OUT3_MIXER_CONTROL, 11, 1, 0),
561 SOC_DAPM_SINGLE("Left Capture Switch",
562 WM8350_OUT3_MIXER_CONTROL, 8, 1, 0),
563 SOC_DAPM_SINGLE("Out4 Playback Switch",
564 WM8350_OUT3_MIXER_CONTROL, 3, 1, 0),
565 SOC_DAPM_SINGLE("Left Mixer Switch",
566 WM8350_OUT3_MIXER_CONTROL, 0, 1, 0),
567};
568
569/* Left Input Mixer */
570static const struct snd_kcontrol_new wm8350_left_capt_mixer_controls[] = {
571 SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
572 WM8350_INPUT_MIXER_VOLUME_L, 1, 7, 0, out_mix_tlv),
573 SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
574 WM8350_INPUT_MIXER_VOLUME_L, 9, 7, 0, out_mix_tlv),
575 SOC_DAPM_SINGLE("PGA Capture Switch",
576 WM8350_LEFT_INPUT_VOLUME, 14, 1, 0),
577};
578
579/* Right Input Mixer */
580static const struct snd_kcontrol_new wm8350_right_capt_mixer_controls[] = {
581 SOC_DAPM_SINGLE_TLV("L2 Capture Volume",
582 WM8350_INPUT_MIXER_VOLUME_R, 5, 7, 0, out_mix_tlv),
583 SOC_DAPM_SINGLE_TLV("L3 Capture Volume",
584 WM8350_INPUT_MIXER_VOLUME_R, 13, 7, 0, out_mix_tlv),
585 SOC_DAPM_SINGLE("PGA Capture Switch",
586 WM8350_RIGHT_INPUT_VOLUME, 14, 1, 0),
587};
588
589/* Left Mic Mixer */
590static const struct snd_kcontrol_new wm8350_left_mic_mixer_controls[] = {
591 SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 1, 1, 0),
592 SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 0, 1, 0),
593 SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 2, 1, 0),
594};
595
596/* Right Mic Mixer */
597static const struct snd_kcontrol_new wm8350_right_mic_mixer_controls[] = {
598 SOC_DAPM_SINGLE("INN Capture Switch", WM8350_INPUT_CONTROL, 9, 1, 0),
599 SOC_DAPM_SINGLE("INP Capture Switch", WM8350_INPUT_CONTROL, 8, 1, 0),
600 SOC_DAPM_SINGLE("IN2 Capture Switch", WM8350_INPUT_CONTROL, 10, 1, 0),
601};
602
603/* Beep Switch */
604static const struct snd_kcontrol_new wm8350_beep_switch_controls =
605SOC_DAPM_SINGLE("Switch", WM8350_BEEP_VOLUME, 15, 1, 1);
606
607/* Out4 Capture Mux */
608static const struct snd_kcontrol_new wm8350_out4_capture_controls =
609SOC_DAPM_ENUM("Route", wm8350_enum[8]);
610
611static const struct snd_soc_dapm_widget wm8350_dapm_widgets[] = {
612
613 SND_SOC_DAPM_PGA("IN3R PGA", WM8350_POWER_MGMT_2, 11, 0, NULL, 0),
614 SND_SOC_DAPM_PGA("IN3L PGA", WM8350_POWER_MGMT_2, 10, 0, NULL, 0),
615 SND_SOC_DAPM_PGA_E("Right Out2 PGA", WM8350_POWER_MGMT_3, 3, 0, NULL,
616 0, pga_event,
617 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
618 SND_SOC_DAPM_PGA_E("Left Out2 PGA", WM8350_POWER_MGMT_3, 2, 0, NULL, 0,
619 pga_event,
620 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
621 SND_SOC_DAPM_PGA_E("Right Out1 PGA", WM8350_POWER_MGMT_3, 1, 0, NULL,
622 0, pga_event,
623 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
624 SND_SOC_DAPM_PGA_E("Left Out1 PGA", WM8350_POWER_MGMT_3, 0, 0, NULL, 0,
625 pga_event,
626 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
627
628 SND_SOC_DAPM_MIXER("Right Capture Mixer", WM8350_POWER_MGMT_2,
629 7, 0, &wm8350_right_capt_mixer_controls[0],
630 ARRAY_SIZE(wm8350_right_capt_mixer_controls)),
631
632 SND_SOC_DAPM_MIXER("Left Capture Mixer", WM8350_POWER_MGMT_2,
633 6, 0, &wm8350_left_capt_mixer_controls[0],
634 ARRAY_SIZE(wm8350_left_capt_mixer_controls)),
635
636 SND_SOC_DAPM_MIXER("Out4 Mixer", WM8350_POWER_MGMT_2, 5, 0,
637 &wm8350_out4_mixer_controls[0],
638 ARRAY_SIZE(wm8350_out4_mixer_controls)),
639
640 SND_SOC_DAPM_MIXER("Out3 Mixer", WM8350_POWER_MGMT_2, 4, 0,
641 &wm8350_out3_mixer_controls[0],
642 ARRAY_SIZE(wm8350_out3_mixer_controls)),
643
644 SND_SOC_DAPM_MIXER("Right Playback Mixer", WM8350_POWER_MGMT_2, 1, 0,
645 &wm8350_right_play_mixer_controls[0],
646 ARRAY_SIZE(wm8350_right_play_mixer_controls)),
647
648 SND_SOC_DAPM_MIXER("Left Playback Mixer", WM8350_POWER_MGMT_2, 0, 0,
649 &wm8350_left_play_mixer_controls[0],
650 ARRAY_SIZE(wm8350_left_play_mixer_controls)),
651
652 SND_SOC_DAPM_MIXER("Left Mic Mixer", WM8350_POWER_MGMT_2, 8, 0,
653 &wm8350_left_mic_mixer_controls[0],
654 ARRAY_SIZE(wm8350_left_mic_mixer_controls)),
655
656 SND_SOC_DAPM_MIXER("Right Mic Mixer", WM8350_POWER_MGMT_2, 9, 0,
657 &wm8350_right_mic_mixer_controls[0],
658 ARRAY_SIZE(wm8350_right_mic_mixer_controls)),
659
660 /* virtual mixer for Beep and Out2R */
661 SND_SOC_DAPM_MIXER("Out2 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
662
663 SND_SOC_DAPM_SWITCH("Beep", WM8350_POWER_MGMT_3, 7, 0,
664 &wm8350_beep_switch_controls),
665
666 SND_SOC_DAPM_ADC("Right ADC", "Right Capture",
667 WM8350_POWER_MGMT_4, 3, 0),
668 SND_SOC_DAPM_ADC("Left ADC", "Left Capture",
669 WM8350_POWER_MGMT_4, 2, 0),
670 SND_SOC_DAPM_DAC("Right DAC", "Right Playback",
671 WM8350_POWER_MGMT_4, 5, 0),
672 SND_SOC_DAPM_DAC("Left DAC", "Left Playback",
673 WM8350_POWER_MGMT_4, 4, 0),
674
675 SND_SOC_DAPM_MICBIAS("Mic Bias", WM8350_POWER_MGMT_1, 4, 0),
676
677 SND_SOC_DAPM_MUX("Out4 Capture Channel", SND_SOC_NOPM, 0, 0,
678 &wm8350_out4_capture_controls),
679
680 SND_SOC_DAPM_OUTPUT("OUT1R"),
681 SND_SOC_DAPM_OUTPUT("OUT1L"),
682 SND_SOC_DAPM_OUTPUT("OUT2R"),
683 SND_SOC_DAPM_OUTPUT("OUT2L"),
684 SND_SOC_DAPM_OUTPUT("OUT3"),
685 SND_SOC_DAPM_OUTPUT("OUT4"),
686
687 SND_SOC_DAPM_INPUT("IN1RN"),
688 SND_SOC_DAPM_INPUT("IN1RP"),
689 SND_SOC_DAPM_INPUT("IN2R"),
690 SND_SOC_DAPM_INPUT("IN1LP"),
691 SND_SOC_DAPM_INPUT("IN1LN"),
692 SND_SOC_DAPM_INPUT("IN2L"),
693 SND_SOC_DAPM_INPUT("IN3R"),
694 SND_SOC_DAPM_INPUT("IN3L"),
695};
696
697static const struct snd_soc_dapm_route audio_map[] = {
698
699 /* left playback mixer */
700 {"Left Playback Mixer", "Playback Switch", "Left DAC"},
701 {"Left Playback Mixer", "Left Bypass Switch", "IN3L PGA"},
702 {"Left Playback Mixer", "Right Playback Switch", "Right DAC"},
703 {"Left Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
704 {"Left Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
705
706 /* right playback mixer */
707 {"Right Playback Mixer", "Playback Switch", "Right DAC"},
708 {"Right Playback Mixer", "Right Bypass Switch", "IN3R PGA"},
709 {"Right Playback Mixer", "Left Playback Switch", "Left DAC"},
710 {"Right Playback Mixer", "Left Sidetone Switch", "Left Mic Mixer"},
711 {"Right Playback Mixer", "Right Sidetone Switch", "Right Mic Mixer"},
712
713 /* out4 playback mixer */
714 {"Out4 Mixer", "Right Playback Switch", "Right DAC"},
715 {"Out4 Mixer", "Left Playback Switch", "Left DAC"},
716 {"Out4 Mixer", "Right Capture Switch", "Right Capture Mixer"},
717 {"Out4 Mixer", "Out3 Playback Switch", "Out3 Mixer"},
718 {"Out4 Mixer", "Right Mixer Switch", "Right Playback Mixer"},
719 {"Out4 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
720 {"OUT4", NULL, "Out4 Mixer"},
721
722 /* out3 playback mixer */
723 {"Out3 Mixer", "Left Playback Switch", "Left DAC"},
724 {"Out3 Mixer", "Left Capture Switch", "Left Capture Mixer"},
725 {"Out3 Mixer", "Left Mixer Switch", "Left Playback Mixer"},
726 {"Out3 Mixer", "Out4 Playback Switch", "Out4 Mixer"},
727 {"OUT3", NULL, "Out3 Mixer"},
728
729 /* out2 */
730 {"Right Out2 PGA", NULL, "Right Playback Mixer"},
731 {"Left Out2 PGA", NULL, "Left Playback Mixer"},
732 {"OUT2L", NULL, "Left Out2 PGA"},
733 {"OUT2R", NULL, "Right Out2 PGA"},
734
735 /* out1 */
736 {"Right Out1 PGA", NULL, "Right Playback Mixer"},
737 {"Left Out1 PGA", NULL, "Left Playback Mixer"},
738 {"OUT1L", NULL, "Left Out1 PGA"},
739 {"OUT1R", NULL, "Right Out1 PGA"},
740
741 /* ADCs */
742 {"Left ADC", NULL, "Left Capture Mixer"},
743 {"Right ADC", NULL, "Right Capture Mixer"},
744
745 /* Left capture mixer */
746 {"Left Capture Mixer", "L2 Capture Volume", "IN2L"},
747 {"Left Capture Mixer", "L3 Capture Volume", "IN3L PGA"},
748 {"Left Capture Mixer", "PGA Capture Switch", "Left Mic Mixer"},
749 {"Left Capture Mixer", NULL, "Out4 Capture Channel"},
750
751 /* Right capture mixer */
752 {"Right Capture Mixer", "L2 Capture Volume", "IN2R"},
753 {"Right Capture Mixer", "L3 Capture Volume", "IN3R PGA"},
754 {"Right Capture Mixer", "PGA Capture Switch", "Right Mic Mixer"},
755 {"Right Capture Mixer", NULL, "Out4 Capture Channel"},
756
757 /* L3 Inputs */
758 {"IN3L PGA", NULL, "IN3L"},
759 {"IN3R PGA", NULL, "IN3R"},
760
761 /* Left Mic mixer */
762 {"Left Mic Mixer", "INN Capture Switch", "IN1LN"},
763 {"Left Mic Mixer", "INP Capture Switch", "IN1LP"},
764 {"Left Mic Mixer", "IN2 Capture Switch", "IN2L"},
765
766 /* Right Mic mixer */
767 {"Right Mic Mixer", "INN Capture Switch", "IN1RN"},
768 {"Right Mic Mixer", "INP Capture Switch", "IN1RP"},
769 {"Right Mic Mixer", "IN2 Capture Switch", "IN2R"},
770
771 /* out 4 capture */
772 {"Out4 Capture Channel", NULL, "Out4 Mixer"},
773
774 /* Beep */
775 {"Beep", NULL, "IN3R PGA"},
776};
777
778static int wm8350_add_controls(struct snd_soc_codec *codec)
779{
780 int err, i;
781
782 for (i = 0; i < ARRAY_SIZE(wm8350_snd_controls); i++) {
783 err = snd_ctl_add(codec->card,
784 snd_soc_cnew(&wm8350_snd_controls[i],
785 codec, NULL));
786 if (err < 0)
787 return err;
788 }
789
790 return 0;
791}
792
793static int wm8350_add_widgets(struct snd_soc_codec *codec)
794{
795 int ret;
796
797 ret = snd_soc_dapm_new_controls(codec,
798 wm8350_dapm_widgets,
799 ARRAY_SIZE(wm8350_dapm_widgets));
800 if (ret != 0) {
801 dev_err(codec->dev, "dapm control register failed\n");
802 return ret;
803 }
804
805 /* set up audio paths */
806 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
807 if (ret != 0) {
808 dev_err(codec->dev, "DAPM route register failed\n");
809 return ret;
810 }
811
812 return snd_soc_dapm_new_widgets(codec);
813}
814
815static int wm8350_set_dai_sysclk(struct snd_soc_dai *codec_dai,
816 int clk_id, unsigned int freq, int dir)
817{
818 struct snd_soc_codec *codec = codec_dai->codec;
819 struct wm8350 *wm8350 = codec->control_data;
820 u16 fll_4;
821
822 switch (clk_id) {
823 case WM8350_MCLK_SEL_MCLK:
824 wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_1,
825 WM8350_MCLK_SEL);
826 break;
827 case WM8350_MCLK_SEL_PLL_MCLK:
828 case WM8350_MCLK_SEL_PLL_DAC:
829 case WM8350_MCLK_SEL_PLL_ADC:
830 case WM8350_MCLK_SEL_PLL_32K:
831 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_1,
832 WM8350_MCLK_SEL);
833 fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) &
834 ~WM8350_FLL_CLK_SRC_MASK;
835 wm8350_codec_write(codec, WM8350_FLL_CONTROL_4, fll_4 | clk_id);
836 break;
837 }
838
839 /* MCLK direction */
840 if (dir == WM8350_MCLK_DIR_OUT)
841 wm8350_set_bits(wm8350, WM8350_CLOCK_CONTROL_2,
842 WM8350_MCLK_DIR);
843 else
844 wm8350_clear_bits(wm8350, WM8350_CLOCK_CONTROL_2,
845 WM8350_MCLK_DIR);
846
847 return 0;
848}
849
850static int wm8350_set_clkdiv(struct snd_soc_dai *codec_dai, int div_id, int div)
851{
852 struct snd_soc_codec *codec = codec_dai->codec;
853 u16 val;
854
855 switch (div_id) {
856 case WM8350_ADC_CLKDIV:
857 val = wm8350_codec_read(codec, WM8350_ADC_DIVIDER) &
858 ~WM8350_ADC_CLKDIV_MASK;
859 wm8350_codec_write(codec, WM8350_ADC_DIVIDER, val | div);
860 break;
861 case WM8350_DAC_CLKDIV:
862 val = wm8350_codec_read(codec, WM8350_DAC_CLOCK_CONTROL) &
863 ~WM8350_DAC_CLKDIV_MASK;
864 wm8350_codec_write(codec, WM8350_DAC_CLOCK_CONTROL, val | div);
865 break;
866 case WM8350_BCLK_CLKDIV:
867 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
868 ~WM8350_BCLK_DIV_MASK;
869 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
870 break;
871 case WM8350_OPCLK_CLKDIV:
872 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
873 ~WM8350_OPCLK_DIV_MASK;
874 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
875 break;
876 case WM8350_SYS_CLKDIV:
877 val = wm8350_codec_read(codec, WM8350_CLOCK_CONTROL_1) &
878 ~WM8350_MCLK_DIV_MASK;
879 wm8350_codec_write(codec, WM8350_CLOCK_CONTROL_1, val | div);
880 break;
881 case WM8350_DACLR_CLKDIV:
882 val = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) &
883 ~WM8350_DACLRC_RATE_MASK;
884 wm8350_codec_write(codec, WM8350_DAC_LR_RATE, val | div);
885 break;
886 case WM8350_ADCLR_CLKDIV:
887 val = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) &
888 ~WM8350_ADCLRC_RATE_MASK;
889 wm8350_codec_write(codec, WM8350_ADC_LR_RATE, val | div);
890 break;
891 default:
892 return -EINVAL;
893 }
894
895 return 0;
896}
897
898static int wm8350_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
899{
900 struct snd_soc_codec *codec = codec_dai->codec;
901 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
902 ~(WM8350_AIF_BCLK_INV | WM8350_AIF_LRCLK_INV | WM8350_AIF_FMT_MASK);
903 u16 master = wm8350_codec_read(codec, WM8350_AI_DAC_CONTROL) &
904 ~WM8350_BCLK_MSTR;
905 u16 dac_lrc = wm8350_codec_read(codec, WM8350_DAC_LR_RATE) &
906 ~WM8350_DACLRC_ENA;
907 u16 adc_lrc = wm8350_codec_read(codec, WM8350_ADC_LR_RATE) &
908 ~WM8350_ADCLRC_ENA;
909
910 /* set master/slave audio interface */
911 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
912 case SND_SOC_DAIFMT_CBM_CFM:
913 master |= WM8350_BCLK_MSTR;
914 dac_lrc |= WM8350_DACLRC_ENA;
915 adc_lrc |= WM8350_ADCLRC_ENA;
916 break;
917 case SND_SOC_DAIFMT_CBS_CFS:
918 break;
919 default:
920 return -EINVAL;
921 }
922
923 /* interface format */
924 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
925 case SND_SOC_DAIFMT_I2S:
926 iface |= 0x2 << 8;
927 break;
928 case SND_SOC_DAIFMT_RIGHT_J:
929 break;
930 case SND_SOC_DAIFMT_LEFT_J:
931 iface |= 0x1 << 8;
932 break;
933 case SND_SOC_DAIFMT_DSP_A:
934 iface |= 0x3 << 8;
935 break;
936 case SND_SOC_DAIFMT_DSP_B:
937 iface |= 0x3 << 8; /* lg not sure which mode */
938 break;
939 default:
940 return -EINVAL;
941 }
942
943 /* clock inversion */
944 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
945 case SND_SOC_DAIFMT_NB_NF:
946 break;
947 case SND_SOC_DAIFMT_IB_IF:
948 iface |= WM8350_AIF_LRCLK_INV | WM8350_AIF_BCLK_INV;
949 break;
950 case SND_SOC_DAIFMT_IB_NF:
951 iface |= WM8350_AIF_BCLK_INV;
952 break;
953 case SND_SOC_DAIFMT_NB_IF:
954 iface |= WM8350_AIF_LRCLK_INV;
955 break;
956 default:
957 return -EINVAL;
958 }
959
960 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
961 wm8350_codec_write(codec, WM8350_AI_DAC_CONTROL, master);
962 wm8350_codec_write(codec, WM8350_DAC_LR_RATE, dac_lrc);
963 wm8350_codec_write(codec, WM8350_ADC_LR_RATE, adc_lrc);
964 return 0;
965}
966
967static int wm8350_pcm_trigger(struct snd_pcm_substream *substream,
968 int cmd, struct snd_soc_dai *codec_dai)
969{
970 struct snd_soc_codec *codec = codec_dai->codec;
971 int master = wm8350_codec_cache_read(codec, WM8350_AI_DAC_CONTROL) &
972 WM8350_BCLK_MSTR;
973 int enabled = 0;
974
975 /* Check that the DACs or ADCs are enabled since they are
976 * required for LRC in master mode. The DACs or ADCs need a
977 * valid audio path i.e. pin -> ADC or DAC -> pin before
978 * the LRC will be enabled in master mode. */
979 if (!master && cmd != SNDRV_PCM_TRIGGER_START)
980 return 0;
981
982 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
983 enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
984 (WM8350_ADCR_ENA | WM8350_ADCL_ENA);
985 } else {
986 enabled = wm8350_codec_cache_read(codec, WM8350_POWER_MGMT_4) &
987 (WM8350_DACR_ENA | WM8350_DACL_ENA);
988 }
989
990 if (!enabled) {
991 dev_err(codec->dev,
992 "%s: invalid audio path - no clocks available\n",
993 __func__);
994 return -EINVAL;
995 }
996 return 0;
997}
998
999static int wm8350_pcm_hw_params(struct snd_pcm_substream *substream,
1000 struct snd_pcm_hw_params *params,
1001 struct snd_soc_dai *codec_dai)
1002{
1003 struct snd_soc_codec *codec = codec_dai->codec;
1004 u16 iface = wm8350_codec_read(codec, WM8350_AI_FORMATING) &
1005 ~WM8350_AIF_WL_MASK;
1006
1007 /* bit size */
1008 switch (params_format(params)) {
1009 case SNDRV_PCM_FORMAT_S16_LE:
1010 break;
1011 case SNDRV_PCM_FORMAT_S20_3LE:
1012 iface |= 0x1 << 10;
1013 break;
1014 case SNDRV_PCM_FORMAT_S24_LE:
1015 iface |= 0x2 << 10;
1016 break;
1017 case SNDRV_PCM_FORMAT_S32_LE:
1018 iface |= 0x3 << 10;
1019 break;
1020 }
1021
1022 wm8350_codec_write(codec, WM8350_AI_FORMATING, iface);
1023 return 0;
1024}
1025
1026static int wm8350_mute(struct snd_soc_dai *dai, int mute)
1027{
1028 struct snd_soc_codec *codec = dai->codec;
1029 struct wm8350 *wm8350 = codec->control_data;
1030
1031 if (mute)
1032 wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
1033 else
1034 wm8350_clear_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
1035 return 0;
1036}
1037
1038/* FLL divisors */
1039struct _fll_div {
1040 int div; /* FLL_OUTDIV */
1041 int n;
1042 int k;
1043 int ratio; /* FLL_FRATIO */
1044};
1045
1046/* The size in bits of the fll divide multiplied by 10
1047 * to allow rounding later */
1048#define FIXED_FLL_SIZE ((1 << 16) * 10)
1049
1050static inline int fll_factors(struct _fll_div *fll_div, unsigned int input,
1051 unsigned int output)
1052{
1053 u64 Kpart;
1054 unsigned int t1, t2, K, Nmod;
1055
1056 if (output >= 2815250 && output <= 3125000)
1057 fll_div->div = 0x4;
1058 else if (output >= 5625000 && output <= 6250000)
1059 fll_div->div = 0x3;
1060 else if (output >= 11250000 && output <= 12500000)
1061 fll_div->div = 0x2;
1062 else if (output >= 22500000 && output <= 25000000)
1063 fll_div->div = 0x1;
1064 else {
1065 printk(KERN_ERR "wm8350: fll freq %d out of range\n", output);
1066 return -EINVAL;
1067 }
1068
1069 if (input > 48000)
1070 fll_div->ratio = 1;
1071 else
1072 fll_div->ratio = 8;
1073
1074 t1 = output * (1 << (fll_div->div + 1));
1075 t2 = input * fll_div->ratio;
1076
1077 fll_div->n = t1 / t2;
1078 Nmod = t1 % t2;
1079
1080 if (Nmod) {
1081 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1082 do_div(Kpart, t2);
1083 K = Kpart & 0xFFFFFFFF;
1084
1085 /* Check if we need to round */
1086 if ((K % 10) >= 5)
1087 K += 5;
1088
1089 /* Move down to proper range now rounding is done */
1090 K /= 10;
1091 fll_div->k = K;
1092 } else
1093 fll_div->k = 0;
1094
1095 return 0;
1096}
1097
1098static int wm8350_set_fll(struct snd_soc_dai *codec_dai,
1099 int pll_id, unsigned int freq_in,
1100 unsigned int freq_out)
1101{
1102 struct snd_soc_codec *codec = codec_dai->codec;
1103 struct wm8350 *wm8350 = codec->control_data;
1104 struct _fll_div fll_div;
1105 int ret = 0;
1106 u16 fll_1, fll_4;
1107
1108 /* power down FLL - we need to do this for reconfiguration */
1109 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
1110 WM8350_FLL_ENA | WM8350_FLL_OSC_ENA);
1111
1112 if (freq_out == 0 || freq_in == 0)
1113 return ret;
1114
1115 ret = fll_factors(&fll_div, freq_in, freq_out);
1116 if (ret < 0)
1117 return ret;
1118 dev_dbg(wm8350->dev,
1119 "FLL in %d FLL out %d N 0x%x K 0x%x div %d ratio %d",
1120 freq_in, freq_out, fll_div.n, fll_div.k, fll_div.div,
1121 fll_div.ratio);
1122
1123 /* set up N.K & dividers */
1124 fll_1 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_1) &
1125 ~(WM8350_FLL_OUTDIV_MASK | WM8350_FLL_RSP_RATE_MASK | 0xc000);
1126 wm8350_codec_write(codec, WM8350_FLL_CONTROL_1,
1127 fll_1 | (fll_div.div << 8) | 0x50);
1128 wm8350_codec_write(codec, WM8350_FLL_CONTROL_2,
1129 (fll_div.ratio << 11) | (fll_div.
1130 n & WM8350_FLL_N_MASK));
1131 wm8350_codec_write(codec, WM8350_FLL_CONTROL_3, fll_div.k);
1132 fll_4 = wm8350_codec_read(codec, WM8350_FLL_CONTROL_4) &
1133 ~(WM8350_FLL_FRAC | WM8350_FLL_SLOW_LOCK_REF);
1134 wm8350_codec_write(codec, WM8350_FLL_CONTROL_4,
1135 fll_4 | (fll_div.k ? WM8350_FLL_FRAC : 0) |
1136 (fll_div.ratio == 8 ? WM8350_FLL_SLOW_LOCK_REF : 0));
1137
1138 /* power FLL on */
1139 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_OSC_ENA);
1140 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_FLL_ENA);
1141
1142 return 0;
1143}
1144
1145static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1146 enum snd_soc_bias_level level)
1147{
1148 struct wm8350 *wm8350 = codec->control_data;
1149 struct wm8350_data *priv = codec->private_data;
1150 struct wm8350_audio_platform_data *platform =
1151 wm8350->codec.platform_data;
1152 u16 pm1;
1153 int ret;
1154
1155 switch (level) {
1156 case SND_SOC_BIAS_ON:
1157 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1158 ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
1159 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1160 pm1 | WM8350_VMID_50K |
1161 platform->codec_current_on << 14);
1162 break;
1163
1164 case SND_SOC_BIAS_PREPARE:
1165 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1);
1166 pm1 &= ~WM8350_VMID_MASK;
1167 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1168 pm1 | WM8350_VMID_50K);
1169 break;
1170
1171 case SND_SOC_BIAS_STANDBY:
1172 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1173 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
1174 priv->supplies);
1175 if (ret != 0)
1176 return ret;
1177
1178 /* Enable the system clock */
1179 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4,
1180 WM8350_SYSCLK_ENA);
1181
1182 /* mute DAC & outputs */
1183 wm8350_set_bits(wm8350, WM8350_DAC_MUTE,
1184 WM8350_DAC_MUTE_ENA);
1185
1186 /* discharge cap memory */
1187 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1188 platform->dis_out1 |
1189 (platform->dis_out2 << 2) |
1190 (platform->dis_out3 << 4) |
1191 (platform->dis_out4 << 6));
1192
1193 /* wait for discharge */
1194 schedule_timeout_interruptible(msecs_to_jiffies
1195 (platform->
1196 cap_discharge_msecs));
1197
1198 /* enable antipop */
1199 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1200 (platform->vmid_s_curve << 8));
1201
1202 /* ramp up vmid */
1203 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1204 (platform->
1205 codec_current_charge << 14) |
1206 WM8350_VMID_5K | WM8350_VMIDEN |
1207 WM8350_VBUFEN);
1208
1209 /* wait for vmid */
1210 schedule_timeout_interruptible(msecs_to_jiffies
1211 (platform->
1212 vmid_charge_msecs));
1213
1214 /* turn on vmid 300k */
1215 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1216 ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
1217 pm1 |= WM8350_VMID_300K |
1218 (platform->codec_current_standby << 14);
1219 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1220 pm1);
1221
1222
1223 /* enable analogue bias */
1224 pm1 |= WM8350_BIASEN;
1225 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
1226
1227 /* disable antipop */
1228 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
1229
1230 } else {
1231 /* turn on vmid 300k and reduce current */
1232 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1233 ~(WM8350_VMID_MASK | WM8350_CODEC_ISEL_MASK);
1234 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1235 pm1 | WM8350_VMID_300K |
1236 (platform->
1237 codec_current_standby << 14));
1238
1239 }
1240 break;
1241
1242 case SND_SOC_BIAS_OFF:
1243
1244 /* mute DAC & enable outputs */
1245 wm8350_set_bits(wm8350, WM8350_DAC_MUTE, WM8350_DAC_MUTE_ENA);
1246
1247 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_3,
1248 WM8350_OUT1L_ENA | WM8350_OUT1R_ENA |
1249 WM8350_OUT2L_ENA | WM8350_OUT2R_ENA);
1250
1251 /* enable anti pop S curve */
1252 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1253 (platform->vmid_s_curve << 8));
1254
1255 /* turn off vmid */
1256 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1257 ~WM8350_VMIDEN;
1258 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
1259
1260 /* wait */
1261 schedule_timeout_interruptible(msecs_to_jiffies
1262 (platform->
1263 vmid_discharge_msecs));
1264
1265 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL,
1266 (platform->vmid_s_curve << 8) |
1267 platform->dis_out1 |
1268 (platform->dis_out2 << 2) |
1269 (platform->dis_out3 << 4) |
1270 (platform->dis_out4 << 6));
1271
1272 /* turn off VBuf and drain */
1273 pm1 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_1) &
1274 ~(WM8350_VBUFEN | WM8350_VMID_MASK);
1275 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1,
1276 pm1 | WM8350_OUTPUT_DRAIN_EN);
1277
1278 /* wait */
1279 schedule_timeout_interruptible(msecs_to_jiffies
1280 (platform->drain_msecs));
1281
1282 pm1 &= ~WM8350_BIASEN;
1283 wm8350_reg_write(wm8350, WM8350_POWER_MGMT_1, pm1);
1284
1285 /* disable anti-pop */
1286 wm8350_reg_write(wm8350, WM8350_ANTI_POP_CONTROL, 0);
1287
1288 wm8350_clear_bits(wm8350, WM8350_LOUT1_VOLUME,
1289 WM8350_OUT1L_ENA);
1290 wm8350_clear_bits(wm8350, WM8350_ROUT1_VOLUME,
1291 WM8350_OUT1R_ENA);
1292 wm8350_clear_bits(wm8350, WM8350_LOUT2_VOLUME,
1293 WM8350_OUT2L_ENA);
1294 wm8350_clear_bits(wm8350, WM8350_ROUT2_VOLUME,
1295 WM8350_OUT2R_ENA);
1296
1297 /* disable clock gen */
1298 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4,
1299 WM8350_SYSCLK_ENA);
1300
1301 regulator_bulk_disable(ARRAY_SIZE(priv->supplies),
1302 priv->supplies);
1303 break;
1304 }
1305 codec->bias_level = level;
1306 return 0;
1307}
1308
1309static int wm8350_suspend(struct platform_device *pdev, pm_message_t state)
1310{
1311 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1312 struct snd_soc_codec *codec = socdev->codec;
1313
1314 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1315 return 0;
1316}
1317
1318static int wm8350_resume(struct platform_device *pdev)
1319{
1320 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1321 struct snd_soc_codec *codec = socdev->codec;
1322
1323 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1324
1325 if (codec->suspend_bias_level == SND_SOC_BIAS_ON)
1326 wm8350_set_bias_level(codec, SND_SOC_BIAS_ON);
1327
1328 return 0;
1329}
1330
1331static struct snd_soc_codec *wm8350_codec;
1332
1333static int wm8350_probe(struct platform_device *pdev)
1334{
1335 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1336 struct snd_soc_codec *codec;
1337 struct wm8350 *wm8350;
1338 struct wm8350_data *priv;
1339 int ret;
1340 struct wm8350_output *out1;
1341 struct wm8350_output *out2;
1342
1343 BUG_ON(!wm8350_codec);
1344
1345 socdev->codec = wm8350_codec;
1346 codec = socdev->codec;
1347 wm8350 = codec->control_data;
1348 priv = codec->private_data;
1349
1350 /* Enable the codec */
1351 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1352
1353 /* Enable robust clocking mode in ADC */
1354 wm8350_codec_write(codec, WM8350_SECURITY, 0xa7);
1355 wm8350_codec_write(codec, 0xde, 0x13);
1356 wm8350_codec_write(codec, WM8350_SECURITY, 0);
1357
1358 /* read OUT1 & OUT2 volumes */
1359 out1 = &priv->out1;
1360 out2 = &priv->out2;
1361 out1->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME) &
1362 WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
1363 out1->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME) &
1364 WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
1365 out2->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME) &
1366 WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
1367 out2->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME) &
1368 WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
1369 wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME, 0);
1370 wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME, 0);
1371 wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME, 0);
1372 wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME, 0);
1373
1374 /* Latch VU bits & mute */
1375 wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME,
1376 WM8350_OUT1_VU | WM8350_OUT1L_MUTE);
1377 wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME,
1378 WM8350_OUT2_VU | WM8350_OUT2L_MUTE);
1379 wm8350_set_bits(wm8350, WM8350_ROUT1_VOLUME,
1380 WM8350_OUT1_VU | WM8350_OUT1R_MUTE);
1381 wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
1382 WM8350_OUT2_VU | WM8350_OUT2R_MUTE);
1383
1384 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1385 if (ret < 0) {
1386 dev_err(&pdev->dev, "failed to create pcms\n");
1387 return ret;
1388 }
1389
1390 wm8350_add_controls(codec);
1391 wm8350_add_widgets(codec);
1392
1393 wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1394
1395 ret = snd_soc_init_card(socdev);
1396 if (ret < 0) {
1397 dev_err(&pdev->dev, "failed to register card\n");
1398 goto card_err;
1399 }
1400
1401 return 0;
1402
1403card_err:
1404 snd_soc_free_pcms(socdev);
1405 snd_soc_dapm_free(socdev);
1406 return ret;
1407}
1408
1409static int wm8350_remove(struct platform_device *pdev)
1410{
1411 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1412 struct snd_soc_codec *codec = socdev->codec;
1413 struct wm8350 *wm8350 = codec->control_data;
1414 int ret;
1415
1416 /* cancel any work waiting to be queued. */
1417 ret = cancel_delayed_work(&codec->delayed_work);
1418
1419 /* if there was any work waiting then we run it now and
1420 * wait for its completion */
1421 if (ret) {
1422 schedule_delayed_work(&codec->delayed_work, 0);
1423 flush_scheduled_work();
1424 }
1425
1426 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1427
1428 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1429
1430 return 0;
1431}
1432
1433#define WM8350_RATES (SNDRV_PCM_RATE_8000_96000)
1434
1435#define WM8350_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1436 SNDRV_PCM_FMTBIT_S20_3LE |\
1437 SNDRV_PCM_FMTBIT_S24_LE)
1438
1439struct snd_soc_dai wm8350_dai = {
1440 .name = "WM8350",
1441 .playback = {
1442 .stream_name = "Playback",
1443 .channels_min = 1,
1444 .channels_max = 2,
1445 .rates = WM8350_RATES,
1446 .formats = WM8350_FORMATS,
1447 },
1448 .capture = {
1449 .stream_name = "Capture",
1450 .channels_min = 1,
1451 .channels_max = 2,
1452 .rates = WM8350_RATES,
1453 .formats = WM8350_FORMATS,
1454 },
1455 .ops = {
1456 .hw_params = wm8350_pcm_hw_params,
1457 .digital_mute = wm8350_mute,
1458 .trigger = wm8350_pcm_trigger,
1459 .set_fmt = wm8350_set_dai_fmt,
1460 .set_sysclk = wm8350_set_dai_sysclk,
1461 .set_pll = wm8350_set_fll,
1462 .set_clkdiv = wm8350_set_clkdiv,
1463 },
1464};
1465EXPORT_SYMBOL_GPL(wm8350_dai);
1466
1467struct snd_soc_codec_device soc_codec_dev_wm8350 = {
1468 .probe = wm8350_probe,
1469 .remove = wm8350_remove,
1470 .suspend = wm8350_suspend,
1471 .resume = wm8350_resume,
1472};
1473EXPORT_SYMBOL_GPL(soc_codec_dev_wm8350);
1474
1475static int wm8350_codec_probe(struct platform_device *pdev)
1476{
1477 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
1478 struct wm8350_data *priv;
1479 struct snd_soc_codec *codec;
1480 int ret, i;
1481
1482 if (wm8350->codec.platform_data == NULL) {
1483 dev_err(&pdev->dev, "No audio platform data supplied\n");
1484 return -EINVAL;
1485 }
1486
1487 priv = kzalloc(sizeof(struct wm8350_data), GFP_KERNEL);
1488 if (priv == NULL)
1489 return -ENOMEM;
1490
1491 for (i = 0; i < ARRAY_SIZE(supply_names); i++)
1492 priv->supplies[i].supply = supply_names[i];
1493
1494 ret = regulator_bulk_get(wm8350->dev, ARRAY_SIZE(priv->supplies),
1495 priv->supplies);
1496 if (ret != 0)
1497 goto err_priv;
1498
1499 codec = &priv->codec;
1500 wm8350->codec.codec = codec;
1501
1502 wm8350_dai.dev = &pdev->dev;
1503
1504 mutex_init(&codec->mutex);
1505 INIT_LIST_HEAD(&codec->dapm_widgets);
1506 INIT_LIST_HEAD(&codec->dapm_paths);
1507 codec->dev = &pdev->dev;
1508 codec->name = "WM8350";
1509 codec->owner = THIS_MODULE;
1510 codec->read = wm8350_codec_read;
1511 codec->write = wm8350_codec_write;
1512 codec->bias_level = SND_SOC_BIAS_OFF;
1513 codec->set_bias_level = wm8350_set_bias_level;
1514 codec->dai = &wm8350_dai;
1515 codec->num_dai = 1;
1516 codec->reg_cache_size = WM8350_MAX_REGISTER;
1517 codec->private_data = priv;
1518 codec->control_data = wm8350;
1519
1520 /* Put the codec into reset if it wasn't already */
1521 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1522
1523 INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work);
1524 ret = snd_soc_register_codec(codec);
1525 if (ret != 0)
1526 goto err_supply;
1527
1528 wm8350_codec = codec;
1529
1530 ret = snd_soc_register_dai(&wm8350_dai);
1531 if (ret != 0)
1532 goto err_codec;
1533 return 0;
1534
1535err_codec:
1536 snd_soc_unregister_codec(codec);
1537err_supply:
1538 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1539err_priv:
1540 kfree(priv);
1541 wm8350_codec = NULL;
1542 return ret;
1543}
1544
1545static int __devexit wm8350_codec_remove(struct platform_device *pdev)
1546{
1547 struct wm8350 *wm8350 = platform_get_drvdata(pdev);
1548 struct snd_soc_codec *codec = wm8350->codec.codec;
1549 struct wm8350_data *priv = codec->private_data;
1550
1551 snd_soc_unregister_dai(&wm8350_dai);
1552 snd_soc_unregister_codec(codec);
1553 regulator_bulk_free(ARRAY_SIZE(priv->supplies), priv->supplies);
1554 kfree(priv);
1555 wm8350_codec = NULL;
1556 return 0;
1557}
1558
1559static struct platform_driver wm8350_codec_driver = {
1560 .driver = {
1561 .name = "wm8350-codec",
1562 .owner = THIS_MODULE,
1563 },
1564 .probe = wm8350_codec_probe,
1565 .remove = __devexit_p(wm8350_codec_remove),
1566};
1567
1568static __init int wm8350_init(void)
1569{
1570 return platform_driver_register(&wm8350_codec_driver);
1571}
1572module_init(wm8350_init);
1573
1574static __exit void wm8350_exit(void)
1575{
1576 platform_driver_unregister(&wm8350_codec_driver);
1577}
1578module_exit(wm8350_exit);
1579
1580MODULE_DESCRIPTION("ASoC WM8350 driver");
1581MODULE_AUTHOR("Liam Girdwood");
1582MODULE_LICENSE("GPL");
1583MODULE_ALIAS("platform:wm8350-codec");
diff --git a/sound/soc/codecs/wm8350.h b/sound/soc/codecs/wm8350.h
new file mode 100644
index 000000000000..cc2887aa6c38
--- /dev/null
+++ b/sound/soc/codecs/wm8350.h
@@ -0,0 +1,20 @@
1/*
2 * wm8350.h - WM8903 audio codec interface
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#ifndef _WM8350_H
13#define _WM8350_H
14
15#include <sound/soc.h>
16
17extern struct snd_soc_dai wm8350_dai;
18extern struct snd_soc_codec_device soc_codec_dev_wm8350;
19
20#endif
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index d8ca2da8d634..40f8238df717 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -463,7 +463,8 @@ static int wm8510_set_dai_fmt(struct snd_soc_dai *codec_dai,
463} 463}
464 464
465static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream, 465static int wm8510_pcm_hw_params(struct snd_pcm_substream *substream,
466 struct snd_pcm_hw_params *params) 466 struct snd_pcm_hw_params *params,
467 struct snd_soc_dai *dai)
467{ 468{
468 struct snd_soc_pcm_runtime *rtd = substream->private_data; 469 struct snd_soc_pcm_runtime *rtd = substream->private_data;
469 struct snd_soc_device *socdev = rtd->socdev; 470 struct snd_soc_device *socdev = rtd->socdev;
@@ -585,8 +586,6 @@ struct snd_soc_dai wm8510_dai = {
585 .formats = WM8510_FORMATS,}, 586 .formats = WM8510_FORMATS,},
586 .ops = { 587 .ops = {
587 .hw_params = wm8510_pcm_hw_params, 588 .hw_params = wm8510_pcm_hw_params,
588 },
589 .dai_ops = {
590 .digital_mute = wm8510_mute, 589 .digital_mute = wm8510_mute,
591 .set_fmt = wm8510_set_dai_fmt, 590 .set_fmt = wm8510_set_dai_fmt,
592 .set_clkdiv = wm8510_set_dai_clkdiv, 591 .set_clkdiv = wm8510_set_dai_clkdiv,
@@ -659,7 +658,7 @@ static int wm8510_init(struct snd_soc_device *socdev)
659 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 658 wm8510_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
660 wm8510_add_controls(codec); 659 wm8510_add_controls(codec);
661 wm8510_add_widgets(codec); 660 wm8510_add_widgets(codec);
662 ret = snd_soc_register_card(socdev); 661 ret = snd_soc_init_card(socdev);
663 if (ret < 0) { 662 if (ret < 0) {
664 printk(KERN_ERR "wm8510: failed to register card\n"); 663 printk(KERN_ERR "wm8510: failed to register card\n");
665 goto card_err; 664 goto card_err;
@@ -890,6 +889,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8510 = {
890}; 889};
891EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510); 890EXPORT_SYMBOL_GPL(soc_codec_dev_wm8510);
892 891
892static int __init wm8510_modinit(void)
893{
894 return snd_soc_register_dai(&wm8510_dai);
895}
896module_init(wm8510_modinit);
897
898static void __exit wm8510_exit(void)
899{
900 snd_soc_unregister_dai(&wm8510_dai);
901}
902module_exit(wm8510_exit);
903
893MODULE_DESCRIPTION("ASoC WM8510 driver"); 904MODULE_DESCRIPTION("ASoC WM8510 driver");
894MODULE_AUTHOR("Liam Girdwood"); 905MODULE_AUTHOR("Liam Girdwood");
895MODULE_LICENSE("GPL"); 906MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 627ebfb4209b..d004e5845298 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -548,13 +548,13 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai,
548 * Set PCM DAI bit size and sample rate. 548 * Set PCM DAI bit size and sample rate.
549 */ 549 */
550static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, 550static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
551 struct snd_pcm_hw_params *params) 551 struct snd_pcm_hw_params *params,
552 struct snd_soc_dai *dai)
552{ 553{
553 struct snd_soc_pcm_runtime *rtd = substream->private_data; 554 struct snd_soc_pcm_runtime *rtd = substream->private_data;
554 struct snd_soc_dai_link *dai = rtd->dai;
555 struct snd_soc_device *socdev = rtd->socdev; 555 struct snd_soc_device *socdev = rtd->socdev;
556 struct snd_soc_codec *codec = socdev->codec; 556 struct snd_soc_codec *codec = socdev->codec;
557 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->codec_dai->id); 557 u16 paifb = wm8580_read(codec, WM8580_PAIF3 + dai->id);
558 558
559 paifb &= ~WM8580_AIF_LENGTH_MASK; 559 paifb &= ~WM8580_AIF_LENGTH_MASK;
560 /* bit size */ 560 /* bit size */
@@ -574,7 +574,7 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
574 return -EINVAL; 574 return -EINVAL;
575 } 575 }
576 576
577 wm8580_write(codec, WM8580_PAIF3 + dai->codec_dai->id, paifb); 577 wm8580_write(codec, WM8580_PAIF3 + dai->id, paifb);
578 return 0; 578 return 0;
579} 579}
580 580
@@ -798,8 +798,6 @@ struct snd_soc_dai wm8580_dai[] = {
798 }, 798 },
799 .ops = { 799 .ops = {
800 .hw_params = wm8580_paif_hw_params, 800 .hw_params = wm8580_paif_hw_params,
801 },
802 .dai_ops = {
803 .set_fmt = wm8580_set_paif_dai_fmt, 801 .set_fmt = wm8580_set_paif_dai_fmt,
804 .set_clkdiv = wm8580_set_dai_clkdiv, 802 .set_clkdiv = wm8580_set_dai_clkdiv,
805 .set_pll = wm8580_set_dai_pll, 803 .set_pll = wm8580_set_dai_pll,
@@ -818,8 +816,6 @@ struct snd_soc_dai wm8580_dai[] = {
818 }, 816 },
819 .ops = { 817 .ops = {
820 .hw_params = wm8580_paif_hw_params, 818 .hw_params = wm8580_paif_hw_params,
821 },
822 .dai_ops = {
823 .set_fmt = wm8580_set_paif_dai_fmt, 819 .set_fmt = wm8580_set_paif_dai_fmt,
824 .set_clkdiv = wm8580_set_dai_clkdiv, 820 .set_clkdiv = wm8580_set_dai_clkdiv,
825 .set_pll = wm8580_set_dai_pll, 821 .set_pll = wm8580_set_dai_pll,
@@ -873,7 +869,7 @@ static int wm8580_init(struct snd_soc_device *socdev)
873 wm8580_add_controls(codec); 869 wm8580_add_controls(codec);
874 wm8580_add_widgets(codec); 870 wm8580_add_widgets(codec);
875 871
876 ret = snd_soc_register_card(socdev); 872 ret = snd_soc_init_card(socdev);
877 if (ret < 0) { 873 if (ret < 0) {
878 printk(KERN_ERR "wm8580: failed to register card\n"); 874 printk(KERN_ERR "wm8580: failed to register card\n");
879 goto card_err; 875 goto card_err;
@@ -900,85 +896,85 @@ static struct snd_soc_device *wm8580_socdev;
900 * low = 0x1a 896 * low = 0x1a
901 * high = 0x1b 897 * high = 0x1b
902 */ 898 */
903static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END };
904
905/* Magic definition of all other variables and things */
906I2C_CLIENT_INSMOD;
907 899
908static struct i2c_driver wm8580_i2c_driver; 900static int wm8580_i2c_probe(struct i2c_client *i2c,
909static struct i2c_client client_template; 901 const struct i2c_device_id *id)
910
911static int wm8580_codec_probe(struct i2c_adapter *adap, int addr, int kind)
912{ 902{
913 struct snd_soc_device *socdev = wm8580_socdev; 903 struct snd_soc_device *socdev = wm8580_socdev;
914 struct wm8580_setup_data *setup = socdev->codec_data;
915 struct snd_soc_codec *codec = socdev->codec; 904 struct snd_soc_codec *codec = socdev->codec;
916 struct i2c_client *i2c;
917 int ret; 905 int ret;
918 906
919 if (addr != setup->i2c_address)
920 return -ENODEV;
921
922 client_template.adapter = adap;
923 client_template.addr = addr;
924
925 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
926 if (i2c == NULL) {
927 kfree(codec);
928 return -ENOMEM;
929 }
930 i2c_set_clientdata(i2c, codec); 907 i2c_set_clientdata(i2c, codec);
931 codec->control_data = i2c; 908 codec->control_data = i2c;
932 909
933 ret = i2c_attach_client(i2c);
934 if (ret < 0) {
935 dev_err(&i2c->dev, "failed to attach codec at addr %x\n", addr);
936 goto err;
937 }
938
939 ret = wm8580_init(socdev); 910 ret = wm8580_init(socdev);
940 if (ret < 0) { 911 if (ret < 0)
941 dev_err(&i2c->dev, "failed to initialise WM8580\n"); 912 dev_err(&i2c->dev, "failed to initialise WM8580\n");
942 goto err;
943 }
944
945 return ret;
946
947err:
948 kfree(codec);
949 kfree(i2c);
950 return ret; 913 return ret;
951} 914}
952 915
953static int wm8580_i2c_detach(struct i2c_client *client) 916static int wm8580_i2c_remove(struct i2c_client *client)
954{ 917{
955 struct snd_soc_codec *codec = i2c_get_clientdata(client); 918 struct snd_soc_codec *codec = i2c_get_clientdata(client);
956 i2c_detach_client(client);
957 kfree(codec->reg_cache); 919 kfree(codec->reg_cache);
958 kfree(client);
959 return 0; 920 return 0;
960} 921}
961 922
962static int wm8580_i2c_attach(struct i2c_adapter *adap) 923static const struct i2c_device_id wm8580_i2c_id[] = {
963{ 924 { "wm8580", 0 },
964 return i2c_probe(adap, &addr_data, wm8580_codec_probe); 925 { }
965} 926};
927MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
966 928
967/* corgi i2c codec control layer */
968static struct i2c_driver wm8580_i2c_driver = { 929static struct i2c_driver wm8580_i2c_driver = {
969 .driver = { 930 .driver = {
970 .name = "WM8580 I2C Codec", 931 .name = "WM8580 I2C Codec",
971 .owner = THIS_MODULE, 932 .owner = THIS_MODULE,
972 }, 933 },
973 .attach_adapter = wm8580_i2c_attach, 934 .probe = wm8580_i2c_probe,
974 .detach_client = wm8580_i2c_detach, 935 .remove = wm8580_i2c_remove,
975 .command = NULL, 936 .id_table = wm8580_i2c_id,
976}; 937};
977 938
978static struct i2c_client client_template = { 939static int wm8580_add_i2c_device(struct platform_device *pdev,
979 .name = "WM8580", 940 const struct wm8580_setup_data *setup)
980 .driver = &wm8580_i2c_driver, 941{
981}; 942 struct i2c_board_info info;
943 struct i2c_adapter *adapter;
944 struct i2c_client *client;
945 int ret;
946
947 ret = i2c_add_driver(&wm8580_i2c_driver);
948 if (ret != 0) {
949 dev_err(&pdev->dev, "can't add i2c driver\n");
950 return ret;
951 }
952
953 memset(&info, 0, sizeof(struct i2c_board_info));
954 info.addr = setup->i2c_address;
955 strlcpy(info.type, "wm8580", I2C_NAME_SIZE);
956
957 adapter = i2c_get_adapter(setup->i2c_bus);
958 if (!adapter) {
959 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
960 setup->i2c_bus);
961 goto err_driver;
962 }
963
964 client = i2c_new_device(adapter, &info);
965 i2c_put_adapter(adapter);
966 if (!client) {
967 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
968 (unsigned int)info.addr);
969 goto err_driver;
970 }
971
972 return 0;
973
974err_driver:
975 i2c_del_driver(&wm8580_i2c_driver);
976 return -ENODEV;
977}
982#endif 978#endif
983 979
984static int wm8580_probe(struct platform_device *pdev) 980static int wm8580_probe(struct platform_device *pdev)
@@ -1011,11 +1007,8 @@ static int wm8580_probe(struct platform_device *pdev)
1011 1007
1012#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1008#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1013 if (setup->i2c_address) { 1009 if (setup->i2c_address) {
1014 normal_i2c[0] = setup->i2c_address;
1015 codec->hw_write = (hw_write_t)i2c_master_send; 1010 codec->hw_write = (hw_write_t)i2c_master_send;
1016 ret = i2c_add_driver(&wm8580_i2c_driver); 1011 ret = wm8580_add_i2c_device(pdev, setup);
1017 if (ret != 0)
1018 printk(KERN_ERR "can't add i2c driver");
1019 } 1012 }
1020#else 1013#else
1021 /* Add other interfaces here */ 1014 /* Add other interfaces here */
@@ -1034,6 +1027,7 @@ static int wm8580_remove(struct platform_device *pdev)
1034 snd_soc_free_pcms(socdev); 1027 snd_soc_free_pcms(socdev);
1035 snd_soc_dapm_free(socdev); 1028 snd_soc_dapm_free(socdev);
1036#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1029#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1030 i2c_unregister_device(codec->control_data);
1037 i2c_del_driver(&wm8580_i2c_driver); 1031 i2c_del_driver(&wm8580_i2c_driver);
1038#endif 1032#endif
1039 kfree(codec->private_data); 1033 kfree(codec->private_data);
@@ -1048,6 +1042,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8580 = {
1048}; 1042};
1049EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580); 1043EXPORT_SYMBOL_GPL(soc_codec_dev_wm8580);
1050 1044
1045static int __init wm8580_modinit(void)
1046{
1047 return snd_soc_register_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
1048}
1049module_init(wm8580_modinit);
1050
1051static void __exit wm8580_exit(void)
1052{
1053 snd_soc_unregister_dais(wm8580_dai, ARRAY_SIZE(wm8580_dai));
1054}
1055module_exit(wm8580_exit);
1056
1051MODULE_DESCRIPTION("ASoC WM8580 driver"); 1057MODULE_DESCRIPTION("ASoC WM8580 driver");
1052MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 1058MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
1053MODULE_LICENSE("GPL"); 1059MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8580.h b/sound/soc/codecs/wm8580.h
index 589ddaba21d7..09e4422f6f2f 100644
--- a/sound/soc/codecs/wm8580.h
+++ b/sound/soc/codecs/wm8580.h
@@ -29,6 +29,7 @@
29#define WM8580_CLKSRC_NONE 5 29#define WM8580_CLKSRC_NONE 5
30 30
31struct wm8580_setup_data { 31struct wm8580_setup_data {
32 int i2c_bus;
32 unsigned short i2c_address; 33 unsigned short i2c_address;
33}; 34};
34 35
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
new file mode 100644
index 000000000000..80b11983e137
--- /dev/null
+++ b/sound/soc/codecs/wm8728.c
@@ -0,0 +1,585 @@
1/*
2 * wm8728.c -- WM8728 ALSA SoC Audio driver
3 *
4 * Copyright 2008 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/platform_device.h>
20#include <linux/spi/spi.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include "wm8728.h"
30
31struct snd_soc_codec_device soc_codec_dev_wm8728;
32
33/*
34 * We can't read the WM8728 register space so we cache them instead.
35 * Note that the defaults here aren't the physical defaults, we latch
36 * the volume update bits, mute the output and enable infinite zero
37 * detect.
38 */
39static const u16 wm8728_reg_defaults[] = {
40 0x1ff,
41 0x1ff,
42 0x001,
43 0x100,
44};
45
46static inline unsigned int wm8728_read_reg_cache(struct snd_soc_codec *codec,
47 unsigned int reg)
48{
49 u16 *cache = codec->reg_cache;
50 BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults));
51 return cache[reg];
52}
53
54static inline void wm8728_write_reg_cache(struct snd_soc_codec *codec,
55 u16 reg, unsigned int value)
56{
57 u16 *cache = codec->reg_cache;
58 BUG_ON(reg > ARRAY_SIZE(wm8728_reg_defaults));
59 cache[reg] = value;
60}
61
62/*
63 * write to the WM8728 register space
64 */
65static int wm8728_write(struct snd_soc_codec *codec, unsigned int reg,
66 unsigned int value)
67{
68 u8 data[2];
69
70 /* data is
71 * D15..D9 WM8728 register offset
72 * D8...D0 register data
73 */
74 data[0] = (reg << 1) | ((value >> 8) & 0x0001);
75 data[1] = value & 0x00ff;
76
77 wm8728_write_reg_cache(codec, reg, value);
78
79 if (codec->hw_write(codec->control_data, data, 2) == 2)
80 return 0;
81 else
82 return -EIO;
83}
84
85static const DECLARE_TLV_DB_SCALE(wm8728_tlv, -12750, 50, 1);
86
87static const struct snd_kcontrol_new wm8728_snd_controls[] = {
88
89SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8728_DACLVOL, WM8728_DACRVOL,
90 0, 255, 0, wm8728_tlv),
91
92SOC_SINGLE("Deemphasis", WM8728_DACCTL, 1, 1, 0),
93};
94
95static int wm8728_add_controls(struct snd_soc_codec *codec)
96{
97 int err, i;
98
99 for (i = 0; i < ARRAY_SIZE(wm8728_snd_controls); i++) {
100 err = snd_ctl_add(codec->card,
101 snd_soc_cnew(&wm8728_snd_controls[i],
102 codec, NULL));
103 if (err < 0)
104 return err;
105 }
106
107 return 0;
108}
109
110/*
111 * DAPM controls.
112 */
113static const struct snd_soc_dapm_widget wm8728_dapm_widgets[] = {
114SND_SOC_DAPM_DAC("DAC", "HiFi Playback", SND_SOC_NOPM, 0, 0),
115SND_SOC_DAPM_OUTPUT("VOUTL"),
116SND_SOC_DAPM_OUTPUT("VOUTR"),
117};
118
119static const struct snd_soc_dapm_route intercon[] = {
120 {"VOUTL", NULL, "DAC"},
121 {"VOUTR", NULL, "DAC"},
122};
123
124static int wm8728_add_widgets(struct snd_soc_codec *codec)
125{
126 snd_soc_dapm_new_controls(codec, wm8728_dapm_widgets,
127 ARRAY_SIZE(wm8728_dapm_widgets));
128
129 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
130
131 snd_soc_dapm_new_widgets(codec);
132
133 return 0;
134}
135
136static int wm8728_mute(struct snd_soc_dai *dai, int mute)
137{
138 struct snd_soc_codec *codec = dai->codec;
139 u16 mute_reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
140
141 if (mute)
142 wm8728_write(codec, WM8728_DACCTL, mute_reg | 1);
143 else
144 wm8728_write(codec, WM8728_DACCTL, mute_reg & ~1);
145
146 return 0;
147}
148
149static int wm8728_hw_params(struct snd_pcm_substream *substream,
150 struct snd_pcm_hw_params *params,
151 struct snd_soc_dai *dai)
152{
153 struct snd_soc_pcm_runtime *rtd = substream->private_data;
154 struct snd_soc_device *socdev = rtd->socdev;
155 struct snd_soc_codec *codec = socdev->codec;
156 u16 dac = wm8728_read_reg_cache(codec, WM8728_DACCTL);
157
158 dac &= ~0x18;
159
160 switch (params_format(params)) {
161 case SNDRV_PCM_FORMAT_S16_LE:
162 break;
163 case SNDRV_PCM_FORMAT_S20_3LE:
164 dac |= 0x10;
165 break;
166 case SNDRV_PCM_FORMAT_S24_LE:
167 dac |= 0x08;
168 break;
169 default:
170 return -EINVAL;
171 }
172
173 wm8728_write(codec, WM8728_DACCTL, dac);
174
175 return 0;
176}
177
178static int wm8728_set_dai_fmt(struct snd_soc_dai *codec_dai,
179 unsigned int fmt)
180{
181 struct snd_soc_codec *codec = codec_dai->codec;
182 u16 iface = wm8728_read_reg_cache(codec, WM8728_IFCTL);
183
184 /* Currently only I2S is supported by the driver, though the
185 * hardware is more flexible.
186 */
187 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
188 case SND_SOC_DAIFMT_I2S:
189 iface |= 1;
190 break;
191 default:
192 return -EINVAL;
193 }
194
195 /* The hardware only support full slave mode */
196 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
197 case SND_SOC_DAIFMT_CBS_CFS:
198 break;
199 default:
200 return -EINVAL;
201 }
202
203 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
204 case SND_SOC_DAIFMT_NB_NF:
205 iface &= ~0x22;
206 break;
207 case SND_SOC_DAIFMT_IB_NF:
208 iface |= 0x20;
209 iface &= ~0x02;
210 break;
211 case SND_SOC_DAIFMT_NB_IF:
212 iface |= 0x02;
213 iface &= ~0x20;
214 break;
215 case SND_SOC_DAIFMT_IB_IF:
216 iface |= 0x22;
217 break;
218 default:
219 return -EINVAL;
220 }
221
222 wm8728_write(codec, WM8728_IFCTL, iface);
223 return 0;
224}
225
226static int wm8728_set_bias_level(struct snd_soc_codec *codec,
227 enum snd_soc_bias_level level)
228{
229 u16 reg;
230 int i;
231
232 switch (level) {
233 case SND_SOC_BIAS_ON:
234 case SND_SOC_BIAS_PREPARE:
235 case SND_SOC_BIAS_STANDBY:
236 if (codec->bias_level == SND_SOC_BIAS_OFF) {
237 /* Power everything up... */
238 reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
239 wm8728_write(codec, WM8728_DACCTL, reg & ~0x4);
240
241 /* ..then sync in the register cache. */
242 for (i = 0; i < ARRAY_SIZE(wm8728_reg_defaults); i++)
243 wm8728_write(codec, i,
244 wm8728_read_reg_cache(codec, i));
245 }
246 break;
247
248 case SND_SOC_BIAS_OFF:
249 reg = wm8728_read_reg_cache(codec, WM8728_DACCTL);
250 wm8728_write(codec, WM8728_DACCTL, reg | 0x4);
251 break;
252 }
253 codec->bias_level = level;
254 return 0;
255}
256
257#define WM8728_RATES (SNDRV_PCM_RATE_8000_192000)
258
259#define WM8728_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
260 SNDRV_PCM_FMTBIT_S24_LE)
261
262struct snd_soc_dai wm8728_dai = {
263 .name = "WM8728",
264 .playback = {
265 .stream_name = "Playback",
266 .channels_min = 2,
267 .channels_max = 2,
268 .rates = WM8728_RATES,
269 .formats = WM8728_FORMATS,
270 },
271 .ops = {
272 .hw_params = wm8728_hw_params,
273 .digital_mute = wm8728_mute,
274 .set_fmt = wm8728_set_dai_fmt,
275 }
276};
277EXPORT_SYMBOL_GPL(wm8728_dai);
278
279static int wm8728_suspend(struct platform_device *pdev, pm_message_t state)
280{
281 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
282 struct snd_soc_codec *codec = socdev->codec;
283
284 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
285
286 return 0;
287}
288
289static int wm8728_resume(struct platform_device *pdev)
290{
291 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
292 struct snd_soc_codec *codec = socdev->codec;
293
294 wm8728_set_bias_level(codec, codec->suspend_bias_level);
295
296 return 0;
297}
298
299/*
300 * initialise the WM8728 driver
301 * register the mixer and dsp interfaces with the kernel
302 */
303static int wm8728_init(struct snd_soc_device *socdev)
304{
305 struct snd_soc_codec *codec = socdev->codec;
306 int ret = 0;
307
308 codec->name = "WM8728";
309 codec->owner = THIS_MODULE;
310 codec->read = wm8728_read_reg_cache;
311 codec->write = wm8728_write;
312 codec->set_bias_level = wm8728_set_bias_level;
313 codec->dai = &wm8728_dai;
314 codec->num_dai = 1;
315 codec->bias_level = SND_SOC_BIAS_OFF;
316 codec->reg_cache_size = ARRAY_SIZE(wm8728_reg_defaults);
317 codec->reg_cache = kmemdup(wm8728_reg_defaults,
318 sizeof(wm8728_reg_defaults),
319 GFP_KERNEL);
320 if (codec->reg_cache == NULL)
321 return -ENOMEM;
322
323 /* register pcms */
324 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
325 if (ret < 0) {
326 printk(KERN_ERR "wm8728: failed to create pcms\n");
327 goto pcm_err;
328 }
329
330 /* power on device */
331 wm8728_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
332
333 wm8728_add_controls(codec);
334 wm8728_add_widgets(codec);
335 ret = snd_soc_init_card(socdev);
336 if (ret < 0) {
337 printk(KERN_ERR "wm8728: failed to register card\n");
338 goto card_err;
339 }
340
341 return ret;
342
343card_err:
344 snd_soc_free_pcms(socdev);
345 snd_soc_dapm_free(socdev);
346pcm_err:
347 kfree(codec->reg_cache);
348 return ret;
349}
350
351static struct snd_soc_device *wm8728_socdev;
352
353#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
354
355/*
356 * WM8728 2 wire address is determined by GPIO5
357 * state during powerup.
358 * low = 0x1a
359 * high = 0x1b
360 */
361
362static int wm8728_i2c_probe(struct i2c_client *i2c,
363 const struct i2c_device_id *id)
364{
365 struct snd_soc_device *socdev = wm8728_socdev;
366 struct snd_soc_codec *codec = socdev->codec;
367 int ret;
368
369 i2c_set_clientdata(i2c, codec);
370 codec->control_data = i2c;
371
372 ret = wm8728_init(socdev);
373 if (ret < 0)
374 pr_err("failed to initialise WM8728\n");
375
376 return ret;
377}
378
379static int wm8728_i2c_remove(struct i2c_client *client)
380{
381 struct snd_soc_codec *codec = i2c_get_clientdata(client);
382 kfree(codec->reg_cache);
383 return 0;
384}
385
386static const struct i2c_device_id wm8728_i2c_id[] = {
387 { "wm8728", 0 },
388 { }
389};
390MODULE_DEVICE_TABLE(i2c, wm8728_i2c_id);
391
392static struct i2c_driver wm8728_i2c_driver = {
393 .driver = {
394 .name = "WM8728 I2C Codec",
395 .owner = THIS_MODULE,
396 },
397 .probe = wm8728_i2c_probe,
398 .remove = wm8728_i2c_remove,
399 .id_table = wm8728_i2c_id,
400};
401
402static int wm8728_add_i2c_device(struct platform_device *pdev,
403 const struct wm8728_setup_data *setup)
404{
405 struct i2c_board_info info;
406 struct i2c_adapter *adapter;
407 struct i2c_client *client;
408 int ret;
409
410 ret = i2c_add_driver(&wm8728_i2c_driver);
411 if (ret != 0) {
412 dev_err(&pdev->dev, "can't add i2c driver\n");
413 return ret;
414 }
415
416 memset(&info, 0, sizeof(struct i2c_board_info));
417 info.addr = setup->i2c_address;
418 strlcpy(info.type, "wm8728", I2C_NAME_SIZE);
419
420 adapter = i2c_get_adapter(setup->i2c_bus);
421 if (!adapter) {
422 dev_err(&pdev->dev, "can't get i2c adapter %d\n",
423 setup->i2c_bus);
424 goto err_driver;
425 }
426
427 client = i2c_new_device(adapter, &info);
428 i2c_put_adapter(adapter);
429 if (!client) {
430 dev_err(&pdev->dev, "can't add i2c device at 0x%x\n",
431 (unsigned int)info.addr);
432 goto err_driver;
433 }
434
435 return 0;
436
437err_driver:
438 i2c_del_driver(&wm8728_i2c_driver);
439 return -ENODEV;
440}
441#endif
442
443#if defined(CONFIG_SPI_MASTER)
444static int __devinit wm8728_spi_probe(struct spi_device *spi)
445{
446 struct snd_soc_device *socdev = wm8728_socdev;
447 struct snd_soc_codec *codec = socdev->codec;
448 int ret;
449
450 codec->control_data = spi;
451
452 ret = wm8728_init(socdev);
453 if (ret < 0)
454 dev_err(&spi->dev, "failed to initialise WM8728\n");
455
456 return ret;
457}
458
459static int __devexit wm8728_spi_remove(struct spi_device *spi)
460{
461 return 0;
462}
463
464static struct spi_driver wm8728_spi_driver = {
465 .driver = {
466 .name = "wm8728",
467 .bus = &spi_bus_type,
468 .owner = THIS_MODULE,
469 },
470 .probe = wm8728_spi_probe,
471 .remove = __devexit_p(wm8728_spi_remove),
472};
473
474static int wm8728_spi_write(struct spi_device *spi, const char *data, int len)
475{
476 struct spi_transfer t;
477 struct spi_message m;
478 u8 msg[2];
479
480 if (len <= 0)
481 return 0;
482
483 msg[0] = data[0];
484 msg[1] = data[1];
485
486 spi_message_init(&m);
487 memset(&t, 0, (sizeof t));
488
489 t.tx_buf = &msg[0];
490 t.len = len;
491
492 spi_message_add_tail(&t, &m);
493 spi_sync(spi, &m);
494
495 return len;
496}
497#endif /* CONFIG_SPI_MASTER */
498
499static int wm8728_probe(struct platform_device *pdev)
500{
501 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
502 struct wm8728_setup_data *setup;
503 struct snd_soc_codec *codec;
504 int ret = 0;
505
506 setup = socdev->codec_data;
507 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL);
508 if (codec == NULL)
509 return -ENOMEM;
510
511 socdev->codec = codec;
512 mutex_init(&codec->mutex);
513 INIT_LIST_HEAD(&codec->dapm_widgets);
514 INIT_LIST_HEAD(&codec->dapm_paths);
515
516 wm8728_socdev = socdev;
517 ret = -ENODEV;
518
519#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
520 if (setup->i2c_address) {
521 codec->hw_write = (hw_write_t)i2c_master_send;
522 ret = wm8728_add_i2c_device(pdev, setup);
523 }
524#endif
525#if defined(CONFIG_SPI_MASTER)
526 if (setup->spi) {
527 codec->hw_write = (hw_write_t)wm8728_spi_write;
528 ret = spi_register_driver(&wm8728_spi_driver);
529 if (ret != 0)
530 printk(KERN_ERR "can't add spi driver");
531 }
532#endif
533
534 if (ret != 0)
535 kfree(codec);
536
537 return ret;
538}
539
540/* power down chip */
541static int wm8728_remove(struct platform_device *pdev)
542{
543 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
544 struct snd_soc_codec *codec = socdev->codec;
545
546 if (codec->control_data)
547 wm8728_set_bias_level(codec, SND_SOC_BIAS_OFF);
548
549 snd_soc_free_pcms(socdev);
550 snd_soc_dapm_free(socdev);
551#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
552 i2c_unregister_device(codec->control_data);
553 i2c_del_driver(&wm8728_i2c_driver);
554#endif
555#if defined(CONFIG_SPI_MASTER)
556 spi_unregister_driver(&wm8728_spi_driver);
557#endif
558 kfree(codec);
559
560 return 0;
561}
562
563struct snd_soc_codec_device soc_codec_dev_wm8728 = {
564 .probe = wm8728_probe,
565 .remove = wm8728_remove,
566 .suspend = wm8728_suspend,
567 .resume = wm8728_resume,
568};
569EXPORT_SYMBOL_GPL(soc_codec_dev_wm8728);
570
571static int __init wm8728_modinit(void)
572{
573 return snd_soc_register_dai(&wm8728_dai);
574}
575module_init(wm8728_modinit);
576
577static void __exit wm8728_exit(void)
578{
579 snd_soc_unregister_dai(&wm8728_dai);
580}
581module_exit(wm8728_exit);
582
583MODULE_DESCRIPTION("ASoC WM8728 driver");
584MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
585MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8728.h b/sound/soc/codecs/wm8728.h
new file mode 100644
index 000000000000..d269c132474b
--- /dev/null
+++ b/sound/soc/codecs/wm8728.h
@@ -0,0 +1,30 @@
1/*
2 * wm8728.h -- WM8728 ASoC codec driver
3 *
4 * Copyright 2008 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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
13#ifndef _WM8728_H
14#define _WM8728_H
15
16#define WM8728_DACLVOL 0x00
17#define WM8728_DACRVOL 0x01
18#define WM8728_DACCTL 0x02
19#define WM8728_IFCTL 0x03
20
21struct wm8728_setup_data {
22 int spi;
23 int i2c_bus;
24 unsigned short i2c_address;
25};
26
27extern struct snd_soc_dai wm8728_dai;
28extern struct snd_soc_codec_device soc_codec_dev_wm8728;
29
30#endif
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 7f8a7e36b33e..c444b9f2701e 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -264,7 +264,8 @@ static inline int get_coeff(int mclk, int rate)
264} 264}
265 265
266static int wm8731_hw_params(struct snd_pcm_substream *substream, 266static int wm8731_hw_params(struct snd_pcm_substream *substream,
267 struct snd_pcm_hw_params *params) 267 struct snd_pcm_hw_params *params,
268 struct snd_soc_dai *dai)
268{ 269{
269 struct snd_soc_pcm_runtime *rtd = substream->private_data; 270 struct snd_soc_pcm_runtime *rtd = substream->private_data;
270 struct snd_soc_device *socdev = rtd->socdev; 271 struct snd_soc_device *socdev = rtd->socdev;
@@ -293,7 +294,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
293 return 0; 294 return 0;
294} 295}
295 296
296static int wm8731_pcm_prepare(struct snd_pcm_substream *substream) 297static int wm8731_pcm_prepare(struct snd_pcm_substream *substream,
298 struct snd_soc_dai *dai)
297{ 299{
298 struct snd_soc_pcm_runtime *rtd = substream->private_data; 300 struct snd_soc_pcm_runtime *rtd = substream->private_data;
299 struct snd_soc_device *socdev = rtd->socdev; 301 struct snd_soc_device *socdev = rtd->socdev;
@@ -305,7 +307,8 @@ static int wm8731_pcm_prepare(struct snd_pcm_substream *substream)
305 return 0; 307 return 0;
306} 308}
307 309
308static void wm8731_shutdown(struct snd_pcm_substream *substream) 310static void wm8731_shutdown(struct snd_pcm_substream *substream,
311 struct snd_soc_dai *dai)
309{ 312{
310 struct snd_soc_pcm_runtime *rtd = substream->private_data; 313 struct snd_soc_pcm_runtime *rtd = substream->private_data;
311 struct snd_soc_device *socdev = rtd->socdev; 314 struct snd_soc_device *socdev = rtd->socdev;
@@ -461,8 +464,6 @@ struct snd_soc_dai wm8731_dai = {
461 .prepare = wm8731_pcm_prepare, 464 .prepare = wm8731_pcm_prepare,
462 .hw_params = wm8731_hw_params, 465 .hw_params = wm8731_hw_params,
463 .shutdown = wm8731_shutdown, 466 .shutdown = wm8731_shutdown,
464 },
465 .dai_ops = {
466 .digital_mute = wm8731_mute, 467 .digital_mute = wm8731_mute,
467 .set_sysclk = wm8731_set_dai_sysclk, 468 .set_sysclk = wm8731_set_dai_sysclk,
468 .set_fmt = wm8731_set_dai_fmt, 469 .set_fmt = wm8731_set_dai_fmt,
@@ -544,7 +545,7 @@ static int wm8731_init(struct snd_soc_device *socdev)
544 545
545 wm8731_add_controls(codec); 546 wm8731_add_controls(codec);
546 wm8731_add_widgets(codec); 547 wm8731_add_widgets(codec);
547 ret = snd_soc_register_card(socdev); 548 ret = snd_soc_init_card(socdev);
548 if (ret < 0) { 549 if (ret < 0) {
549 printk(KERN_ERR "wm8731: failed to register card\n"); 550 printk(KERN_ERR "wm8731: failed to register card\n");
550 goto card_err; 551 goto card_err;
@@ -792,6 +793,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8731 = {
792}; 793};
793EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731); 794EXPORT_SYMBOL_GPL(soc_codec_dev_wm8731);
794 795
796static int __init wm8731_modinit(void)
797{
798 return snd_soc_register_dai(&wm8731_dai);
799}
800module_init(wm8731_modinit);
801
802static void __exit wm8731_exit(void)
803{
804 snd_soc_unregister_dai(&wm8731_dai);
805}
806module_exit(wm8731_exit);
807
795MODULE_DESCRIPTION("ASoC WM8731 driver"); 808MODULE_DESCRIPTION("ASoC WM8731 driver");
796MODULE_AUTHOR("Richard Purdie"); 809MODULE_AUTHOR("Richard Purdie");
797MODULE_LICENSE("GPL"); 810MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 9b7296ee5b08..5997fa68e0d5 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -614,7 +614,8 @@ static int wm8750_set_dai_fmt(struct snd_soc_dai *codec_dai,
614} 614}
615 615
616static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream, 616static int wm8750_pcm_hw_params(struct snd_pcm_substream *substream,
617 struct snd_pcm_hw_params *params) 617 struct snd_pcm_hw_params *params,
618 struct snd_soc_dai *dai)
618{ 619{
619 struct snd_soc_pcm_runtime *rtd = substream->private_data; 620 struct snd_soc_pcm_runtime *rtd = substream->private_data;
620 struct snd_soc_device *socdev = rtd->socdev; 621 struct snd_soc_device *socdev = rtd->socdev;
@@ -709,8 +710,6 @@ struct snd_soc_dai wm8750_dai = {
709 .formats = WM8750_FORMATS,}, 710 .formats = WM8750_FORMATS,},
710 .ops = { 711 .ops = {
711 .hw_params = wm8750_pcm_hw_params, 712 .hw_params = wm8750_pcm_hw_params,
712 },
713 .dai_ops = {
714 .digital_mute = wm8750_mute, 713 .digital_mute = wm8750_mute,
715 .set_fmt = wm8750_set_dai_fmt, 714 .set_fmt = wm8750_set_dai_fmt,
716 .set_sysclk = wm8750_set_dai_sysclk, 715 .set_sysclk = wm8750_set_dai_sysclk,
@@ -819,7 +818,7 @@ static int wm8750_init(struct snd_soc_device *socdev)
819 818
820 wm8750_add_controls(codec); 819 wm8750_add_controls(codec);
821 wm8750_add_widgets(codec); 820 wm8750_add_widgets(codec);
822 ret = snd_soc_register_card(socdev); 821 ret = snd_soc_init_card(socdev);
823 if (ret < 0) { 822 if (ret < 0) {
824 printk(KERN_ERR "wm8750: failed to register card\n"); 823 printk(KERN_ERR "wm8750: failed to register card\n");
825 goto card_err; 824 goto card_err;
@@ -1086,6 +1085,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8750 = {
1086}; 1085};
1087EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750); 1086EXPORT_SYMBOL_GPL(soc_codec_dev_wm8750);
1088 1087
1088static int __init wm8750_modinit(void)
1089{
1090 return snd_soc_register_dai(&wm8750_dai);
1091}
1092module_init(wm8750_modinit);
1093
1094static void __exit wm8750_exit(void)
1095{
1096 snd_soc_unregister_dai(&wm8750_dai);
1097}
1098module_exit(wm8750_exit);
1099
1089MODULE_DESCRIPTION("ASoC WM8750 driver"); 1100MODULE_DESCRIPTION("ASoC WM8750 driver");
1090MODULE_AUTHOR("Liam Girdwood"); 1101MODULE_AUTHOR("Liam Girdwood");
1091MODULE_LICENSE("GPL"); 1102MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index d426eaa22185..6c21b50c9375 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -922,7 +922,8 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai,
922 * Set PCM DAI bit size and sample rate. 922 * Set PCM DAI bit size and sample rate.
923 */ 923 */
924static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, 924static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream,
925 struct snd_pcm_hw_params *params) 925 struct snd_pcm_hw_params *params,
926 struct snd_soc_dai *dai)
926{ 927{
927 struct snd_soc_pcm_runtime *rtd = substream->private_data; 928 struct snd_soc_pcm_runtime *rtd = substream->private_data;
928 struct snd_soc_device *socdev = rtd->socdev; 929 struct snd_soc_device *socdev = rtd->socdev;
@@ -1155,7 +1156,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1155 * Set PCM DAI bit size and sample rate. 1156 * Set PCM DAI bit size and sample rate.
1156 */ 1157 */
1157static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, 1158static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream,
1158 struct snd_pcm_hw_params *params) 1159 struct snd_pcm_hw_params *params,
1160 struct snd_soc_dai *dai)
1159{ 1161{
1160 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1162 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1161 struct snd_soc_device *socdev = rtd->socdev; 1163 struct snd_soc_device *socdev = rtd->socdev;
@@ -1323,16 +1325,15 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1323 .channels_min = 1, 1325 .channels_min = 1,
1324 .channels_max = 2, 1326 .channels_max = 2,
1325 .rates = WM8753_RATES, 1327 .rates = WM8753_RATES,
1326 .formats = WM8753_FORMATS,}, 1328 .formats = WM8753_FORMATS},
1327 .capture = { /* dummy for fast DAI switching */ 1329 .capture = { /* dummy for fast DAI switching */
1328 .stream_name = "Capture", 1330 .stream_name = "Capture",
1329 .channels_min = 1, 1331 .channels_min = 1,
1330 .channels_max = 2, 1332 .channels_max = 2,
1331 .rates = WM8753_RATES, 1333 .rates = WM8753_RATES,
1332 .formats = WM8753_FORMATS,}, 1334 .formats = WM8753_FORMATS},
1333 .ops = { 1335 .ops = {
1334 .hw_params = wm8753_i2s_hw_params,}, 1336 .hw_params = wm8753_i2s_hw_params,
1335 .dai_ops = {
1336 .digital_mute = wm8753_mute, 1337 .digital_mute = wm8753_mute,
1337 .set_fmt = wm8753_mode1h_set_dai_fmt, 1338 .set_fmt = wm8753_mode1h_set_dai_fmt,
1338 .set_clkdiv = wm8753_set_dai_clkdiv, 1339 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1356,8 +1357,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1356 .rates = WM8753_RATES, 1357 .rates = WM8753_RATES,
1357 .formats = WM8753_FORMATS,}, 1358 .formats = WM8753_FORMATS,},
1358 .ops = { 1359 .ops = {
1359 .hw_params = wm8753_pcm_hw_params,}, 1360 .hw_params = wm8753_pcm_hw_params,
1360 .dai_ops = {
1361 .digital_mute = wm8753_mute, 1361 .digital_mute = wm8753_mute,
1362 .set_fmt = wm8753_mode1v_set_dai_fmt, 1362 .set_fmt = wm8753_mode1v_set_dai_fmt,
1363 .set_clkdiv = wm8753_set_dai_clkdiv, 1363 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1385,8 +1385,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1385 .rates = WM8753_RATES, 1385 .rates = WM8753_RATES,
1386 .formats = WM8753_FORMATS,}, 1386 .formats = WM8753_FORMATS,},
1387 .ops = { 1387 .ops = {
1388 .hw_params = wm8753_pcm_hw_params,}, 1388 .hw_params = wm8753_pcm_hw_params,
1389 .dai_ops = {
1390 .digital_mute = wm8753_mute, 1389 .digital_mute = wm8753_mute,
1391 .set_fmt = wm8753_mode2_set_dai_fmt, 1390 .set_fmt = wm8753_mode2_set_dai_fmt,
1392 .set_clkdiv = wm8753_set_dai_clkdiv, 1391 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1410,8 +1409,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1410 .rates = WM8753_RATES, 1409 .rates = WM8753_RATES,
1411 .formats = WM8753_FORMATS,}, 1410 .formats = WM8753_FORMATS,},
1412 .ops = { 1411 .ops = {
1413 .hw_params = wm8753_i2s_hw_params,}, 1412 .hw_params = wm8753_i2s_hw_params,
1414 .dai_ops = {
1415 .digital_mute = wm8753_mute, 1413 .digital_mute = wm8753_mute,
1416 .set_fmt = wm8753_mode3_4_set_dai_fmt, 1414 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1417 .set_clkdiv = wm8753_set_dai_clkdiv, 1415 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1439,8 +1437,7 @@ static const struct snd_soc_dai wm8753_all_dai[] = {
1439 .rates = WM8753_RATES, 1437 .rates = WM8753_RATES,
1440 .formats = WM8753_FORMATS,}, 1438 .formats = WM8753_FORMATS,},
1441 .ops = { 1439 .ops = {
1442 .hw_params = wm8753_i2s_hw_params,}, 1440 .hw_params = wm8753_i2s_hw_params,
1443 .dai_ops = {
1444 .digital_mute = wm8753_mute, 1441 .digital_mute = wm8753_mute,
1445 .set_fmt = wm8753_mode3_4_set_dai_fmt, 1442 .set_fmt = wm8753_mode3_4_set_dai_fmt,
1446 .set_clkdiv = wm8753_set_dai_clkdiv, 1443 .set_clkdiv = wm8753_set_dai_clkdiv,
@@ -1608,7 +1605,7 @@ static int wm8753_init(struct snd_soc_device *socdev)
1608 1605
1609 wm8753_add_controls(codec); 1606 wm8753_add_controls(codec);
1610 wm8753_add_widgets(codec); 1607 wm8753_add_widgets(codec);
1611 ret = snd_soc_register_card(socdev); 1608 ret = snd_soc_init_card(socdev);
1612 if (ret < 0) { 1609 if (ret < 0) {
1613 printk(KERN_ERR "wm8753: failed to register card\n"); 1610 printk(KERN_ERR "wm8753: failed to register card\n");
1614 goto card_err; 1611 goto card_err;
@@ -1877,6 +1874,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8753 = {
1877}; 1874};
1878EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753); 1875EXPORT_SYMBOL_GPL(soc_codec_dev_wm8753);
1879 1876
1877static int __init wm8753_modinit(void)
1878{
1879 return snd_soc_register_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai));
1880}
1881module_init(wm8753_modinit);
1882
1883static void __exit wm8753_exit(void)
1884{
1885 snd_soc_unregister_dais(wm8753_dai, ARRAY_SIZE(wm8753_dai));
1886}
1887module_exit(wm8753_exit);
1888
1880MODULE_DESCRIPTION("ASoC WM8753 driver"); 1889MODULE_DESCRIPTION("ASoC WM8753 driver");
1881MODULE_AUTHOR("Liam Girdwood"); 1890MODULE_AUTHOR("Liam Girdwood");
1882MODULE_LICENSE("GPL"); 1891MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index 3b326c9b5586..6767de10ded0 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -138,6 +138,10 @@
138struct snd_soc_codec_device soc_codec_dev_wm8900; 138struct snd_soc_codec_device soc_codec_dev_wm8900;
139 139
140struct wm8900_priv { 140struct wm8900_priv {
141 struct snd_soc_codec codec;
142
143 u16 reg_cache[WM8900_MAXREG];
144
141 u32 fll_in; /* FLL input frequency */ 145 u32 fll_in; /* FLL input frequency */
142 u32 fll_out; /* FLL output frequency */ 146 u32 fll_out; /* FLL output frequency */
143}; 147};
@@ -727,7 +731,8 @@ static int wm8900_add_widgets(struct snd_soc_codec *codec)
727} 731}
728 732
729static int wm8900_hw_params(struct snd_pcm_substream *substream, 733static int wm8900_hw_params(struct snd_pcm_substream *substream,
730 struct snd_pcm_hw_params *params) 734 struct snd_pcm_hw_params *params,
735 struct snd_soc_dai *dai)
731{ 736{
732 struct snd_soc_pcm_runtime *rtd = substream->private_data; 737 struct snd_soc_pcm_runtime *rtd = substream->private_data;
733 struct snd_soc_device *socdev = rtd->socdev; 738 struct snd_soc_device *socdev = rtd->socdev;
@@ -1117,8 +1122,6 @@ struct snd_soc_dai wm8900_dai = {
1117 }, 1122 },
1118 .ops = { 1123 .ops = {
1119 .hw_params = wm8900_hw_params, 1124 .hw_params = wm8900_hw_params,
1120 },
1121 .dai_ops = {
1122 .set_clkdiv = wm8900_set_dai_clkdiv, 1125 .set_clkdiv = wm8900_set_dai_clkdiv,
1123 .set_pll = wm8900_set_dai_pll, 1126 .set_pll = wm8900_set_dai_pll,
1124 .set_fmt = wm8900_set_dai_fmt, 1127 .set_fmt = wm8900_set_dai_fmt,
@@ -1283,16 +1286,28 @@ static int wm8900_resume(struct platform_device *pdev)
1283 return 0; 1286 return 0;
1284} 1287}
1285 1288
1286/* 1289static struct snd_soc_codec *wm8900_codec;
1287 * initialise the WM8900 driver 1290
1288 * register the mixer and dsp interfaces with the kernel 1291static int wm8900_i2c_probe(struct i2c_client *i2c,
1289 */ 1292 const struct i2c_device_id *id)
1290static int wm8900_init(struct snd_soc_device *socdev)
1291{ 1293{
1292 struct snd_soc_codec *codec = socdev->codec; 1294 struct wm8900_priv *wm8900;
1293 int ret = 0; 1295 struct snd_soc_codec *codec;
1294 unsigned int reg; 1296 unsigned int reg;
1295 struct i2c_client *i2c_client = socdev->codec->control_data; 1297 int ret;
1298
1299 wm8900 = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1300 if (wm8900 == NULL)
1301 return -ENOMEM;
1302
1303 codec = &wm8900->codec;
1304 codec->private_data = wm8900;
1305 codec->reg_cache = &wm8900->reg_cache[0];
1306 codec->reg_cache_size = WM8900_MAXREG;
1307
1308 mutex_init(&codec->mutex);
1309 INIT_LIST_HEAD(&codec->dapm_widgets);
1310 INIT_LIST_HEAD(&codec->dapm_paths);
1296 1311
1297 codec->name = "WM8900"; 1312 codec->name = "WM8900";
1298 codec->owner = THIS_MODULE; 1313 codec->owner = THIS_MODULE;
@@ -1300,33 +1315,28 @@ static int wm8900_init(struct snd_soc_device *socdev)
1300 codec->write = wm8900_write; 1315 codec->write = wm8900_write;
1301 codec->dai = &wm8900_dai; 1316 codec->dai = &wm8900_dai;
1302 codec->num_dai = 1; 1317 codec->num_dai = 1;
1303 codec->reg_cache_size = WM8900_MAXREG; 1318 codec->hw_write = (hw_write_t)i2c_master_send;
1304 codec->reg_cache = kmemdup(wm8900_reg_defaults, 1319 codec->control_data = i2c;
1305 sizeof(wm8900_reg_defaults), GFP_KERNEL); 1320 codec->set_bias_level = wm8900_set_bias_level;
1306 1321 codec->dev = &i2c->dev;
1307 if (codec->reg_cache == NULL)
1308 return -ENOMEM;
1309 1322
1310 reg = wm8900_read(codec, WM8900_REG_ID); 1323 reg = wm8900_read(codec, WM8900_REG_ID);
1311 if (reg != 0x8900) { 1324 if (reg != 0x8900) {
1312 dev_err(&i2c_client->dev, "Device is not a WM8900 - ID %x\n", 1325 dev_err(&i2c->dev, "Device is not a WM8900 - ID %x\n", reg);
1313 reg); 1326 ret = -ENODEV;
1314 return -ENODEV; 1327 goto err;
1315 }
1316
1317 codec->private_data = kzalloc(sizeof(struct wm8900_priv), GFP_KERNEL);
1318 if (codec->private_data == NULL) {
1319 ret = -ENOMEM;
1320 goto priv_err;
1321 } 1328 }
1322 1329
1323 /* Read back from the chip */ 1330 /* Read back from the chip */
1324 reg = wm8900_chip_read(codec, WM8900_REG_POWER1); 1331 reg = wm8900_chip_read(codec, WM8900_REG_POWER1);
1325 reg = (reg >> 12) & 0xf; 1332 reg = (reg >> 12) & 0xf;
1326 dev_info(&i2c_client->dev, "WM8900 revision %d\n", reg); 1333 dev_info(&i2c->dev, "WM8900 revision %d\n", reg);
1327 1334
1328 wm8900_reset(codec); 1335 wm8900_reset(codec);
1329 1336
1337 /* Turn the chip on */
1338 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1339
1330 /* Latch the volume update bits */ 1340 /* Latch the volume update bits */
1331 wm8900_write(codec, WM8900_REG_LINVOL, 1341 wm8900_write(codec, WM8900_REG_LINVOL,
1332 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100); 1342 wm8900_read(codec, WM8900_REG_LINVOL) | 0x100);
@@ -1352,160 +1362,98 @@ static int wm8900_init(struct snd_soc_device *socdev)
1352 /* Set the DAC and mixer output bias */ 1362 /* Set the DAC and mixer output bias */
1353 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81); 1363 wm8900_write(codec, WM8900_REG_OUTBIASCTL, 0x81);
1354 1364
1355 /* Register pcms */ 1365 wm8900_dai.dev = &i2c->dev;
1356 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1357 if (ret < 0) {
1358 dev_err(&i2c_client->dev, "Failed to register new PCMs\n");
1359 goto pcm_err;
1360 }
1361
1362 /* Turn the chip on */
1363 codec->bias_level = SND_SOC_BIAS_OFF;
1364 wm8900_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1365
1366 wm8900_add_controls(codec);
1367 wm8900_add_widgets(codec);
1368
1369 ret = snd_soc_register_card(socdev);
1370 if (ret < 0) {
1371 dev_err(&i2c_client->dev, "Failed to register card\n");
1372 goto card_err;
1373 }
1374 return ret;
1375
1376card_err:
1377 snd_soc_free_pcms(socdev);
1378 snd_soc_dapm_free(socdev);
1379pcm_err:
1380 kfree(codec->reg_cache);
1381priv_err:
1382 kfree(codec->private_data);
1383 return ret;
1384}
1385 1366
1386static struct snd_soc_device *wm8900_socdev; 1367 wm8900_codec = codec;
1387 1368
1388#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1369 ret = snd_soc_register_codec(codec);
1389 1370 if (ret != 0) {
1390static unsigned short normal_i2c[] = { 0, I2C_CLIENT_END }; 1371 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1391
1392/* Magic definition of all other variables and things */
1393I2C_CLIENT_INSMOD;
1394
1395static struct i2c_driver wm8900_i2c_driver;
1396static struct i2c_client client_template;
1397
1398/* If the i2c layer weren't so broken, we could pass this kind of data
1399 around */
1400static int wm8900_codec_probe(struct i2c_adapter *adap, int addr, int kind)
1401{
1402 struct snd_soc_device *socdev = wm8900_socdev;
1403 struct wm8900_setup_data *setup = socdev->codec_data;
1404 struct snd_soc_codec *codec = socdev->codec;
1405 struct i2c_client *i2c;
1406 int ret;
1407
1408 if (addr != setup->i2c_address)
1409 return -ENODEV;
1410
1411 dev_err(&adap->dev, "Probe on %x\n", addr);
1412
1413 client_template.adapter = adap;
1414 client_template.addr = addr;
1415
1416 i2c = kmemdup(&client_template, sizeof(client_template), GFP_KERNEL);
1417 if (i2c == NULL) {
1418 kfree(codec);
1419 return -ENOMEM;
1420 }
1421 i2c_set_clientdata(i2c, codec);
1422 codec->control_data = i2c;
1423
1424 ret = i2c_attach_client(i2c);
1425 if (ret < 0) {
1426 dev_err(&adap->dev,
1427 "failed to attach codec at addr %x\n", addr);
1428 goto err; 1372 goto err;
1429 } 1373 }
1430 1374
1431 ret = wm8900_init(socdev); 1375 ret = snd_soc_register_dai(&wm8900_dai);
1432 if (ret < 0) { 1376 if (ret != 0) {
1433 dev_err(&adap->dev, "failed to initialise WM8900\n"); 1377 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1434 goto err; 1378 goto err_codec;
1435 } 1379 }
1380
1436 return ret; 1381 return ret;
1437 1382
1383err_codec:
1384 snd_soc_unregister_codec(codec);
1438err: 1385err:
1439 kfree(codec); 1386 kfree(wm8900);
1440 kfree(i2c); 1387 wm8900_codec = NULL;
1441 return ret; 1388 return ret;
1442} 1389}
1443 1390
1444static int wm8900_i2c_detach(struct i2c_client *client) 1391static int wm8900_i2c_remove(struct i2c_client *client)
1445{ 1392{
1446 struct snd_soc_codec *codec = i2c_get_clientdata(client); 1393 snd_soc_unregister_dai(&wm8900_dai);
1447 i2c_detach_client(client); 1394 snd_soc_unregister_codec(wm8900_codec);
1448 kfree(codec->reg_cache); 1395
1449 kfree(client); 1396 wm8900_set_bias_level(wm8900_codec, SND_SOC_BIAS_OFF);
1397
1398 wm8900_dai.dev = NULL;
1399 kfree(wm8900_codec->private_data);
1400 wm8900_codec = NULL;
1401
1450 return 0; 1402 return 0;
1451} 1403}
1452 1404
1453static int wm8900_i2c_attach(struct i2c_adapter *adap) 1405static const struct i2c_device_id wm8900_i2c_id[] = {
1454{ 1406 { "wm8900", 0 },
1455 return i2c_probe(adap, &addr_data, wm8900_codec_probe); 1407 { }
1456} 1408};
1409MODULE_DEVICE_TABLE(i2c, wm8900_i2c_id);
1457 1410
1458/* corgi i2c codec control layer */
1459static struct i2c_driver wm8900_i2c_driver = { 1411static struct i2c_driver wm8900_i2c_driver = {
1460 .driver = { 1412 .driver = {
1461 .name = "WM8900 I2C codec", 1413 .name = "WM8900",
1462 .owner = THIS_MODULE, 1414 .owner = THIS_MODULE,
1463 }, 1415 },
1464 .attach_adapter = wm8900_i2c_attach, 1416 .probe = wm8900_i2c_probe,
1465 .detach_client = wm8900_i2c_detach, 1417 .remove = wm8900_i2c_remove,
1466 .command = NULL, 1418 .id_table = wm8900_i2c_id,
1467};
1468
1469static struct i2c_client client_template = {
1470 .name = "WM8900",
1471 .driver = &wm8900_i2c_driver,
1472}; 1419};
1473#endif
1474 1420
1475static int wm8900_probe(struct platform_device *pdev) 1421static int wm8900_probe(struct platform_device *pdev)
1476{ 1422{
1477 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1423 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1478 struct wm8900_setup_data *setup;
1479 struct snd_soc_codec *codec; 1424 struct snd_soc_codec *codec;
1480 int ret = 0; 1425 int ret = 0;
1481 1426
1482 dev_info(&pdev->dev, "WM8900 Audio Codec\n"); 1427 if (!wm8900_codec) {
1483 1428 dev_err(&pdev->dev, "I2C client not yet instantiated\n");
1484 setup = socdev->codec_data; 1429 return -ENODEV;
1485 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1430 }
1486 if (codec == NULL)
1487 return -ENOMEM;
1488
1489 mutex_init(&codec->mutex);
1490 INIT_LIST_HEAD(&codec->dapm_widgets);
1491 INIT_LIST_HEAD(&codec->dapm_paths);
1492 1431
1432 codec = wm8900_codec;
1493 socdev->codec = codec; 1433 socdev->codec = codec;
1494 1434
1495 codec->set_bias_level = wm8900_set_bias_level; 1435 /* Register pcms */
1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1437 if (ret < 0) {
1438 dev_err(&pdev->dev, "Failed to register new PCMs\n");
1439 goto pcm_err;
1440 }
1496 1441
1497 wm8900_socdev = socdev; 1442 wm8900_add_controls(codec);
1498#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1443 wm8900_add_widgets(codec);
1499 if (setup->i2c_address) { 1444
1500 normal_i2c[0] = setup->i2c_address; 1445 ret = snd_soc_init_card(socdev);
1501 codec->hw_write = (hw_write_t)i2c_master_send; 1446 if (ret < 0) {
1502 ret = i2c_add_driver(&wm8900_i2c_driver); 1447 dev_err(&pdev->dev, "Failed to register card\n");
1503 if (ret != 0) 1448 goto card_err;
1504 printk(KERN_ERR "can't add i2c driver");
1505 } 1449 }
1506#else 1450
1507#error Non-I2C interfaces not yet supported 1451 return ret;
1508#endif 1452
1453card_err:
1454 snd_soc_free_pcms(socdev);
1455 snd_soc_dapm_free(socdev);
1456pcm_err:
1509 return ret; 1457 return ret;
1510} 1458}
1511 1459
@@ -1513,17 +1461,9 @@ static int wm8900_probe(struct platform_device *pdev)
1513static int wm8900_remove(struct platform_device *pdev) 1461static int wm8900_remove(struct platform_device *pdev)
1514{ 1462{
1515 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1463 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1516 struct snd_soc_codec *codec = socdev->codec;
1517
1518 if (codec->control_data)
1519 wm8900_set_bias_level(codec, SND_SOC_BIAS_OFF);
1520 1464
1521 snd_soc_free_pcms(socdev); 1465 snd_soc_free_pcms(socdev);
1522 snd_soc_dapm_free(socdev); 1466 snd_soc_dapm_free(socdev);
1523#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1524 i2c_del_driver(&wm8900_i2c_driver);
1525#endif
1526 kfree(codec);
1527 1467
1528 return 0; 1468 return 0;
1529} 1469}
@@ -1536,6 +1476,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8900 = {
1536}; 1476};
1537EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900); 1477EXPORT_SYMBOL_GPL(soc_codec_dev_wm8900);
1538 1478
1479static int __init wm8900_modinit(void)
1480{
1481 return i2c_add_driver(&wm8900_i2c_driver);
1482}
1483module_init(wm8900_modinit);
1484
1485static void __exit wm8900_exit(void)
1486{
1487 i2c_del_driver(&wm8900_i2c_driver);
1488}
1489module_exit(wm8900_exit);
1490
1539MODULE_DESCRIPTION("ASoC WM8900 driver"); 1491MODULE_DESCRIPTION("ASoC WM8900 driver");
1540MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>"); 1492MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfonmicro.com>");
1541MODULE_LICENSE("GPL"); 1493MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8900.h b/sound/soc/codecs/wm8900.h
index ba450d99e902..fd15007d10c7 100644
--- a/sound/soc/codecs/wm8900.h
+++ b/sound/soc/codecs/wm8900.h
@@ -52,12 +52,6 @@
52#define WM8900_DAC_CLKDIV_5_5 0x14 52#define WM8900_DAC_CLKDIV_5_5 0x14
53#define WM8900_DAC_CLKDIV_6 0x18 53#define WM8900_DAC_CLKDIV_6 0x18
54 54
55#define WM8900_
56
57struct wm8900_setup_data {
58 unsigned short i2c_address;
59};
60
61extern struct snd_soc_dai wm8900_dai; 55extern struct snd_soc_dai wm8900_dai;
62extern struct snd_soc_codec_device soc_codec_dev_wm8900; 56extern struct snd_soc_codec_device soc_codec_dev_wm8900;
63 57
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index ce40d7877605..bde74546db4a 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -33,19 +33,6 @@
33 33
34#include "wm8903.h" 34#include "wm8903.h"
35 35
36struct wm8903_priv {
37 int sysclk;
38
39 /* Reference counts */
40 int charge_pump_users;
41 int class_w_users;
42 int playback_active;
43 int capture_active;
44
45 struct snd_pcm_substream *master_substream;
46 struct snd_pcm_substream *slave_substream;
47};
48
49/* Register defaults at reset */ 36/* Register defaults at reset */
50static u16 wm8903_reg_defaults[] = { 37static u16 wm8903_reg_defaults[] = {
51 0x8903, /* R0 - SW Reset and ID */ 38 0x8903, /* R0 - SW Reset and ID */
@@ -223,6 +210,23 @@ static u16 wm8903_reg_defaults[] = {
223 0x0000, /* R172 - Analogue Output Bias 0 */ 210 0x0000, /* R172 - Analogue Output Bias 0 */
224}; 211};
225 212
213struct wm8903_priv {
214 struct snd_soc_codec codec;
215 u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
216
217 int sysclk;
218
219 /* Reference counts */
220 int charge_pump_users;
221 int class_w_users;
222 int playback_active;
223 int capture_active;
224
225 struct snd_pcm_substream *master_substream;
226 struct snd_pcm_substream *slave_substream;
227};
228
229
226static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec, 230static unsigned int wm8903_read_reg_cache(struct snd_soc_codec *codec,
227 unsigned int reg) 231 unsigned int reg)
228{ 232{
@@ -360,6 +364,8 @@ static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache)
360static void wm8903_reset(struct snd_soc_codec *codec) 364static void wm8903_reset(struct snd_soc_codec *codec)
361{ 365{
362 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0); 366 wm8903_write(codec, WM8903_SW_RESET_AND_ID, 0);
367 memcpy(codec->reg_cache, wm8903_reg_defaults,
368 sizeof(wm8903_reg_defaults));
363} 369}
364 370
365#define WM8903_OUTPUT_SHORT 0x8 371#define WM8903_OUTPUT_SHORT 0x8
@@ -392,6 +398,7 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
392 break; 398 break;
393 default: 399 default:
394 BUG(); 400 BUG();
401 return -EINVAL; /* Spurious warning from some compilers */
395 } 402 }
396 403
397 switch (w->shift) { 404 switch (w->shift) {
@@ -403,6 +410,7 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w,
403 break; 410 break;
404 default: 411 default:
405 BUG(); 412 BUG();
413 return -EINVAL; /* Spurious warning from some compilers */
406 } 414 }
407 415
408 if (event & SND_SOC_DAPM_PRE_PMU) { 416 if (event & SND_SOC_DAPM_PRE_PMU) {
@@ -773,14 +781,14 @@ static const struct snd_kcontrol_new left_output_mixer[] = {
773SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), 781SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0),
774SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), 782SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0),
775SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0), 783SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0),
776SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 1, 1, 0), 784SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_LEFT_MIX_0, 0, 1, 0),
777}; 785};
778 786
779static const struct snd_kcontrol_new right_output_mixer[] = { 787static const struct snd_kcontrol_new right_output_mixer[] = {
780SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0), 788SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 3, 1, 0),
781SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0), 789SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 2, 1, 0),
782SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0), 790SOC_DAPM_SINGLE_W("Left Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0),
783SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 1, 1, 0), 791SOC_DAPM_SINGLE_W("Right Bypass Switch", WM8903_ANALOGUE_RIGHT_MIX_0, 0, 1, 0),
784}; 792};
785 793
786static const struct snd_kcontrol_new left_speaker_mixer[] = { 794static const struct snd_kcontrol_new left_speaker_mixer[] = {
@@ -788,7 +796,7 @@ SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 3, 1, 0),
788SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 2, 1, 0), 796SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 2, 1, 0),
789SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 1, 1, 0), 797SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 1, 1, 0),
790SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0, 798SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_LEFT_0,
791 1, 1, 0), 799 0, 1, 0),
792}; 800};
793 801
794static const struct snd_kcontrol_new right_speaker_mixer[] = { 802static const struct snd_kcontrol_new right_speaker_mixer[] = {
@@ -797,7 +805,7 @@ SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 2, 1, 0),
797SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 805SOC_DAPM_SINGLE("Left Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
798 1, 1, 0), 806 1, 1, 0),
799SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0, 807SOC_DAPM_SINGLE("Right Bypass Switch", WM8903_ANALOGUE_SPK_MIX_RIGHT_0,
800 1, 1, 0), 808 0, 1, 0),
801}; 809};
802 810
803static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = { 811static const struct snd_soc_dapm_widget wm8903_dapm_widgets[] = {
@@ -989,6 +997,9 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
989 997
990 case SND_SOC_BIAS_STANDBY: 998 case SND_SOC_BIAS_STANDBY:
991 if (codec->bias_level == SND_SOC_BIAS_OFF) { 999 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1000 wm8903_write(codec, WM8903_CLOCK_RATES_2,
1001 WM8903_CLK_SYS_ENA);
1002
992 wm8903_run_sequence(codec, 0); 1003 wm8903_run_sequence(codec, 0);
993 wm8903_sync_reg_cache(codec, codec->reg_cache); 1004 wm8903_sync_reg_cache(codec, codec->reg_cache);
994 1005
@@ -1019,6 +1030,9 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
1019 1030
1020 case SND_SOC_BIAS_OFF: 1031 case SND_SOC_BIAS_OFF:
1021 wm8903_run_sequence(codec, 32); 1032 wm8903_run_sequence(codec, 32);
1033 reg = wm8903_read(codec, WM8903_CLOCK_RATES_2);
1034 reg &= ~WM8903_CLK_SYS_ENA;
1035 wm8903_write(codec, WM8903_CLOCK_RATES_2, reg);
1022 break; 1036 break;
1023 } 1037 }
1024 1038
@@ -1257,7 +1271,8 @@ static struct {
1257 { 0, 0 }, 1271 { 0, 0 },
1258}; 1272};
1259 1273
1260static int wm8903_startup(struct snd_pcm_substream *substream) 1274static int wm8903_startup(struct snd_pcm_substream *substream,
1275 struct snd_soc_dai *dai)
1261{ 1276{
1262 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1263 struct snd_soc_device *socdev = rtd->socdev; 1278 struct snd_soc_device *socdev = rtd->socdev;
@@ -1298,7 +1313,8 @@ static int wm8903_startup(struct snd_pcm_substream *substream)
1298 return 0; 1313 return 0;
1299} 1314}
1300 1315
1301static void wm8903_shutdown(struct snd_pcm_substream *substream) 1316static void wm8903_shutdown(struct snd_pcm_substream *substream,
1317 struct snd_soc_dai *dai)
1302{ 1318{
1303 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1319 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1304 struct snd_soc_device *socdev = rtd->socdev; 1320 struct snd_soc_device *socdev = rtd->socdev;
@@ -1317,7 +1333,8 @@ static void wm8903_shutdown(struct snd_pcm_substream *substream)
1317} 1333}
1318 1334
1319static int wm8903_hw_params(struct snd_pcm_substream *substream, 1335static int wm8903_hw_params(struct snd_pcm_substream *substream,
1320 struct snd_pcm_hw_params *params) 1336 struct snd_pcm_hw_params *params,
1337 struct snd_soc_dai *dai)
1321{ 1338{
1322 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1339 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1323 struct snd_soc_device *socdev = rtd->socdev; 1340 struct snd_soc_device *socdev = rtd->socdev;
@@ -1515,8 +1532,6 @@ struct snd_soc_dai wm8903_dai = {
1515 .startup = wm8903_startup, 1532 .startup = wm8903_startup,
1516 .shutdown = wm8903_shutdown, 1533 .shutdown = wm8903_shutdown,
1517 .hw_params = wm8903_hw_params, 1534 .hw_params = wm8903_hw_params,
1518 },
1519 .dai_ops = {
1520 .digital_mute = wm8903_digital_mute, 1535 .digital_mute = wm8903_digital_mute,
1521 .set_fmt = wm8903_set_dai_fmt, 1536 .set_fmt = wm8903_set_dai_fmt,
1522 .set_sysclk = wm8903_set_dai_sysclk 1537 .set_sysclk = wm8903_set_dai_sysclk
@@ -1560,39 +1575,48 @@ static int wm8903_resume(struct platform_device *pdev)
1560 return 0; 1575 return 0;
1561} 1576}
1562 1577
1563/* 1578static struct snd_soc_codec *wm8903_codec;
1564 * initialise the WM8903 driver 1579
1565 * register the mixer and dsp interfaces with the kernel 1580static int wm8903_i2c_probe(struct i2c_client *i2c,
1566 */ 1581 const struct i2c_device_id *id)
1567static int wm8903_init(struct snd_soc_device *socdev)
1568{ 1582{
1569 struct snd_soc_codec *codec = socdev->codec; 1583 struct wm8903_priv *wm8903;
1570 struct i2c_client *i2c = codec->control_data; 1584 struct snd_soc_codec *codec;
1571 int ret = 0; 1585 int ret;
1572 u16 val; 1586 u16 val;
1573 1587
1574 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID); 1588 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL);
1575 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { 1589 if (wm8903 == NULL)
1576 dev_err(&i2c->dev, 1590 return -ENOMEM;
1577 "Device with ID register %x is not a WM8903\n", val); 1591
1578 return -ENODEV; 1592 codec = &wm8903->codec;
1579 }
1580 1593
1594 mutex_init(&codec->mutex);
1595 INIT_LIST_HEAD(&codec->dapm_widgets);
1596 INIT_LIST_HEAD(&codec->dapm_paths);
1597
1598 codec->dev = &i2c->dev;
1581 codec->name = "WM8903"; 1599 codec->name = "WM8903";
1582 codec->owner = THIS_MODULE; 1600 codec->owner = THIS_MODULE;
1583 codec->read = wm8903_read; 1601 codec->read = wm8903_read;
1584 codec->write = wm8903_write; 1602 codec->write = wm8903_write;
1603 codec->hw_write = (hw_write_t)i2c_master_send;
1585 codec->bias_level = SND_SOC_BIAS_OFF; 1604 codec->bias_level = SND_SOC_BIAS_OFF;
1586 codec->set_bias_level = wm8903_set_bias_level; 1605 codec->set_bias_level = wm8903_set_bias_level;
1587 codec->dai = &wm8903_dai; 1606 codec->dai = &wm8903_dai;
1588 codec->num_dai = 1; 1607 codec->num_dai = 1;
1589 codec->reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults); 1608 codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache);
1590 codec->reg_cache = kmemdup(wm8903_reg_defaults, 1609 codec->reg_cache = &wm8903->reg_cache[0];
1591 sizeof(wm8903_reg_defaults), 1610 codec->private_data = wm8903;
1592 GFP_KERNEL); 1611
1593 if (codec->reg_cache == NULL) { 1612 i2c_set_clientdata(i2c, codec);
1594 dev_err(&i2c->dev, "Failed to allocate register cache\n"); 1613 codec->control_data = i2c;
1595 return -ENOMEM; 1614
1615 val = wm8903_hw_read(codec, WM8903_SW_RESET_AND_ID);
1616 if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) {
1617 dev_err(&i2c->dev,
1618 "Device with ID register %x is not a WM8903\n", val);
1619 return -ENODEV;
1596 } 1620 }
1597 1621
1598 val = wm8903_read(codec, WM8903_REVISION_NUMBER); 1622 val = wm8903_read(codec, WM8903_REVISION_NUMBER);
@@ -1601,16 +1625,6 @@ static int wm8903_init(struct snd_soc_device *socdev)
1601 1625
1602 wm8903_reset(codec); 1626 wm8903_reset(codec);
1603 1627
1604 /* register pcms */
1605 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1606 if (ret < 0) {
1607 dev_err(&i2c->dev, "failed to create pcms\n");
1608 goto pcm_err;
1609 }
1610
1611 /* SYSCLK is required for pretty much anything */
1612 wm8903_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA);
1613
1614 /* power on device */ 1628 /* power on device */
1615 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1629 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1616 1630
@@ -1645,47 +1659,45 @@ static int wm8903_init(struct snd_soc_device *socdev)
1645 val |= WM8903_DAC_MUTEMODE; 1659 val |= WM8903_DAC_MUTEMODE;
1646 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val); 1660 wm8903_write(codec, WM8903_DAC_DIGITAL_1, val);
1647 1661
1648 wm8903_add_controls(codec); 1662 wm8903_dai.dev = &i2c->dev;
1649 wm8903_add_widgets(codec); 1663 wm8903_codec = codec;
1650 ret = snd_soc_register_card(socdev); 1664
1651 if (ret < 0) { 1665 ret = snd_soc_register_codec(codec);
1652 dev_err(&i2c->dev, "wm8903: failed to register card\n"); 1666 if (ret != 0) {
1653 goto card_err; 1667 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1668 goto err;
1669 }
1670
1671 ret = snd_soc_register_dai(&wm8903_dai);
1672 if (ret != 0) {
1673 dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret);
1674 goto err_codec;
1654 } 1675 }
1655 1676
1656 return ret; 1677 return ret;
1657 1678
1658card_err: 1679err_codec:
1659 snd_soc_free_pcms(socdev); 1680 snd_soc_unregister_codec(codec);
1660 snd_soc_dapm_free(socdev); 1681err:
1661pcm_err: 1682 wm8903_codec = NULL;
1662 kfree(codec->reg_cache); 1683 kfree(wm8903);
1663 return ret; 1684 return ret;
1664} 1685}
1665 1686
1666static struct snd_soc_device *wm8903_socdev; 1687static int wm8903_i2c_remove(struct i2c_client *client)
1667
1668static int wm8903_i2c_probe(struct i2c_client *i2c,
1669 const struct i2c_device_id *id)
1670{ 1688{
1671 struct snd_soc_device *socdev = wm8903_socdev; 1689 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1672 struct snd_soc_codec *codec = socdev->codec;
1673 int ret;
1674 1690
1675 i2c_set_clientdata(i2c, codec); 1691 snd_soc_unregister_dai(&wm8903_dai);
1676 codec->control_data = i2c; 1692 snd_soc_unregister_codec(codec);
1677 1693
1678 ret = wm8903_init(socdev); 1694 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
1679 if (ret < 0)
1680 dev_err(&i2c->dev, "Device initialisation failed\n");
1681 1695
1682 return ret; 1696 kfree(codec->private_data);
1683} 1697
1698 wm8903_codec = NULL;
1699 wm8903_dai.dev = NULL;
1684 1700
1685static int wm8903_i2c_remove(struct i2c_client *client)
1686{
1687 struct snd_soc_codec *codec = i2c_get_clientdata(client);
1688 kfree(codec->reg_cache);
1689 return 0; 1701 return 0;
1690} 1702}
1691 1703
@@ -1709,75 +1721,37 @@ static struct i2c_driver wm8903_i2c_driver = {
1709static int wm8903_probe(struct platform_device *pdev) 1721static int wm8903_probe(struct platform_device *pdev)
1710{ 1722{
1711 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1723 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
1712 struct wm8903_setup_data *setup;
1713 struct snd_soc_codec *codec;
1714 struct wm8903_priv *wm8903;
1715 struct i2c_board_info board_info;
1716 struct i2c_adapter *adapter;
1717 struct i2c_client *i2c_client;
1718 int ret = 0; 1724 int ret = 0;
1719 1725
1720 setup = socdev->codec_data; 1726 if (!wm8903_codec) {
1721 1727 dev_err(&pdev->dev, "I2C device not yet probed\n");
1722 if (!setup->i2c_address) { 1728 goto err;
1723 dev_err(&pdev->dev, "No codec address provided\n");
1724 return -ENODEV;
1725 } 1729 }
1726 1730
1727 codec = kzalloc(sizeof(struct snd_soc_codec), GFP_KERNEL); 1731 socdev->codec = wm8903_codec;
1728 if (codec == NULL)
1729 return -ENOMEM;
1730 1732
1731 wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); 1733 /* register pcms */
1732 if (wm8903 == NULL) { 1734 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
1733 ret = -ENOMEM; 1735 if (ret < 0) {
1734 goto err_codec; 1736 dev_err(&pdev->dev, "failed to create pcms\n");
1737 goto err;
1735 } 1738 }
1736 1739
1737 codec->private_data = wm8903; 1740 wm8903_add_controls(socdev->codec);
1738 socdev->codec = codec; 1741 wm8903_add_widgets(socdev->codec);
1739 mutex_init(&codec->mutex);
1740 INIT_LIST_HEAD(&codec->dapm_widgets);
1741 INIT_LIST_HEAD(&codec->dapm_paths);
1742
1743 wm8903_socdev = socdev;
1744 1742
1745 codec->hw_write = (hw_write_t)i2c_master_send; 1743 ret = snd_soc_init_card(socdev);
1746 ret = i2c_add_driver(&wm8903_i2c_driver); 1744 if (ret < 0) {
1747 if (ret != 0) { 1745 dev_err(&pdev->dev, "wm8903: failed to register card\n");
1748 dev_err(&pdev->dev, "can't add i2c driver\n"); 1746 goto card_err;
1749 goto err_priv;
1750 } else {
1751 memset(&board_info, 0, sizeof(board_info));
1752 strlcpy(board_info.type, "wm8903", I2C_NAME_SIZE);
1753 board_info.addr = setup->i2c_address;
1754
1755 adapter = i2c_get_adapter(setup->i2c_bus);
1756 if (!adapter) {
1757 dev_err(&pdev->dev, "Can't get I2C bus %d\n",
1758 setup->i2c_bus);
1759 ret = -ENODEV;
1760 goto err_adapter;
1761 }
1762
1763 i2c_client = i2c_new_device(adapter, &board_info);
1764 i2c_put_adapter(adapter);
1765 if (i2c_client == NULL) {
1766 dev_err(&pdev->dev,
1767 "I2C driver registration failed\n");
1768 ret = -ENODEV;
1769 goto err_adapter;
1770 }
1771 } 1747 }
1772 1748
1773 return ret; 1749 return ret;
1774 1750
1775err_adapter: 1751card_err:
1776 i2c_del_driver(&wm8903_i2c_driver); 1752 snd_soc_free_pcms(socdev);
1777err_priv: 1753 snd_soc_dapm_free(socdev);
1778 kfree(codec->private_data); 1754err:
1779err_codec:
1780 kfree(codec);
1781 return ret; 1755 return ret;
1782} 1756}
1783 1757
@@ -1792,10 +1766,6 @@ static int wm8903_remove(struct platform_device *pdev)
1792 1766
1793 snd_soc_free_pcms(socdev); 1767 snd_soc_free_pcms(socdev);
1794 snd_soc_dapm_free(socdev); 1768 snd_soc_dapm_free(socdev);
1795 i2c_unregister_device(socdev->codec->control_data);
1796 i2c_del_driver(&wm8903_i2c_driver);
1797 kfree(codec->private_data);
1798 kfree(codec);
1799 1769
1800 return 0; 1770 return 0;
1801} 1771}
@@ -1808,6 +1778,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8903 = {
1808}; 1778};
1809EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903); 1779EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903);
1810 1780
1781static int __init wm8903_modinit(void)
1782{
1783 return i2c_add_driver(&wm8903_i2c_driver);
1784}
1785module_init(wm8903_modinit);
1786
1787static void __exit wm8903_exit(void)
1788{
1789 i2c_del_driver(&wm8903_i2c_driver);
1790}
1791module_exit(wm8903_exit);
1792
1811MODULE_DESCRIPTION("ASoC WM8903 driver"); 1793MODULE_DESCRIPTION("ASoC WM8903 driver");
1812MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>"); 1794MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.cm>");
1813MODULE_LICENSE("GPL"); 1795MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index cec622f2f660..0ea27e2b9963 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -18,11 +18,6 @@
18extern struct snd_soc_dai wm8903_dai; 18extern struct snd_soc_dai wm8903_dai;
19extern struct snd_soc_codec_device soc_codec_dev_wm8903; 19extern struct snd_soc_codec_device soc_codec_dev_wm8903;
20 20
21struct wm8903_setup_data {
22 int i2c_bus;
23 int i2c_address;
24};
25
26#define WM8903_MCLK_DIV_2 1 21#define WM8903_MCLK_DIV_2 1
27#define WM8903_CLK_SYS 2 22#define WM8903_CLK_SYS 2
28#define WM8903_BCLK 3 23#define WM8903_BCLK 3
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index f41a578ddd4f..88ead7f8dd98 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -541,7 +541,8 @@ static int wm8971_set_dai_fmt(struct snd_soc_dai *codec_dai,
541} 541}
542 542
543static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream, 543static int wm8971_pcm_hw_params(struct snd_pcm_substream *substream,
544 struct snd_pcm_hw_params *params) 544 struct snd_pcm_hw_params *params,
545 struct snd_soc_dai *dai)
545{ 546{
546 struct snd_soc_pcm_runtime *rtd = substream->private_data; 547 struct snd_soc_pcm_runtime *rtd = substream->private_data;
547 struct snd_soc_device *socdev = rtd->socdev; 548 struct snd_soc_device *socdev = rtd->socdev;
@@ -634,8 +635,6 @@ struct snd_soc_dai wm8971_dai = {
634 .formats = WM8971_FORMATS,}, 635 .formats = WM8971_FORMATS,},
635 .ops = { 636 .ops = {
636 .hw_params = wm8971_pcm_hw_params, 637 .hw_params = wm8971_pcm_hw_params,
637 },
638 .dai_ops = {
639 .digital_mute = wm8971_mute, 638 .digital_mute = wm8971_mute,
640 .set_fmt = wm8971_set_dai_fmt, 639 .set_fmt = wm8971_set_dai_fmt,
641 .set_sysclk = wm8971_set_dai_sysclk, 640 .set_sysclk = wm8971_set_dai_sysclk,
@@ -748,7 +747,7 @@ static int wm8971_init(struct snd_soc_device *socdev)
748 747
749 wm8971_add_controls(codec); 748 wm8971_add_controls(codec);
750 wm8971_add_widgets(codec); 749 wm8971_add_widgets(codec);
751 ret = snd_soc_register_card(socdev); 750 ret = snd_soc_init_card(socdev);
752 if (ret < 0) { 751 if (ret < 0) {
753 printk(KERN_ERR "wm8971: failed to register card\n"); 752 printk(KERN_ERR "wm8971: failed to register card\n");
754 goto card_err; 753 goto card_err;
@@ -936,6 +935,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8971 = {
936 935
937EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971); 936EXPORT_SYMBOL_GPL(soc_codec_dev_wm8971);
938 937
938static int __init wm8971_modinit(void)
939{
940 return snd_soc_register_dai(&wm8971_dai);
941}
942module_init(wm8971_modinit);
943
944static void __exit wm8971_exit(void)
945{
946 snd_soc_unregister_dai(&wm8971_dai);
947}
948module_exit(wm8971_exit);
949
939MODULE_DESCRIPTION("ASoC WM8971 driver"); 950MODULE_DESCRIPTION("ASoC WM8971 driver");
940MODULE_AUTHOR("Lab126"); 951MODULE_AUTHOR("Lab126");
941MODULE_LICENSE("GPL"); 952MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 572d22b0880b..5b5afc144478 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -106,6 +106,7 @@ static const u16 wm8990_reg[] = {
106 0x0008, /* R60 - PLL1 */ 106 0x0008, /* R60 - PLL1 */
107 0x0031, /* R61 - PLL2 */ 107 0x0031, /* R61 - PLL2 */
108 0x0026, /* R62 - PLL3 */ 108 0x0026, /* R62 - PLL3 */
109 0x0000, /* R63 - Driver internal */
109}; 110};
110 111
111/* 112/*
@@ -126,10 +127,9 @@ static inline void wm8990_write_reg_cache(struct snd_soc_codec *codec,
126 unsigned int reg, unsigned int value) 127 unsigned int reg, unsigned int value)
127{ 128{
128 u16 *cache = codec->reg_cache; 129 u16 *cache = codec->reg_cache;
129 BUG_ON(reg > (ARRAY_SIZE(wm8990_reg)) - 1);
130 130
131 /* Reset register is uncached */ 131 /* Reset register and reserved registers are uncached */
132 if (reg == 0) 132 if (reg == 0 || reg > ARRAY_SIZE(wm8990_reg) - 1)
133 return; 133 return;
134 134
135 cache[reg] = value; 135 cache[reg] = value;
@@ -1172,7 +1172,8 @@ static int wm8990_set_dai_clkdiv(struct snd_soc_dai *codec_dai,
1172 * Set PCM DAI bit size and sample rate. 1172 * Set PCM DAI bit size and sample rate.
1173 */ 1173 */
1174static int wm8990_hw_params(struct snd_pcm_substream *substream, 1174static int wm8990_hw_params(struct snd_pcm_substream *substream,
1175 struct snd_pcm_hw_params *params) 1175 struct snd_pcm_hw_params *params,
1176 struct snd_soc_dai *dai)
1176{ 1177{
1177 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1178 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1178 struct snd_soc_device *socdev = rtd->socdev; 1179 struct snd_soc_device *socdev = rtd->socdev;
@@ -1222,8 +1223,14 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1222 switch (level) { 1223 switch (level) {
1223 case SND_SOC_BIAS_ON: 1224 case SND_SOC_BIAS_ON:
1224 break; 1225 break;
1226
1225 case SND_SOC_BIAS_PREPARE: 1227 case SND_SOC_BIAS_PREPARE:
1228 /* VMID=2*50k */
1229 val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) &
1230 ~WM8990_VMID_MODE_MASK;
1231 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x2);
1226 break; 1232 break;
1233
1227 case SND_SOC_BIAS_STANDBY: 1234 case SND_SOC_BIAS_STANDBY:
1228 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1235 if (codec->bias_level == SND_SOC_BIAS_OFF) {
1229 /* Enable all output discharge bits */ 1236 /* Enable all output discharge bits */
@@ -1272,10 +1279,17 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1272 1279
1273 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */ 1280 /* disable POBCTRL, SOFT_ST and BUFDCOPEN */
1274 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN); 1281 wm8990_write(codec, WM8990_ANTIPOP2, WM8990_BUFIOEN);
1275 } else {
1276 /* ON -> standby */
1277 1282
1283 /* Enable workaround for ADC clocking issue. */
1284 wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0x2);
1285 wm8990_write(codec, WM8990_EXT_CTL1, 0xa003);
1286 wm8990_write(codec, WM8990_EXT_ACCESS_ENA, 0);
1278 } 1287 }
1288
1289 /* VMID=2*250k */
1290 val = wm8990_read_reg_cache(codec, WM8990_POWER_MANAGEMENT_1) &
1291 ~WM8990_VMID_MODE_MASK;
1292 wm8990_write(codec, WM8990_POWER_MANAGEMENT_1, val | 0x4);
1279 break; 1293 break;
1280 1294
1281 case SND_SOC_BIAS_OFF: 1295 case SND_SOC_BIAS_OFF:
@@ -1349,8 +1363,7 @@ struct snd_soc_dai wm8990_dai = {
1349 .rates = WM8990_RATES, 1363 .rates = WM8990_RATES,
1350 .formats = WM8990_FORMATS,}, 1364 .formats = WM8990_FORMATS,},
1351 .ops = { 1365 .ops = {
1352 .hw_params = wm8990_hw_params,}, 1366 .hw_params = wm8990_hw_params,
1353 .dai_ops = {
1354 .digital_mute = wm8990_mute, 1367 .digital_mute = wm8990_mute,
1355 .set_fmt = wm8990_set_dai_fmt, 1368 .set_fmt = wm8990_set_dai_fmt,
1356 .set_clkdiv = wm8990_set_dai_clkdiv, 1369 .set_clkdiv = wm8990_set_dai_clkdiv,
@@ -1449,7 +1462,7 @@ static int wm8990_init(struct snd_soc_device *socdev)
1449 1462
1450 wm8990_add_controls(codec); 1463 wm8990_add_controls(codec);
1451 wm8990_add_widgets(codec); 1464 wm8990_add_widgets(codec);
1452 ret = snd_soc_register_card(socdev); 1465 ret = snd_soc_init_card(socdev);
1453 if (ret < 0) { 1466 if (ret < 0) {
1454 printk(KERN_ERR "wm8990: failed to register card\n"); 1467 printk(KERN_ERR "wm8990: failed to register card\n");
1455 goto card_err; 1468 goto card_err;
@@ -1630,6 +1643,18 @@ struct snd_soc_codec_device soc_codec_dev_wm8990 = {
1630}; 1643};
1631EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990); 1644EXPORT_SYMBOL_GPL(soc_codec_dev_wm8990);
1632 1645
1646static int __init wm8990_modinit(void)
1647{
1648 return snd_soc_register_dai(&wm8990_dai);
1649}
1650module_init(wm8990_modinit);
1651
1652static void __exit wm8990_exit(void)
1653{
1654 snd_soc_unregister_dai(&wm8990_dai);
1655}
1656module_exit(wm8990_exit);
1657
1633MODULE_DESCRIPTION("ASoC WM8990 driver"); 1658MODULE_DESCRIPTION("ASoC WM8990 driver");
1634MODULE_AUTHOR("Liam Girdwood"); 1659MODULE_AUTHOR("Liam Girdwood");
1635MODULE_LICENSE("GPL"); 1660MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8990.h b/sound/soc/codecs/wm8990.h
index 0e192f3b0788..7114ddc88b4b 100644
--- a/sound/soc/codecs/wm8990.h
+++ b/sound/soc/codecs/wm8990.h
@@ -80,8 +80,8 @@
80#define WM8990_PLL3 0x3E 80#define WM8990_PLL3 0x3E
81#define WM8990_INTDRIVBITS 0x3F 81#define WM8990_INTDRIVBITS 0x3F
82 82
83#define WM8990_REGISTER_COUNT 60 83#define WM8990_EXT_ACCESS_ENA 0x75
84#define WM8990_MAX_REGISTER 0x3F 84#define WM8990_EXT_CTL1 0x7a
85 85
86/* 86/*
87 * Field Definitions. 87 * Field Definitions.
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index ffb471e420e2..af83d629078a 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -487,7 +487,8 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
487 return 0; 487 return 0;
488} 488}
489 489
490static int ac97_prepare(struct snd_pcm_substream *substream) 490static int ac97_prepare(struct snd_pcm_substream *substream,
491 struct snd_soc_dai *dai)
491{ 492{
492 struct snd_pcm_runtime *runtime = substream->runtime; 493 struct snd_pcm_runtime *runtime = substream->runtime;
493 struct snd_soc_pcm_runtime *rtd = substream->private_data; 494 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -507,7 +508,8 @@ static int ac97_prepare(struct snd_pcm_substream *substream)
507 return ac97_write(codec, reg, runtime->rate); 508 return ac97_write(codec, reg, runtime->rate);
508} 509}
509 510
510static int ac97_aux_prepare(struct snd_pcm_substream *substream) 511static int ac97_aux_prepare(struct snd_pcm_substream *substream,
512 struct snd_soc_dai *dai)
511{ 513{
512 struct snd_pcm_runtime *runtime = substream->runtime; 514 struct snd_pcm_runtime *runtime = substream->runtime;
513 struct snd_soc_pcm_runtime *rtd = substream->private_data; 515 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -533,7 +535,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
533struct snd_soc_dai wm9712_dai[] = { 535struct snd_soc_dai wm9712_dai[] = {
534{ 536{
535 .name = "AC97 HiFi", 537 .name = "AC97 HiFi",
536 .type = SND_SOC_DAI_AC97_BUS, 538 .ac97_control = 1,
537 .playback = { 539 .playback = {
538 .stream_name = "HiFi Playback", 540 .stream_name = "HiFi Playback",
539 .channels_min = 1, 541 .channels_min = 1,
@@ -688,7 +690,7 @@ static int wm9712_soc_probe(struct platform_device *pdev)
688 690
689 ret = wm9712_reset(codec, 0); 691 ret = wm9712_reset(codec, 0);
690 if (ret < 0) { 692 if (ret < 0) {
691 printk(KERN_ERR "AC97 link error\n"); 693 printk(KERN_ERR "Failed to reset WM9712: AC97 link error\n");
692 goto reset_err; 694 goto reset_err;
693 } 695 }
694 696
@@ -698,7 +700,7 @@ static int wm9712_soc_probe(struct platform_device *pdev)
698 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 700 wm9712_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
699 wm9712_add_controls(codec); 701 wm9712_add_controls(codec);
700 wm9712_add_widgets(codec); 702 wm9712_add_widgets(codec);
701 ret = snd_soc_register_card(socdev); 703 ret = snd_soc_init_card(socdev);
702 if (ret < 0) { 704 if (ret < 0) {
703 printk(KERN_ERR "wm9712: failed to register card\n"); 705 printk(KERN_ERR "wm9712: failed to register card\n");
704 goto reset_err; 706 goto reset_err;
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 945b32ed9884..f3ca8aaf0139 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -928,11 +928,10 @@ static int wm9713_set_dai_fmt(struct snd_soc_dai *codec_dai,
928} 928}
929 929
930static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream, 930static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
931 struct snd_pcm_hw_params *params) 931 struct snd_pcm_hw_params *params,
932 struct snd_soc_dai *dai)
932{ 933{
933 struct snd_soc_pcm_runtime *rtd = substream->private_data; 934 struct snd_soc_codec *codec = dai->codec;
934 struct snd_soc_device *socdev = rtd->socdev;
935 struct snd_soc_codec *codec = socdev->codec;
936 u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3; 935 u16 reg = ac97_read(codec, AC97_CENTER_LFE_MASTER) & 0xfff3;
937 936
938 switch (params_format(params)) { 937 switch (params_format(params)) {
@@ -954,11 +953,10 @@ static int wm9713_pcm_hw_params(struct snd_pcm_substream *substream,
954 return 0; 953 return 0;
955} 954}
956 955
957static void wm9713_voiceshutdown(struct snd_pcm_substream *substream) 956static void wm9713_voiceshutdown(struct snd_pcm_substream *substream,
957 struct snd_soc_dai *dai)
958{ 958{
959 struct snd_soc_pcm_runtime *rtd = substream->private_data; 959 struct snd_soc_codec *codec = dai->codec;
960 struct snd_soc_device *socdev = rtd->socdev;
961 struct snd_soc_codec *codec = socdev->codec;
962 u16 status; 960 u16 status;
963 961
964 /* Gracefully shut down the voice interface. */ 962 /* Gracefully shut down the voice interface. */
@@ -969,12 +967,11 @@ static void wm9713_voiceshutdown(struct snd_pcm_substream *substream)
969 ac97_write(codec, AC97_EXTENDED_MID, status); 967 ac97_write(codec, AC97_EXTENDED_MID, status);
970} 968}
971 969
972static int ac97_hifi_prepare(struct snd_pcm_substream *substream) 970static int ac97_hifi_prepare(struct snd_pcm_substream *substream,
971 struct snd_soc_dai *dai)
973{ 972{
973 struct snd_soc_codec *codec = dai->codec;
974 struct snd_pcm_runtime *runtime = substream->runtime; 974 struct snd_pcm_runtime *runtime = substream->runtime;
975 struct snd_soc_pcm_runtime *rtd = substream->private_data;
976 struct snd_soc_device *socdev = rtd->socdev;
977 struct snd_soc_codec *codec = socdev->codec;
978 int reg; 975 int reg;
979 u16 vra; 976 u16 vra;
980 977
@@ -989,12 +986,11 @@ static int ac97_hifi_prepare(struct snd_pcm_substream *substream)
989 return ac97_write(codec, reg, runtime->rate); 986 return ac97_write(codec, reg, runtime->rate);
990} 987}
991 988
992static int ac97_aux_prepare(struct snd_pcm_substream *substream) 989static int ac97_aux_prepare(struct snd_pcm_substream *substream,
990 struct snd_soc_dai *dai)
993{ 991{
992 struct snd_soc_codec *codec = dai->codec;
994 struct snd_pcm_runtime *runtime = substream->runtime; 993 struct snd_pcm_runtime *runtime = substream->runtime;
995 struct snd_soc_pcm_runtime *rtd = substream->private_data;
996 struct snd_soc_device *socdev = rtd->socdev;
997 struct snd_soc_codec *codec = socdev->codec;
998 u16 vra, xsle; 994 u16 vra, xsle;
999 995
1000 vra = ac97_read(codec, AC97_EXTENDED_STATUS); 996 vra = ac97_read(codec, AC97_EXTENDED_STATUS);
@@ -1028,7 +1024,7 @@ static int ac97_aux_prepare(struct snd_pcm_substream *substream)
1028struct snd_soc_dai wm9713_dai[] = { 1024struct snd_soc_dai wm9713_dai[] = {
1029{ 1025{
1030 .name = "AC97 HiFi", 1026 .name = "AC97 HiFi",
1031 .type = SND_SOC_DAI_AC97_BUS, 1027 .ac97_control = 1,
1032 .playback = { 1028 .playback = {
1033 .stream_name = "HiFi Playback", 1029 .stream_name = "HiFi Playback",
1034 .channels_min = 1, 1030 .channels_min = 1,
@@ -1042,8 +1038,7 @@ struct snd_soc_dai wm9713_dai[] = {
1042 .rates = WM9713_RATES, 1038 .rates = WM9713_RATES,
1043 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1039 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
1044 .ops = { 1040 .ops = {
1045 .prepare = ac97_hifi_prepare,}, 1041 .prepare = ac97_hifi_prepare,
1046 .dai_ops = {
1047 .set_clkdiv = wm9713_set_dai_clkdiv, 1042 .set_clkdiv = wm9713_set_dai_clkdiv,
1048 .set_pll = wm9713_set_dai_pll,}, 1043 .set_pll = wm9713_set_dai_pll,},
1049 }, 1044 },
@@ -1056,8 +1051,7 @@ struct snd_soc_dai wm9713_dai[] = {
1056 .rates = WM9713_RATES, 1051 .rates = WM9713_RATES,
1057 .formats = SNDRV_PCM_FMTBIT_S16_LE,}, 1052 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
1058 .ops = { 1053 .ops = {
1059 .prepare = ac97_aux_prepare,}, 1054 .prepare = ac97_aux_prepare,
1060 .dai_ops = {
1061 .set_clkdiv = wm9713_set_dai_clkdiv, 1055 .set_clkdiv = wm9713_set_dai_clkdiv,
1062 .set_pll = wm9713_set_dai_pll,}, 1056 .set_pll = wm9713_set_dai_pll,},
1063 }, 1057 },
@@ -1077,8 +1071,7 @@ struct snd_soc_dai wm9713_dai[] = {
1077 .formats = WM9713_PCM_FORMATS,}, 1071 .formats = WM9713_PCM_FORMATS,},
1078 .ops = { 1072 .ops = {
1079 .hw_params = wm9713_pcm_hw_params, 1073 .hw_params = wm9713_pcm_hw_params,
1080 .shutdown = wm9713_voiceshutdown,}, 1074 .shutdown = wm9713_voiceshutdown,
1081 .dai_ops = {
1082 .set_clkdiv = wm9713_set_dai_clkdiv, 1075 .set_clkdiv = wm9713_set_dai_clkdiv,
1083 .set_pll = wm9713_set_dai_pll, 1076 .set_pll = wm9713_set_dai_pll,
1084 .set_fmt = wm9713_set_dai_fmt, 1077 .set_fmt = wm9713_set_dai_fmt,
@@ -1097,6 +1090,8 @@ int wm9713_reset(struct snd_soc_codec *codec, int try_warm)
1097 } 1090 }
1098 1091
1099 soc_ac97_ops.reset(codec->ac97); 1092 soc_ac97_ops.reset(codec->ac97);
1093 if (soc_ac97_ops.warm_reset)
1094 soc_ac97_ops.warm_reset(codec->ac97);
1100 if (ac97_read(codec, 0) != wm9713_reg[0]) 1095 if (ac97_read(codec, 0) != wm9713_reg[0])
1101 return -EIO; 1096 return -EIO;
1102 return 0; 1097 return 0;
@@ -1240,7 +1235,7 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1240 wm9713_reset(codec, 0); 1235 wm9713_reset(codec, 0);
1241 ret = wm9713_reset(codec, 1); 1236 ret = wm9713_reset(codec, 1);
1242 if (ret < 0) { 1237 if (ret < 0) {
1243 printk(KERN_ERR "AC97 link error\n"); 1238 printk(KERN_ERR "Failed to reset WM9713: AC97 link error\n");
1244 goto reset_err; 1239 goto reset_err;
1245 } 1240 }
1246 1241
@@ -1252,7 +1247,7 @@ static int wm9713_soc_probe(struct platform_device *pdev)
1252 1247
1253 wm9713_add_controls(codec); 1248 wm9713_add_controls(codec);
1254 wm9713_add_widgets(codec); 1249 wm9713_add_widgets(codec);
1255 ret = snd_soc_register_card(socdev); 1250 ret = snd_soc_init_card(socdev);
1256 if (ret < 0) 1251 if (ret < 0)
1257 goto reset_err; 1252 goto reset_err;
1258 return 0; 1253 return 0;
@@ -1288,7 +1283,6 @@ static int wm9713_soc_remove(struct platform_device *pdev)
1288 snd_soc_free_ac97_codec(codec); 1283 snd_soc_free_ac97_codec(codec);
1289 kfree(codec->private_data); 1284 kfree(codec->private_data);
1290 kfree(codec->reg_cache); 1285 kfree(codec->reg_cache);
1291 kfree(codec->dai);
1292 kfree(codec); 1286 kfree(codec);
1293 return 0; 1287 return 0;
1294} 1288}
diff --git a/sound/soc/davinci/Kconfig b/sound/soc/davinci/Kconfig
index 8f7e33834902..b502741692d6 100644
--- a/sound/soc/davinci/Kconfig
+++ b/sound/soc/davinci/Kconfig
@@ -17,3 +17,13 @@ config SND_DAVINCI_SOC_EVM
17 help 17 help
18 Say Y if you want to add support for SoC audio on TI 18 Say Y if you want to add support for SoC audio on TI
19 DaVinci EVM platform. 19 DaVinci EVM platform.
20
21config SND_DAVINCI_SOC_SFFSDR
22 tristate "SoC Audio support for SFFSDR"
23 depends on SND_DAVINCI_SOC && MACH_DAVINCI_SFFSDR
24 select SND_DAVINCI_SOC_I2S
25 select SND_SOC_PCM3008
26 select SFFSDR_FPGA
27 help
28 Say Y if you want to add support for SoC audio on
29 Lyrtech SFFSDR board.
diff --git a/sound/soc/davinci/Makefile b/sound/soc/davinci/Makefile
index ca772e5b4637..ca8bae1fc3f6 100644
--- a/sound/soc/davinci/Makefile
+++ b/sound/soc/davinci/Makefile
@@ -7,5 +7,7 @@ obj-$(CONFIG_SND_DAVINCI_SOC_I2S) += snd-soc-davinci-i2s.o
7 7
8# DAVINCI Machine Support 8# DAVINCI Machine Support
9snd-soc-evm-objs := davinci-evm.o 9snd-soc-evm-objs := davinci-evm.o
10snd-soc-sffsdr-objs := davinci-sffsdr.o
10 11
11obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o 12obj-$(CONFIG_SND_DAVINCI_SOC_EVM) += snd-soc-evm.o
13obj-$(CONFIG_SND_DAVINCI_SOC_SFFSDR) += snd-soc-sffsdr.o
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index 9e6062cd6b59..01b948bb55a1 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -28,6 +28,8 @@
28 28
29#define EVM_CODEC_CLOCK 22579200 29#define EVM_CODEC_CLOCK 22579200
30 30
31#define AUDIO_FORMAT (SND_SOC_DAIFMT_DSP_B | \
32 SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_IB_NF)
31static int evm_hw_params(struct snd_pcm_substream *substream, 33static int evm_hw_params(struct snd_pcm_substream *substream,
32 struct snd_pcm_hw_params *params) 34 struct snd_pcm_hw_params *params)
33{ 35{
@@ -37,14 +39,12 @@ static int evm_hw_params(struct snd_pcm_substream *substream,
37 int ret = 0; 39 int ret = 0;
38 40
39 /* set codec DAI configuration */ 41 /* set codec DAI configuration */
40 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 42 ret = snd_soc_dai_set_fmt(codec_dai, AUDIO_FORMAT);
41 SND_SOC_DAIFMT_CBM_CFM);
42 if (ret < 0) 43 if (ret < 0)
43 return ret; 44 return ret;
44 45
45 /* set cpu DAI configuration */ 46 /* set cpu DAI configuration */
46 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_CBM_CFM | 47 ret = snd_soc_dai_set_fmt(cpu_dai, AUDIO_FORMAT);
47 SND_SOC_DAIFMT_IB_NF);
48 if (ret < 0) 48 if (ret < 0)
49 return ret; 49 return ret;
50 50
@@ -128,8 +128,9 @@ static struct snd_soc_dai_link evm_dai = {
128}; 128};
129 129
130/* davinci-evm audio machine driver */ 130/* davinci-evm audio machine driver */
131static struct snd_soc_machine snd_soc_machine_evm = { 131static struct snd_soc_card snd_soc_card_evm = {
132 .name = "DaVinci EVM", 132 .name = "DaVinci EVM",
133 .platform = &davinci_soc_platform,
133 .dai_link = &evm_dai, 134 .dai_link = &evm_dai,
134 .num_links = 1, 135 .num_links = 1,
135}; 136};
@@ -142,8 +143,7 @@ static struct aic3x_setup_data evm_aic3x_setup = {
142 143
143/* evm audio subsystem */ 144/* evm audio subsystem */
144static struct snd_soc_device evm_snd_devdata = { 145static struct snd_soc_device evm_snd_devdata = {
145 .machine = &snd_soc_machine_evm, 146 .card = &snd_soc_card_evm,
146 .platform = &davinci_soc_platform,
147 .codec_dev = &soc_codec_dev_aic3x, 147 .codec_dev = &soc_codec_dev_aic3x,
148 .codec_data = &evm_aic3x_setup, 148 .codec_data = &evm_aic3x_setup,
149}; 149};
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c
index abb5fedb0b1e..0fee779e3c76 100644
--- a/sound/soc/davinci/davinci-i2s.c
+++ b/sound/soc/davinci/davinci-i2s.c
@@ -59,6 +59,7 @@
59#define DAVINCI_MCBSP_PCR_CLKXP (1 << 1) 59#define DAVINCI_MCBSP_PCR_CLKXP (1 << 1)
60#define DAVINCI_MCBSP_PCR_FSRP (1 << 2) 60#define DAVINCI_MCBSP_PCR_FSRP (1 << 2)
61#define DAVINCI_MCBSP_PCR_FSXP (1 << 3) 61#define DAVINCI_MCBSP_PCR_FSXP (1 << 3)
62#define DAVINCI_MCBSP_PCR_SCLKME (1 << 7)
62#define DAVINCI_MCBSP_PCR_CLKRM (1 << 8) 63#define DAVINCI_MCBSP_PCR_CLKRM (1 << 8)
63#define DAVINCI_MCBSP_PCR_CLKXM (1 << 9) 64#define DAVINCI_MCBSP_PCR_CLKXM (1 << 9)
64#define DAVINCI_MCBSP_PCR_FSRM (1 << 10) 65#define DAVINCI_MCBSP_PCR_FSRM (1 << 10)
@@ -110,16 +111,59 @@ static void davinci_mcbsp_start(struct snd_pcm_substream *substream)
110{ 111{
111 struct snd_soc_pcm_runtime *rtd = substream->private_data; 112 struct snd_soc_pcm_runtime *rtd = substream->private_data;
112 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data; 113 struct davinci_mcbsp_dev *dev = rtd->dai->cpu_dai->private_data;
114 struct snd_soc_device *socdev = rtd->socdev;
115 struct snd_soc_platform *platform = socdev->card->platform;
113 u32 w; 116 u32 w;
117 int ret;
114 118
115 /* Start the sample generator and enable transmitter/receiver */ 119 /* Start the sample generator and enable transmitter/receiver */
116 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 120 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
117 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST, 1); 121 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_GRST, 1);
118 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 122 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
123
124 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
125 /* Stop the DMA to avoid data loss */
126 /* while the transmitter is out of reset to handle XSYNCERR */
127 if (platform->pcm_ops->trigger) {
128 ret = platform->pcm_ops->trigger(substream,
129 SNDRV_PCM_TRIGGER_STOP);
130 if (ret < 0)
131 printk(KERN_DEBUG "Playback DMA stop failed\n");
132 }
133
134 /* Enable the transmitter */
135 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
119 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1); 136 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1);
120 else 137 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
138
139 /* wait for any unexpected frame sync error to occur */
140 udelay(100);
141
142 /* Disable the transmitter to clear any outstanding XSYNCERR */
143 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
144 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 0);
145 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
146
147 /* Restart the DMA */
148 if (platform->pcm_ops->trigger) {
149 ret = platform->pcm_ops->trigger(substream,
150 SNDRV_PCM_TRIGGER_START);
151 if (ret < 0)
152 printk(KERN_DEBUG "Playback DMA start failed\n");
153 }
154 /* Enable the transmitter */
155 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
156 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_XRST, 1);
157 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
158
159 } else {
160
161 /* Enable the reciever */
162 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
121 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 1); 163 MOD_REG_BIT(w, DAVINCI_MCBSP_SPCR_RRST, 1);
122 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 164 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
165 }
166
123 167
124 /* Start frame sync */ 168 /* Start frame sync */
125 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG); 169 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
@@ -144,7 +188,8 @@ static void davinci_mcbsp_stop(struct snd_pcm_substream *substream)
144 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w); 188 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
145} 189}
146 190
147static int davinci_i2s_startup(struct snd_pcm_substream *substream) 191static int davinci_i2s_startup(struct snd_pcm_substream *substream,
192 struct snd_soc_dai *dai)
148{ 193{
149 struct snd_soc_pcm_runtime *rtd = substream->private_data; 194 struct snd_soc_pcm_runtime *rtd = substream->private_data;
150 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 195 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -155,61 +200,138 @@ static int davinci_i2s_startup(struct snd_pcm_substream *substream)
155 return 0; 200 return 0;
156} 201}
157 202
203#define DEFAULT_BITPERSAMPLE 16
204
158static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai, 205static int davinci_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
159 unsigned int fmt) 206 unsigned int fmt)
160{ 207{
161 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 208 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
162 u32 w; 209 unsigned int pcr;
210 unsigned int srgr;
211 unsigned int rcr;
212 unsigned int xcr;
213 srgr = DAVINCI_MCBSP_SRGR_FSGM |
214 DAVINCI_MCBSP_SRGR_FPER(DEFAULT_BITPERSAMPLE * 2 - 1) |
215 DAVINCI_MCBSP_SRGR_FWID(DEFAULT_BITPERSAMPLE - 1);
163 216
164 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 217 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
165 case SND_SOC_DAIFMT_CBS_CFS: 218 case SND_SOC_DAIFMT_CBS_CFS:
166 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, 219 /* cpu is master */
167 DAVINCI_MCBSP_PCR_FSXM | 220 pcr = DAVINCI_MCBSP_PCR_FSXM |
168 DAVINCI_MCBSP_PCR_FSRM | 221 DAVINCI_MCBSP_PCR_FSRM |
169 DAVINCI_MCBSP_PCR_CLKXM | 222 DAVINCI_MCBSP_PCR_CLKXM |
170 DAVINCI_MCBSP_PCR_CLKRM); 223 DAVINCI_MCBSP_PCR_CLKRM;
171 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, 224 break;
172 DAVINCI_MCBSP_SRGR_FSGM); 225 case SND_SOC_DAIFMT_CBM_CFS:
226 /* McBSP CLKR pin is the input for the Sample Rate Generator.
227 * McBSP FSR and FSX are driven by the Sample Rate Generator. */
228 pcr = DAVINCI_MCBSP_PCR_SCLKME |
229 DAVINCI_MCBSP_PCR_FSXM |
230 DAVINCI_MCBSP_PCR_FSRM;
173 break; 231 break;
174 case SND_SOC_DAIFMT_CBM_CFM: 232 case SND_SOC_DAIFMT_CBM_CFM:
175 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, 0); 233 /* codec is master */
234 pcr = 0;
176 break; 235 break;
177 default: 236 default:
237 printk(KERN_ERR "%s:bad master\n", __func__);
178 return -EINVAL; 238 return -EINVAL;
179 } 239 }
180 240
181 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 241 rcr = DAVINCI_MCBSP_RCR_RFRLEN1(1);
182 case SND_SOC_DAIFMT_IB_NF: 242 xcr = DAVINCI_MCBSP_XCR_XFIG | DAVINCI_MCBSP_XCR_XFRLEN1(1);
183 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_PCR_REG); 243 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
184 MOD_REG_BIT(w, DAVINCI_MCBSP_PCR_CLKXP | 244 case SND_SOC_DAIFMT_DSP_B:
185 DAVINCI_MCBSP_PCR_CLKRP, 1);
186 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, w);
187 break; 245 break;
188 case SND_SOC_DAIFMT_NB_IF: 246 case SND_SOC_DAIFMT_I2S:
189 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_PCR_REG); 247 /* Davinci doesn't support TRUE I2S, but some codecs will have
190 MOD_REG_BIT(w, DAVINCI_MCBSP_PCR_FSXP | 248 * the left and right channels contiguous. This allows
191 DAVINCI_MCBSP_PCR_FSRP, 1); 249 * dsp_a mode to be used with an inverted normal frame clk.
192 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, w); 250 * If your codec is master and does not have contiguous
251 * channels, then you will have sound on only one channel.
252 * Try using a different mode, or codec as slave.
253 *
254 * The TLV320AIC33 is an example of a codec where this works.
255 * It has a variable bit clock frequency allowing it to have
256 * valid data on every bit clock.
257 *
258 * The TLV320AIC23 is an example of a codec where this does not
259 * work. It has a fixed bit clock frequency with progressively
260 * more empty bit clock slots between channels as the sample
261 * rate is lowered.
262 */
263 fmt ^= SND_SOC_DAIFMT_NB_IF;
264 case SND_SOC_DAIFMT_DSP_A:
265 rcr |= DAVINCI_MCBSP_RCR_RDATDLY(1);
266 xcr |= DAVINCI_MCBSP_XCR_XDATDLY(1);
267 break;
268 default:
269 printk(KERN_ERR "%s:bad format\n", __func__);
270 return -EINVAL;
271 }
272
273 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
274 case SND_SOC_DAIFMT_NB_NF:
275 /* CLKRP Receive clock polarity,
276 * 1 - sampled on rising edge of CLKR
277 * valid on rising edge
278 * CLKXP Transmit clock polarity,
279 * 1 - clocked on falling edge of CLKX
280 * valid on rising edge
281 * FSRP Receive frame sync pol, 0 - active high
282 * FSXP Transmit frame sync pol, 0 - active high
283 */
284 pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP);
193 break; 285 break;
194 case SND_SOC_DAIFMT_IB_IF: 286 case SND_SOC_DAIFMT_IB_IF:
195 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_PCR_REG); 287 /* CLKRP Receive clock polarity,
196 MOD_REG_BIT(w, DAVINCI_MCBSP_PCR_CLKXP | 288 * 0 - sampled on falling edge of CLKR
197 DAVINCI_MCBSP_PCR_CLKRP | 289 * valid on falling edge
198 DAVINCI_MCBSP_PCR_FSXP | 290 * CLKXP Transmit clock polarity,
199 DAVINCI_MCBSP_PCR_FSRP, 1); 291 * 0 - clocked on rising edge of CLKX
200 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, w); 292 * valid on falling edge
293 * FSRP Receive frame sync pol, 1 - active low
294 * FSXP Transmit frame sync pol, 1 - active low
295 */
296 pcr |= (DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
201 break; 297 break;
202 case SND_SOC_DAIFMT_NB_NF: 298 case SND_SOC_DAIFMT_NB_IF:
299 /* CLKRP Receive clock polarity,
300 * 1 - sampled on rising edge of CLKR
301 * valid on rising edge
302 * CLKXP Transmit clock polarity,
303 * 1 - clocked on falling edge of CLKX
304 * valid on rising edge
305 * FSRP Receive frame sync pol, 1 - active low
306 * FSXP Transmit frame sync pol, 1 - active low
307 */
308 pcr |= (DAVINCI_MCBSP_PCR_CLKXP | DAVINCI_MCBSP_PCR_CLKRP |
309 DAVINCI_MCBSP_PCR_FSXP | DAVINCI_MCBSP_PCR_FSRP);
310 break;
311 case SND_SOC_DAIFMT_IB_NF:
312 /* CLKRP Receive clock polarity,
313 * 0 - sampled on falling edge of CLKR
314 * valid on falling edge
315 * CLKXP Transmit clock polarity,
316 * 0 - clocked on rising edge of CLKX
317 * valid on falling edge
318 * FSRP Receive frame sync pol, 0 - active high
319 * FSXP Transmit frame sync pol, 0 - active high
320 */
203 break; 321 break;
204 default: 322 default:
205 return -EINVAL; 323 return -EINVAL;
206 } 324 }
207 325 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, srgr);
326 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_PCR_REG, pcr);
327 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, rcr);
328 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, xcr);
208 return 0; 329 return 0;
209} 330}
210 331
211static int davinci_i2s_hw_params(struct snd_pcm_substream *substream, 332static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
212 struct snd_pcm_hw_params *params) 333 struct snd_pcm_hw_params *params,
334 struct snd_soc_dai *dai)
213{ 335{
214 struct snd_soc_pcm_runtime *rtd = substream->private_data; 336 struct snd_soc_pcm_runtime *rtd = substream->private_data;
215 struct davinci_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; 337 struct davinci_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data;
@@ -219,25 +341,20 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
219 u32 w; 341 u32 w;
220 342
221 /* general line settings */ 343 /* general line settings */
222 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, 344 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SPCR_REG);
223 DAVINCI_MCBSP_SPCR_RINTM(3) | 345 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
224 DAVINCI_MCBSP_SPCR_XINTM(3) | 346 w |= DAVINCI_MCBSP_SPCR_RINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
225 DAVINCI_MCBSP_SPCR_FREE); 347 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
226 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, 348 } else {
227 DAVINCI_MCBSP_RCR_RFRLEN1(1) | 349 w |= DAVINCI_MCBSP_SPCR_XINTM(3) | DAVINCI_MCBSP_SPCR_FREE;
228 DAVINCI_MCBSP_RCR_RDATDLY(1)); 350 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SPCR_REG, w);
229 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, 351 }
230 DAVINCI_MCBSP_XCR_XFRLEN1(1) |
231 DAVINCI_MCBSP_XCR_XDATDLY(1) |
232 DAVINCI_MCBSP_XCR_XFIG);
233 352
234 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS); 353 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS);
235 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SRGR_REG); 354 w = DAVINCI_MCBSP_SRGR_FSGM;
236 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1), 1); 355 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FWID(snd_interval_value(i) - 1), 1);
237 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w);
238 356
239 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS); 357 i = hw_param_interval(params, SNDRV_PCM_HW_PARAM_FRAME_BITS);
240 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_SRGR_REG);
241 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1), 1); 358 MOD_REG_BIT(w, DAVINCI_MCBSP_SRGR_FPER(snd_interval_value(i) - 1), 1);
242 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w); 359 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_SRGR_REG, w);
243 360
@@ -260,20 +377,24 @@ static int davinci_i2s_hw_params(struct snd_pcm_substream *substream,
260 return -EINVAL; 377 return -EINVAL;
261 } 378 }
262 379
263 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG); 380 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
264 MOD_REG_BIT(w, DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) | 381 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_RCR_REG);
265 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length), 1); 382 MOD_REG_BIT(w, DAVINCI_MCBSP_RCR_RWDLEN1(mcbsp_word_length) |
266 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, w); 383 DAVINCI_MCBSP_RCR_RWDLEN2(mcbsp_word_length), 1);
384 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_RCR_REG, w);
267 385
268 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG); 386 } else {
269 MOD_REG_BIT(w, DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) | 387 w = davinci_mcbsp_read_reg(dev, DAVINCI_MCBSP_XCR_REG);
270 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length), 1); 388 MOD_REG_BIT(w, DAVINCI_MCBSP_XCR_XWDLEN1(mcbsp_word_length) |
271 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, w); 389 DAVINCI_MCBSP_XCR_XWDLEN2(mcbsp_word_length), 1);
390 davinci_mcbsp_write_reg(dev, DAVINCI_MCBSP_XCR_REG, w);
272 391
392 }
273 return 0; 393 return 0;
274} 394}
275 395
276static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 396static int davinci_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
397 struct snd_soc_dai *dai)
277{ 398{
278 int ret = 0; 399 int ret = 0;
279 400
@@ -299,8 +420,8 @@ static int davinci_i2s_probe(struct platform_device *pdev,
299 struct snd_soc_dai *dai) 420 struct snd_soc_dai *dai)
300{ 421{
301 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 422 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
302 struct snd_soc_machine *machine = socdev->machine; 423 struct snd_soc_card *card = socdev->card;
303 struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; 424 struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
304 struct davinci_mcbsp_dev *dev; 425 struct davinci_mcbsp_dev *dev;
305 struct resource *mem, *ioarea; 426 struct resource *mem, *ioarea;
306 struct evm_snd_platform_data *pdata; 427 struct evm_snd_platform_data *pdata;
@@ -361,8 +482,8 @@ static void davinci_i2s_remove(struct platform_device *pdev,
361 struct snd_soc_dai *dai) 482 struct snd_soc_dai *dai)
362{ 483{
363 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 484 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
364 struct snd_soc_machine *machine = socdev->machine; 485 struct snd_soc_card *card = socdev->card;
365 struct snd_soc_dai *cpu_dai = machine->dai_link[pdev->id].cpu_dai; 486 struct snd_soc_dai *cpu_dai = card->dai_link[pdev->id].cpu_dai;
366 struct davinci_mcbsp_dev *dev = cpu_dai->private_data; 487 struct davinci_mcbsp_dev *dev = cpu_dai->private_data;
367 struct resource *mem; 488 struct resource *mem;
368 489
@@ -381,7 +502,6 @@ static void davinci_i2s_remove(struct platform_device *pdev,
381struct snd_soc_dai davinci_i2s_dai = { 502struct snd_soc_dai davinci_i2s_dai = {
382 .name = "davinci-i2s", 503 .name = "davinci-i2s",
383 .id = 0, 504 .id = 0,
384 .type = SND_SOC_DAI_I2S,
385 .probe = davinci_i2s_probe, 505 .probe = davinci_i2s_probe,
386 .remove = davinci_i2s_remove, 506 .remove = davinci_i2s_remove,
387 .playback = { 507 .playback = {
@@ -397,13 +517,24 @@ struct snd_soc_dai davinci_i2s_dai = {
397 .ops = { 517 .ops = {
398 .startup = davinci_i2s_startup, 518 .startup = davinci_i2s_startup,
399 .trigger = davinci_i2s_trigger, 519 .trigger = davinci_i2s_trigger,
400 .hw_params = davinci_i2s_hw_params,}, 520 .hw_params = davinci_i2s_hw_params,
401 .dai_ops = {
402 .set_fmt = davinci_i2s_set_dai_fmt, 521 .set_fmt = davinci_i2s_set_dai_fmt,
403 }, 522 },
404}; 523};
405EXPORT_SYMBOL_GPL(davinci_i2s_dai); 524EXPORT_SYMBOL_GPL(davinci_i2s_dai);
406 525
526static int __init davinci_i2s_init(void)
527{
528 return snd_soc_register_dai(&davinci_i2s_dai);
529}
530module_init(davinci_i2s_init);
531
532static void __exit davinci_i2s_exit(void)
533{
534 snd_soc_unregister_dai(&davinci_i2s_dai);
535}
536module_exit(davinci_i2s_exit);
537
407MODULE_AUTHOR("Vladimir Barinov"); 538MODULE_AUTHOR("Vladimir Barinov");
408MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface"); 539MODULE_DESCRIPTION("TI DAVINCI I2S (McBSP) SoC Interface");
409MODULE_LICENSE("GPL"); 540MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c
index 76feaa657375..74abc9b4f1cc 100644
--- a/sound/soc/davinci/davinci-pcm.c
+++ b/sound/soc/davinci/davinci-pcm.c
@@ -14,6 +14,7 @@
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/dma-mapping.h> 16#include <linux/dma-mapping.h>
17#include <linux/kernel.h>
17 18
18#include <sound/core.h> 19#include <sound/core.h>
19#include <sound/pcm.h> 20#include <sound/pcm.h>
@@ -24,13 +25,6 @@
24 25
25#include "davinci-pcm.h" 26#include "davinci-pcm.h"
26 27
27#define DAVINCI_PCM_DEBUG 0
28#if DAVINCI_PCM_DEBUG
29#define DPRINTK(x...) printk(KERN_DEBUG x)
30#else
31#define DPRINTK(x...)
32#endif
33
34static struct snd_pcm_hardware davinci_pcm_hardware = { 28static struct snd_pcm_hardware davinci_pcm_hardware = {
35 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | 29 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
36 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | 30 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
@@ -78,8 +72,8 @@ static void davinci_pcm_enqueue_dma(struct snd_pcm_substream *substream)
78 dma_offset = prtd->period * period_size; 72 dma_offset = prtd->period * period_size;
79 dma_pos = runtime->dma_addr + dma_offset; 73 dma_pos = runtime->dma_addr + dma_offset;
80 74
81 DPRINTK("audio_set_dma_params_play channel = %d dma_ptr = %x " 75 pr_debug("davinci_pcm: audio_set_dma_params_play channel = %d "
82 "period_size=%x\n", lch, dma_pos, period_size); 76 "dma_ptr = %x period_size=%x\n", lch, dma_pos, period_size);
83 77
84 data_type = prtd->params->data_type; 78 data_type = prtd->params->data_type;
85 count = period_size / data_type; 79 count = period_size / data_type;
@@ -112,7 +106,7 @@ static void davinci_pcm_dma_irq(int lch, u16 ch_status, void *data)
112 struct snd_pcm_substream *substream = data; 106 struct snd_pcm_substream *substream = data;
113 struct davinci_runtime_data *prtd = substream->runtime->private_data; 107 struct davinci_runtime_data *prtd = substream->runtime->private_data;
114 108
115 DPRINTK("lch=%d, status=0x%x\n", lch, ch_status); 109 pr_debug("davinci_pcm: lch=%d, status=0x%x\n", lch, ch_status);
116 110
117 if (unlikely(ch_status != DMA_COMPLETE)) 111 if (unlikely(ch_status != DMA_COMPLETE))
118 return; 112 return;
@@ -316,8 +310,8 @@ static int davinci_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
316 buf->area = dma_alloc_writecombine(pcm->card->dev, size, 310 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
317 &buf->addr, GFP_KERNEL); 311 &buf->addr, GFP_KERNEL);
318 312
319 DPRINTK("preallocate_dma_buffer: area=%p, addr=%p, size=%d\n", 313 pr_debug("davinci_pcm: preallocate_dma_buffer: area=%p, addr=%p, "
320 (void *) buf->area, (void *) buf->addr, size); 314 "size=%d\n", (void *) buf->area, (void *) buf->addr, size);
321 315
322 if (!buf->area) 316 if (!buf->area)
323 return -ENOMEM; 317 return -ENOMEM;
@@ -384,6 +378,18 @@ struct snd_soc_platform davinci_soc_platform = {
384}; 378};
385EXPORT_SYMBOL_GPL(davinci_soc_platform); 379EXPORT_SYMBOL_GPL(davinci_soc_platform);
386 380
381static int __init davinci_soc_platform_init(void)
382{
383 return snd_soc_register_platform(&davinci_soc_platform);
384}
385module_init(davinci_soc_platform_init);
386
387static void __exit davinci_soc_platform_exit(void)
388{
389 snd_soc_unregister_platform(&davinci_soc_platform);
390}
391module_exit(davinci_soc_platform_exit);
392
387MODULE_AUTHOR("Vladimir Barinov"); 393MODULE_AUTHOR("Vladimir Barinov");
388MODULE_DESCRIPTION("TI DAVINCI PCM DMA module"); 394MODULE_DESCRIPTION("TI DAVINCI PCM DMA module");
389MODULE_LICENSE("GPL"); 395MODULE_LICENSE("GPL");
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
new file mode 100644
index 000000000000..f67579d52765
--- /dev/null
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -0,0 +1,157 @@
1/*
2 * ASoC driver for Lyrtech SFFSDR board.
3 *
4 * Author: Hugo Villeneuve
5 * Copyright (C) 2008 Lyrtech inc
6 *
7 * Based on ASoC driver for TI DAVINCI EVM platform, original copyright follow:
8 * Copyright: (C) 2007 MontaVista Software, Inc., <source@mvista.com>
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/timer.h>
18#include <linux/interrupt.h>
19#include <linux/platform_device.h>
20#include <linux/gpio.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25
26#include <asm/dma.h>
27#include <asm/plat-sffsdr/sffsdr-fpga.h>
28
29#include <mach/mcbsp.h>
30#include <mach/edma.h>
31
32#include "../codecs/pcm3008.h"
33#include "davinci-pcm.h"
34#include "davinci-i2s.h"
35
36static int sffsdr_hw_params(struct snd_pcm_substream *substream,
37 struct snd_pcm_hw_params *params,
38 struct snd_soc_dai *dai)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
42 int fs;
43 int ret = 0;
44
45 /* Set cpu DAI configuration:
46 * CLKX and CLKR are the inputs for the Sample Rate Generator.
47 * FSX and FSR are outputs, driven by the sample Rate Generator. */
48 ret = snd_soc_dai_set_fmt(cpu_dai,
49 SND_SOC_DAIFMT_RIGHT_J |
50 SND_SOC_DAIFMT_CBM_CFS |
51 SND_SOC_DAIFMT_IB_NF);
52 if (ret < 0)
53 return ret;
54
55 /* Fsref can be 32000, 44100 or 48000. */
56 fs = params_rate(params);
57
58 pr_debug("sffsdr_hw_params: rate = %d Hz\n", fs);
59
60 return sffsdr_fpga_set_codec_fs(fs);
61}
62
63static struct snd_soc_ops sffsdr_ops = {
64 .hw_params = sffsdr_hw_params,
65};
66
67/* davinci-sffsdr digital audio interface glue - connects codec <--> CPU */
68static struct snd_soc_dai_link sffsdr_dai = {
69 .name = "PCM3008", /* Codec name */
70 .stream_name = "PCM3008 HiFi",
71 .cpu_dai = &davinci_i2s_dai,
72 .codec_dai = &pcm3008_dai,
73 .ops = &sffsdr_ops,
74};
75
76/* davinci-sffsdr audio machine driver */
77static struct snd_soc_card snd_soc_sffsdr = {
78 .name = "DaVinci SFFSDR",
79 .platform = &davinci_soc_platform,
80 .dai_link = &sffsdr_dai,
81 .num_links = 1,
82};
83
84/* sffsdr audio private data */
85static struct pcm3008_setup_data sffsdr_pcm3008_setup = {
86 .dem0_pin = GPIO(45),
87 .dem1_pin = GPIO(46),
88 .pdad_pin = GPIO(47),
89 .pdda_pin = GPIO(38),
90};
91
92/* sffsdr audio subsystem */
93static struct snd_soc_device sffsdr_snd_devdata = {
94 .card = &snd_soc_sffsdr,
95 .codec_dev = &soc_codec_dev_pcm3008,
96 .codec_data = &sffsdr_pcm3008_setup,
97};
98
99static struct resource sffsdr_snd_resources[] = {
100 {
101 .start = DAVINCI_MCBSP_BASE,
102 .end = DAVINCI_MCBSP_BASE + SZ_8K - 1,
103 .flags = IORESOURCE_MEM,
104 },
105};
106
107static struct evm_snd_platform_data sffsdr_snd_data = {
108 .tx_dma_ch = DAVINCI_DMA_MCBSP_TX,
109 .rx_dma_ch = DAVINCI_DMA_MCBSP_RX,
110};
111
112static struct platform_device *sffsdr_snd_device;
113
114static int __init sffsdr_init(void)
115{
116 int ret;
117
118 sffsdr_snd_device = platform_device_alloc("soc-audio", 0);
119 if (!sffsdr_snd_device) {
120 printk(KERN_ERR "platform device allocation failed\n");
121 return -ENOMEM;
122 }
123
124 platform_set_drvdata(sffsdr_snd_device, &sffsdr_snd_devdata);
125 sffsdr_snd_devdata.dev = &sffsdr_snd_device->dev;
126 sffsdr_snd_device->dev.platform_data = &sffsdr_snd_data;
127
128 ret = platform_device_add_resources(sffsdr_snd_device,
129 sffsdr_snd_resources,
130 ARRAY_SIZE(sffsdr_snd_resources));
131 if (ret) {
132 printk(KERN_ERR "platform device add ressources failed\n");
133 goto error;
134 }
135
136 ret = platform_device_add(sffsdr_snd_device);
137 if (ret)
138 goto error;
139
140 return ret;
141
142error:
143 platform_device_put(sffsdr_snd_device);
144 return ret;
145}
146
147static void __exit sffsdr_exit(void)
148{
149 platform_device_unregister(sffsdr_snd_device);
150}
151
152module_init(sffsdr_init);
153module_exit(sffsdr_exit);
154
155MODULE_AUTHOR("Hugo Villeneuve");
156MODULE_DESCRIPTION("Lyrtech SFFSDR ASoC driver");
157MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 8d73edc56102..95c12b26fe37 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -20,7 +20,7 @@ config SND_SOC_MPC8610_HPCD
20 20
21config SND_SOC_MPC5200_I2S 21config SND_SOC_MPC5200_I2S
22 tristate "Freescale MPC5200 PSC in I2S mode driver" 22 tristate "Freescale MPC5200 PSC in I2S mode driver"
23 depends on SND_SOC && PPC_MPC52xx && PPC_BESTCOMM 23 depends on PPC_MPC52xx && PPC_BESTCOMM
24 select SND_SOC_OF_SIMPLE 24 select SND_SOC_OF_SIMPLE
25 select PPC_BESTCOMM_GEN_BD 25 select PPC_BESTCOMM_GEN_BD
26 help 26 help
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index d2d3da9729f2..64993eda5679 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -284,7 +284,7 @@ static irqreturn_t fsl_dma_isr(int irq, void *dev_id)
284 * fsl_dma_new: initialize this PCM driver. 284 * fsl_dma_new: initialize this PCM driver.
285 * 285 *
286 * This function is called when the codec driver calls snd_soc_new_pcms(), 286 * This function is called when the codec driver calls snd_soc_new_pcms(),
287 * once for each .dai_link in the machine driver's snd_soc_machine 287 * once for each .dai_link in the machine driver's snd_soc_card
288 * structure. 288 * structure.
289 */ 289 */
290static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai, 290static int fsl_dma_new(struct snd_card *card, struct snd_soc_dai *dai,
@@ -853,6 +853,18 @@ int fsl_dma_configure(struct fsl_dma_info *dma_info)
853} 853}
854EXPORT_SYMBOL_GPL(fsl_dma_configure); 854EXPORT_SYMBOL_GPL(fsl_dma_configure);
855 855
856static int __init fsl_soc_platform_init(void)
857{
858 return snd_soc_register_platform(&fsl_soc_platform);
859}
860module_init(fsl_soc_platform_init);
861
862static void __exit fsl_soc_platform_exit(void)
863{
864 snd_soc_unregister_platform(&fsl_soc_platform);
865}
866module_exit(fsl_soc_platform_exit);
867
856MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 868MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
857MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM module"); 869MODULE_DESCRIPTION("Freescale Elo DMA ASoC PCM module");
858MODULE_LICENSE("GPL"); 870MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 157a7895ffa1..c6d6eb71dc1d 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -266,7 +266,8 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
266 * If this is the first stream open, then grab the IRQ and program most of 266 * If this is the first stream open, then grab the IRQ and program most of
267 * the SSI registers. 267 * the SSI registers.
268 */ 268 */
269static int fsl_ssi_startup(struct snd_pcm_substream *substream) 269static int fsl_ssi_startup(struct snd_pcm_substream *substream,
270 struct snd_soc_dai *dai)
270{ 271{
271 struct snd_soc_pcm_runtime *rtd = substream->private_data; 272 struct snd_soc_pcm_runtime *rtd = substream->private_data;
272 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 273 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -411,7 +412,8 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream)
411 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the 412 * Note: The SxCCR.DC and SxCCR.PM bits are only used if the SSI is the
412 * clock master. 413 * clock master.
413 */ 414 */
414static int fsl_ssi_prepare(struct snd_pcm_substream *substream) 415static int fsl_ssi_prepare(struct snd_pcm_substream *substream,
416 struct snd_soc_dai *dai)
415{ 417{
416 struct snd_pcm_runtime *runtime = substream->runtime; 418 struct snd_pcm_runtime *runtime = substream->runtime;
417 struct snd_soc_pcm_runtime *rtd = substream->private_data; 419 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -441,7 +443,8 @@ static int fsl_ssi_prepare(struct snd_pcm_substream *substream)
441 * The DMA channel is in external master start and pause mode, which 443 * The DMA channel is in external master start and pause mode, which
442 * means the SSI completely controls the flow of data. 444 * means the SSI completely controls the flow of data.
443 */ 445 */
444static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd) 446static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
447 struct snd_soc_dai *dai)
445{ 448{
446 struct snd_soc_pcm_runtime *rtd = substream->private_data; 449 struct snd_soc_pcm_runtime *rtd = substream->private_data;
447 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 450 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -490,7 +493,8 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd)
490 * 493 *
491 * Shutdown the SSI if there are no other substreams open. 494 * Shutdown the SSI if there are no other substreams open.
492 */ 495 */
493static void fsl_ssi_shutdown(struct snd_pcm_substream *substream) 496static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
497 struct snd_soc_dai *dai)
494{ 498{
495 struct snd_soc_pcm_runtime *rtd = substream->private_data; 499 struct snd_soc_pcm_runtime *rtd = substream->private_data;
496 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data; 500 struct fsl_ssi_private *ssi_private = rtd->dai->cpu_dai->private_data;
@@ -578,8 +582,6 @@ static struct snd_soc_dai fsl_ssi_dai_template = {
578 .prepare = fsl_ssi_prepare, 582 .prepare = fsl_ssi_prepare,
579 .shutdown = fsl_ssi_shutdown, 583 .shutdown = fsl_ssi_shutdown,
580 .trigger = fsl_ssi_trigger, 584 .trigger = fsl_ssi_trigger,
581 },
582 .dai_ops = {
583 .set_sysclk = fsl_ssi_set_sysclk, 585 .set_sysclk = fsl_ssi_set_sysclk,
584 .set_fmt = fsl_ssi_set_fmt, 586 .set_fmt = fsl_ssi_set_fmt,
585 }, 587 },
@@ -671,6 +673,14 @@ struct snd_soc_dai *fsl_ssi_create_dai(struct fsl_ssi_info *ssi_info)
671 fsl_ssi_dai->private_data = ssi_private; 673 fsl_ssi_dai->private_data = ssi_private;
672 fsl_ssi_dai->name = ssi_private->name; 674 fsl_ssi_dai->name = ssi_private->name;
673 fsl_ssi_dai->id = ssi_info->id; 675 fsl_ssi_dai->id = ssi_info->id;
676 fsl_ssi_dai->dev = ssi_info->dev;
677
678 ret = snd_soc_register_dai(fsl_ssi_dai);
679 if (ret != 0) {
680 dev_err(ssi_info->dev, "failed to register DAI: %d\n", ret);
681 kfree(fsl_ssi_dai);
682 return NULL;
683 }
674 684
675 return fsl_ssi_dai; 685 return fsl_ssi_dai;
676} 686}
@@ -688,6 +698,8 @@ void fsl_ssi_destroy_dai(struct snd_soc_dai *fsl_ssi_dai)
688 698
689 device_remove_file(ssi_private->dev, &ssi_private->dev_attr); 699 device_remove_file(ssi_private->dev, &ssi_private->dev_attr);
690 700
701 snd_soc_unregister_dai(&ssi_private->cpu_dai);
702
691 kfree(ssi_private); 703 kfree(ssi_private);
692} 704}
693EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai); 705EXPORT_SYMBOL_GPL(fsl_ssi_destroy_dai);
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index 94a02eaa4825..9eb1ce185bd0 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -187,7 +187,8 @@ static irqreturn_t psc_i2s_bcom_irq(int irq, void *_psc_i2s_stream)
187 * If this is the first stream open, then grab the IRQ and program most of 187 * If this is the first stream open, then grab the IRQ and program most of
188 * the PSC registers. 188 * the PSC registers.
189 */ 189 */
190static int psc_i2s_startup(struct snd_pcm_substream *substream) 190static int psc_i2s_startup(struct snd_pcm_substream *substream,
191 struct snd_soc_dai *dai)
191{ 192{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data; 193 struct snd_soc_pcm_runtime *rtd = substream->private_data;
193 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 194 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -220,7 +221,8 @@ static int psc_i2s_startup(struct snd_pcm_substream *substream)
220} 221}
221 222
222static int psc_i2s_hw_params(struct snd_pcm_substream *substream, 223static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
223 struct snd_pcm_hw_params *params) 224 struct snd_pcm_hw_params *params,
225 struct snd_soc_dai *dai)
224{ 226{
225 struct snd_soc_pcm_runtime *rtd = substream->private_data; 227 struct snd_soc_pcm_runtime *rtd = substream->private_data;
226 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 228 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -256,7 +258,8 @@ static int psc_i2s_hw_params(struct snd_pcm_substream *substream,
256 return 0; 258 return 0;
257} 259}
258 260
259static int psc_i2s_hw_free(struct snd_pcm_substream *substream) 261static int psc_i2s_hw_free(struct snd_pcm_substream *substream,
262 struct snd_soc_dai *dai)
260{ 263{
261 snd_pcm_set_runtime_buffer(substream, NULL); 264 snd_pcm_set_runtime_buffer(substream, NULL);
262 return 0; 265 return 0;
@@ -268,7 +271,8 @@ static int psc_i2s_hw_free(struct snd_pcm_substream *substream)
268 * This function is called by ALSA to start, stop, pause, and resume the DMA 271 * This function is called by ALSA to start, stop, pause, and resume the DMA
269 * transfer of data. 272 * transfer of data.
270 */ 273 */
271static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 274static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
275 struct snd_soc_dai *dai)
272{ 276{
273 struct snd_soc_pcm_runtime *rtd = substream->private_data; 277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
274 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 278 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -383,7 +387,8 @@ static int psc_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
383 * 387 *
384 * Shutdown the PSC if there are no other substreams open. 388 * Shutdown the PSC if there are no other substreams open.
385 */ 389 */
386static void psc_i2s_shutdown(struct snd_pcm_substream *substream) 390static void psc_i2s_shutdown(struct snd_pcm_substream *substream,
391 struct snd_soc_dai *dai)
387{ 392{
388 struct snd_soc_pcm_runtime *rtd = substream->private_data; 393 struct snd_soc_pcm_runtime *rtd = substream->private_data;
389 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data; 394 struct psc_i2s *psc_i2s = rtd->dai->cpu_dai->private_data;
@@ -464,7 +469,6 @@ static int psc_i2s_set_fmt(struct snd_soc_dai *cpu_dai, unsigned int format)
464 * psc_i2s_dai_template: template CPU Digital Audio Interface 469 * psc_i2s_dai_template: template CPU Digital Audio Interface
465 */ 470 */
466static struct snd_soc_dai psc_i2s_dai_template = { 471static struct snd_soc_dai psc_i2s_dai_template = {
467 .type = SND_SOC_DAI_I2S,
468 .playback = { 472 .playback = {
469 .channels_min = 2, 473 .channels_min = 2,
470 .channels_max = 2, 474 .channels_max = 2,
@@ -483,8 +487,6 @@ static struct snd_soc_dai psc_i2s_dai_template = {
483 .hw_free = psc_i2s_hw_free, 487 .hw_free = psc_i2s_hw_free,
484 .shutdown = psc_i2s_shutdown, 488 .shutdown = psc_i2s_shutdown,
485 .trigger = psc_i2s_trigger, 489 .trigger = psc_i2s_trigger,
486 },
487 .dai_ops = {
488 .set_sysclk = psc_i2s_set_sysclk, 490 .set_sysclk = psc_i2s_set_sysclk,
489 .set_fmt = psc_i2s_set_fmt, 491 .set_fmt = psc_i2s_set_fmt,
490 }, 492 },
@@ -826,6 +828,8 @@ static int __devinit psc_i2s_of_probe(struct of_device *op,
826 if (rc) 828 if (rc)
827 dev_info(psc_i2s->dev, "error creating sysfs files\n"); 829 dev_info(psc_i2s->dev, "error creating sysfs files\n");
828 830
831 snd_soc_register_platform(&psc_i2s_pcm_soc_platform);
832
829 /* Tell the ASoC OF helpers about it */ 833 /* Tell the ASoC OF helpers about it */
830 of_snd_soc_register_platform(&psc_i2s_pcm_soc_platform, op->node, 834 of_snd_soc_register_platform(&psc_i2s_pcm_soc_platform, op->node,
831 &psc_i2s->dai); 835 &psc_i2s->dai);
@@ -839,6 +843,8 @@ static int __devexit psc_i2s_of_remove(struct of_device *op)
839 843
840 dev_dbg(&op->dev, "psc_i2s_remove()\n"); 844 dev_dbg(&op->dev, "psc_i2s_remove()\n");
841 845
846 snd_soc_unregister_platform(&psc_i2s_pcm_soc_platform);
847
842 bcom_gen_bd_rx_release(psc_i2s->capture.bcom_task); 848 bcom_gen_bd_rx_release(psc_i2s->capture.bcom_task);
843 bcom_gen_bd_tx_release(psc_i2s->playback.bcom_task); 849 bcom_gen_bd_tx_release(psc_i2s->playback.bcom_task);
844 850
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c
index 94f89debde1f..bcec3f60bad9 100644
--- a/sound/soc/fsl/mpc8610_hpcd.c
+++ b/sound/soc/fsl/mpc8610_hpcd.c
@@ -29,7 +29,7 @@
29struct mpc8610_hpcd_data { 29struct mpc8610_hpcd_data {
30 struct snd_soc_device sound_devdata; 30 struct snd_soc_device sound_devdata;
31 struct snd_soc_dai_link dai; 31 struct snd_soc_dai_link dai;
32 struct snd_soc_machine machine; 32 struct snd_soc_card machine;
33 unsigned int dai_format; 33 unsigned int dai_format;
34 unsigned int codec_clk_direction; 34 unsigned int codec_clk_direction;
35 unsigned int cpu_clk_direction; 35 unsigned int cpu_clk_direction;
@@ -185,7 +185,7 @@ static struct snd_soc_ops mpc8610_hpcd_ops = {
185/** 185/**
186 * mpc8610_hpcd_machine: ASoC machine data 186 * mpc8610_hpcd_machine: ASoC machine data
187 */ 187 */
188static struct snd_soc_machine mpc8610_hpcd_machine = { 188static struct snd_soc_card mpc8610_hpcd_machine = {
189 .probe = mpc8610_hpcd_machine_probe, 189 .probe = mpc8610_hpcd_machine_probe,
190 .remove = mpc8610_hpcd_machine_remove, 190 .remove = mpc8610_hpcd_machine_remove,
191 .name = "MPC8610 HPCD", 191 .name = "MPC8610 HPCD",
@@ -465,9 +465,9 @@ static int mpc8610_hpcd_probe(struct of_device *ofdev,
465 goto error; 465 goto error;
466 } 466 }
467 467
468 machine_data->sound_devdata.machine = &mpc8610_hpcd_machine; 468 machine_data->sound_devdata.card = &mpc8610_hpcd_machine;
469 machine_data->sound_devdata.codec_dev = &soc_codec_device_cs4270; 469 machine_data->sound_devdata.codec_dev = &soc_codec_device_cs4270;
470 machine_data->sound_devdata.platform = &fsl_soc_platform; 470 machine_data->machine.platform = &fsl_soc_platform;
471 471
472 sound_device->dev.platform_data = machine_data; 472 sound_device->dev.platform_data = machine_data;
473 473
diff --git a/sound/soc/fsl/soc-of-simple.c b/sound/soc/fsl/soc-of-simple.c
index 0382fdac51cd..8bc5cd9e972f 100644
--- a/sound/soc/fsl/soc-of-simple.c
+++ b/sound/soc/fsl/soc-of-simple.c
@@ -31,7 +31,7 @@ struct of_snd_soc_device {
31 int id; 31 int id;
32 struct list_head list; 32 struct list_head list;
33 struct snd_soc_device device; 33 struct snd_soc_device device;
34 struct snd_soc_machine machine; 34 struct snd_soc_card card;
35 struct snd_soc_dai_link dai_link; 35 struct snd_soc_dai_link dai_link;
36 struct platform_device *pdev; 36 struct platform_device *pdev;
37 struct device_node *platform_node; 37 struct device_node *platform_node;
@@ -58,9 +58,9 @@ of_snd_soc_get_device(struct device_node *codec_node)
58 /* Initialize the structure and add it to the global list */ 58 /* Initialize the structure and add it to the global list */
59 of_soc->codec_node = codec_node; 59 of_soc->codec_node = codec_node;
60 of_soc->id = of_snd_soc_next_index++; 60 of_soc->id = of_snd_soc_next_index++;
61 of_soc->machine.dai_link = &of_soc->dai_link; 61 of_soc->card.dai_link = &of_soc->dai_link;
62 of_soc->machine.num_links = 1; 62 of_soc->card.num_links = 1;
63 of_soc->device.machine = &of_soc->machine; 63 of_soc->device.card = &of_soc->card;
64 of_soc->dai_link.ops = &of_snd_soc_ops; 64 of_soc->dai_link.ops = &of_snd_soc_ops;
65 list_add(&of_soc->list, &of_snd_soc_device_list); 65 list_add(&of_soc->list, &of_snd_soc_device_list);
66 66
@@ -158,8 +158,8 @@ int of_snd_soc_register_platform(struct snd_soc_platform *platform,
158 158
159 of_soc->platform_node = node; 159 of_soc->platform_node = node;
160 of_soc->dai_link.cpu_dai = cpu_dai; 160 of_soc->dai_link.cpu_dai = cpu_dai;
161 of_soc->device.platform = platform; 161 of_soc->card.platform = platform;
162 of_soc->machine.name = of_soc->dai_link.cpu_dai->name; 162 of_soc->card.name = of_soc->dai_link.cpu_dai->name;
163 163
164 /* Now try to register the SoC device */ 164 /* Now try to register the SoC device */
165 of_snd_soc_register_device(of_soc); 165 of_snd_soc_register_device(of_soc);
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig
index 8b7766b998d7..a7b1d77b2105 100644
--- a/sound/soc/omap/Kconfig
+++ b/sound/soc/omap/Kconfig
@@ -1,6 +1,6 @@
1config SND_OMAP_SOC 1config SND_OMAP_SOC
2 tristate "SoC Audio for the Texas Instruments OMAP chips" 2 tristate "SoC Audio for the Texas Instruments OMAP chips"
3 depends on ARCH_OMAP && SND_SOC 3 depends on ARCH_OMAP
4 4
5config SND_OMAP_SOC_MCBSP 5config SND_OMAP_SOC_MCBSP
6 tristate 6 tristate
@@ -21,3 +21,36 @@ config SND_OMAP_SOC_OSK5912
21 select SND_SOC_TLV320AIC23 21 select SND_SOC_TLV320AIC23
22 help 22 help
23 Say Y if you want to add support for SoC audio on osk5912. 23 Say Y if you want to add support for SoC audio on osk5912.
24
25config SND_OMAP_SOC_OVERO
26 tristate "SoC Audio support for Gumstix Overo"
27 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OVERO
28 select SND_OMAP_SOC_MCBSP
29 select SND_SOC_TWL4030
30 help
31 Say Y if you want to add support for SoC audio on the Gumstix Overo.
32
33config SND_OMAP_SOC_OMAP2EVM
34 tristate "SoC Audio support for OMAP2EVM board"
35 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP2EVM
36 select SND_OMAP_SOC_MCBSP
37 select SND_SOC_TWL4030
38 help
39 Say Y if you want to add support for SoC audio on the omap2evm board.
40
41config SND_OMAP_SOC_SDP3430
42 tristate "SoC Audio support for Texas Instruments SDP3430"
43 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP_3430SDP
44 select SND_OMAP_SOC_MCBSP
45 select SND_SOC_TWL4030
46 help
47 Say Y if you want to add support for SoC audio on Texas Instruments
48 SDP3430.
49
50config SND_OMAP_SOC_OMAP3_PANDORA
51 tristate "SoC Audio support for OMAP3 Pandora"
52 depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3_PANDORA
53 select SND_OMAP_SOC_MCBSP
54 select SND_SOC_TWL4030
55 help
56 Say Y if you want to add support for SoC audio on the OMAP3 Pandora.
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile
index e09d1f297f64..76fedd96e365 100644
--- a/sound/soc/omap/Makefile
+++ b/sound/soc/omap/Makefile
@@ -8,6 +8,14 @@ obj-$(CONFIG_SND_OMAP_SOC_MCBSP) += snd-soc-omap-mcbsp.o
8# OMAP Machine Support 8# OMAP Machine Support
9snd-soc-n810-objs := n810.o 9snd-soc-n810-objs := n810.o
10snd-soc-osk5912-objs := osk5912.o 10snd-soc-osk5912-objs := osk5912.o
11snd-soc-overo-objs := overo.o
12snd-soc-omap2evm-objs := omap2evm.o
13snd-soc-sdp3430-objs := sdp3430.o
14snd-soc-omap3pandora-objs := omap3pandora.o
11 15
12obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o 16obj-$(CONFIG_SND_OMAP_SOC_N810) += snd-soc-n810.o
13obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o 17obj-$(CONFIG_SND_OMAP_SOC_OSK5912) += snd-soc-osk5912.o
18obj-$(CONFIG_SND_OMAP_SOC_OVERO) += snd-soc-overo.o
19obj-$(CONFIG_MACH_OMAP2EVM) += snd-soc-omap2evm.o
20obj-$(CONFIG_SND_OMAP_SOC_SDP3430) += snd-soc-sdp3430.o
21obj-$(CONFIG_SND_OMAP_SOC_OMAP3_PANDORA) += snd-soc-omap3pandora.o
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index fae3ad36e0bf..25593fee9121 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -70,9 +70,13 @@ static void n810_ext_control(struct snd_soc_codec *codec)
70 70
71static int n810_startup(struct snd_pcm_substream *substream) 71static int n810_startup(struct snd_pcm_substream *substream)
72{ 72{
73 struct snd_pcm_runtime *runtime = substream->runtime;
73 struct snd_soc_pcm_runtime *rtd = substream->private_data; 74 struct snd_soc_pcm_runtime *rtd = substream->private_data;
74 struct snd_soc_codec *codec = rtd->socdev->codec; 75 struct snd_soc_codec *codec = rtd->socdev->codec;
75 76
77 snd_pcm_hw_constraint_minmax(runtime,
78 SNDRV_PCM_HW_PARAM_CHANNELS, 2, 2);
79
76 n810_ext_control(codec); 80 n810_ext_control(codec);
77 return clk_enable(sys_clkout2); 81 return clk_enable(sys_clkout2);
78} 82}
@@ -282,8 +286,9 @@ static struct snd_soc_dai_link n810_dai = {
282}; 286};
283 287
284/* Audio machine driver */ 288/* Audio machine driver */
285static struct snd_soc_machine snd_soc_machine_n810 = { 289static struct snd_soc_card snd_soc_n810 = {
286 .name = "N810", 290 .name = "N810",
291 .platform = &omap_soc_platform,
287 .dai_link = &n810_dai, 292 .dai_link = &n810_dai,
288 .num_links = 1, 293 .num_links = 1,
289}; 294};
@@ -298,8 +303,7 @@ static struct aic3x_setup_data n810_aic33_setup = {
298 303
299/* Audio subsystem */ 304/* Audio subsystem */
300static struct snd_soc_device n810_snd_devdata = { 305static struct snd_soc_device n810_snd_devdata = {
301 .machine = &snd_soc_machine_n810, 306 .card = &snd_soc_n810,
302 .platform = &omap_soc_platform,
303 .codec_dev = &soc_codec_dev_aic3x, 307 .codec_dev = &soc_codec_dev_aic3x,
304 .codec_data = &n810_aic33_setup, 308 .codec_data = &n810_aic33_setup,
305}; 309};
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 8485a8a9d0ff..ec5e18a78758 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -36,9 +36,7 @@
36#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
37#include "omap-pcm.h" 37#include "omap-pcm.h"
38 38
39#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_44100 | \ 39#define OMAP_MCBSP_RATES (SNDRV_PCM_RATE_8000_96000)
40 SNDRV_PCM_RATE_48000 | \
41 SNDRV_PCM_RATE_KNOT)
42 40
43struct omap_mcbsp_data { 41struct omap_mcbsp_data {
44 unsigned int bus_id; 42 unsigned int bus_id;
@@ -140,7 +138,8 @@ static const unsigned long omap34xx_mcbsp_port[][2] = {
140static const unsigned long omap34xx_mcbsp_port[][2] = {}; 138static const unsigned long omap34xx_mcbsp_port[][2] = {};
141#endif 139#endif
142 140
143static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream) 141static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
142 struct snd_soc_dai *dai)
144{ 143{
145 struct snd_soc_pcm_runtime *rtd = substream->private_data; 144 struct snd_soc_pcm_runtime *rtd = substream->private_data;
146 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 145 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -153,7 +152,8 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream)
153 return err; 152 return err;
154} 153}
155 154
156static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream) 155static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream,
156 struct snd_soc_dai *dai)
157{ 157{
158 struct snd_soc_pcm_runtime *rtd = substream->private_data; 158 struct snd_soc_pcm_runtime *rtd = substream->private_data;
159 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 159 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -165,7 +165,8 @@ static void omap_mcbsp_dai_shutdown(struct snd_pcm_substream *substream)
165 } 165 }
166} 166}
167 167
168static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd) 168static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd,
169 struct snd_soc_dai *dai)
169{ 170{
170 struct snd_soc_pcm_runtime *rtd = substream->private_data; 171 struct snd_soc_pcm_runtime *rtd = substream->private_data;
171 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 172 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -194,14 +195,15 @@ static int omap_mcbsp_dai_trigger(struct snd_pcm_substream *substream, int cmd)
194} 195}
195 196
196static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, 197static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
197 struct snd_pcm_hw_params *params) 198 struct snd_pcm_hw_params *params,
199 struct snd_soc_dai *dai)
198{ 200{
199 struct snd_soc_pcm_runtime *rtd = substream->private_data; 201 struct snd_soc_pcm_runtime *rtd = substream->private_data;
200 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 202 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
201 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data); 203 struct omap_mcbsp_data *mcbsp_data = to_mcbsp(cpu_dai->private_data);
202 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs; 204 struct omap_mcbsp_reg_cfg *regs = &mcbsp_data->regs;
203 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id; 205 int dma, bus_id = mcbsp_data->bus_id, id = cpu_dai->id;
204 int wlen; 206 int wlen, channels;
205 unsigned long port; 207 unsigned long port;
206 208
207 if (cpu_class_is_omap1()) { 209 if (cpu_class_is_omap1()) {
@@ -230,12 +232,17 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
230 return 0; 232 return 0;
231 } 233 }
232 234
233 switch (params_channels(params)) { 235 channels = params_channels(params);
236 switch (channels) {
234 case 2: 237 case 2:
235 /* Set 1 word per (McBPSP) frame and use dual-phase frames */ 238 /* Use dual-phase frames */
236 regs->rcr2 |= RFRLEN2(1 - 1) | RPHASE; 239 regs->rcr2 |= RPHASE;
240 regs->xcr2 |= XPHASE;
241 case 1:
242 /* Set 1 word per (McBSP) frame */
243 regs->rcr2 |= RFRLEN2(1 - 1);
237 regs->rcr1 |= RFRLEN1(1 - 1); 244 regs->rcr1 |= RFRLEN1(1 - 1);
238 regs->xcr2 |= XFRLEN2(1 - 1) | XPHASE; 245 regs->xcr2 |= XFRLEN2(1 - 1);
239 regs->xcr1 |= XFRLEN1(1 - 1); 246 regs->xcr1 |= XFRLEN1(1 - 1);
240 break; 247 break;
241 default: 248 default:
@@ -263,9 +270,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
263 regs->srgr2 |= FPER(wlen * 2 - 1); 270 regs->srgr2 |= FPER(wlen * 2 - 1);
264 regs->srgr1 |= FWID(wlen - 1); 271 regs->srgr1 |= FWID(wlen - 1);
265 break; 272 break;
266 case SND_SOC_DAIFMT_DSP_A: 273 case SND_SOC_DAIFMT_DSP_B:
267 regs->srgr2 |= FPER(wlen * 2 - 1); 274 regs->srgr2 |= FPER(wlen * channels - 1);
268 regs->srgr1 |= FWID(wlen * 2 - 2); 275 regs->srgr1 |= FWID(wlen * channels - 2);
269 break; 276 break;
270 } 277 }
271 278
@@ -302,7 +309,7 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
302 regs->rcr2 |= RDATDLY(1); 309 regs->rcr2 |= RDATDLY(1);
303 regs->xcr2 |= XDATDLY(1); 310 regs->xcr2 |= XDATDLY(1);
304 break; 311 break;
305 case SND_SOC_DAIFMT_DSP_A: 312 case SND_SOC_DAIFMT_DSP_B:
306 /* 0-bit data delay */ 313 /* 0-bit data delay */
307 regs->rcr2 |= RDATDLY(0); 314 regs->rcr2 |= RDATDLY(0);
308 regs->xcr2 |= XDATDLY(0); 315 regs->xcr2 |= XDATDLY(0);
@@ -452,17 +459,16 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
452 459
453#define OMAP_MCBSP_DAI_BUILDER(link_id) \ 460#define OMAP_MCBSP_DAI_BUILDER(link_id) \
454{ \ 461{ \
455 .name = "omap-mcbsp-dai-(link_id)", \ 462 .name = "omap-mcbsp-dai-"#link_id, \
456 .id = (link_id), \ 463 .id = (link_id), \
457 .type = SND_SOC_DAI_I2S, \
458 .playback = { \ 464 .playback = { \
459 .channels_min = 2, \ 465 .channels_min = 1, \
460 .channels_max = 2, \ 466 .channels_max = 2, \
461 .rates = OMAP_MCBSP_RATES, \ 467 .rates = OMAP_MCBSP_RATES, \
462 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 468 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
463 }, \ 469 }, \
464 .capture = { \ 470 .capture = { \
465 .channels_min = 2, \ 471 .channels_min = 1, \
466 .channels_max = 2, \ 472 .channels_max = 2, \
467 .rates = OMAP_MCBSP_RATES, \ 473 .rates = OMAP_MCBSP_RATES, \
468 .formats = SNDRV_PCM_FMTBIT_S16_LE, \ 474 .formats = SNDRV_PCM_FMTBIT_S16_LE, \
@@ -472,8 +478,6 @@ static int omap_mcbsp_dai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
472 .shutdown = omap_mcbsp_dai_shutdown, \ 478 .shutdown = omap_mcbsp_dai_shutdown, \
473 .trigger = omap_mcbsp_dai_trigger, \ 479 .trigger = omap_mcbsp_dai_trigger, \
474 .hw_params = omap_mcbsp_dai_hw_params, \ 480 .hw_params = omap_mcbsp_dai_hw_params, \
475 }, \
476 .dai_ops = { \
477 .set_fmt = omap_mcbsp_dai_set_dai_fmt, \ 481 .set_fmt = omap_mcbsp_dai_set_dai_fmt, \
478 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \ 482 .set_clkdiv = omap_mcbsp_dai_set_clkdiv, \
479 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \ 483 .set_sysclk = omap_mcbsp_dai_set_dai_sysclk, \
@@ -495,6 +499,19 @@ struct snd_soc_dai omap_mcbsp_dai[] = {
495 499
496EXPORT_SYMBOL_GPL(omap_mcbsp_dai); 500EXPORT_SYMBOL_GPL(omap_mcbsp_dai);
497 501
502static int __init snd_omap_mcbsp_init(void)
503{
504 return snd_soc_register_dais(omap_mcbsp_dai,
505 ARRAY_SIZE(omap_mcbsp_dai));
506}
507module_init(snd_omap_mcbsp_init);
508
509static void __exit snd_omap_mcbsp_exit(void)
510{
511 snd_soc_unregister_dais(omap_mcbsp_dai, ARRAY_SIZE(omap_mcbsp_dai));
512}
513module_exit(snd_omap_mcbsp_exit);
514
498MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); 515MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
499MODULE_DESCRIPTION("OMAP I2S SoC Interface"); 516MODULE_DESCRIPTION("OMAP I2S SoC Interface");
500MODULE_LICENSE("GPL"); 517MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c
index e9084fdd2082..b0362dfd5b71 100644
--- a/sound/soc/omap/omap-pcm.c
+++ b/sound/soc/omap/omap-pcm.c
@@ -97,7 +97,7 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
97 prtd->dma_data = dma_data; 97 prtd->dma_data = dma_data;
98 err = omap_request_dma(dma_data->dma_req, dma_data->name, 98 err = omap_request_dma(dma_data->dma_req, dma_data->name,
99 omap_pcm_dma_irq, substream, &prtd->dma_ch); 99 omap_pcm_dma_irq, substream, &prtd->dma_ch);
100 if (!err & !cpu_is_omap1510()) { 100 if (!err && !cpu_is_omap1510()) {
101 /* 101 /*
102 * Link channel with itself so DMA doesn't need any 102 * Link channel with itself so DMA doesn't need any
103 * reprogramming while looping the buffer 103 * reprogramming while looping the buffer
@@ -233,7 +233,7 @@ static int omap_pcm_open(struct snd_pcm_substream *substream)
233 if (ret < 0) 233 if (ret < 0)
234 goto out; 234 goto out;
235 235
236 prtd = kzalloc(sizeof(prtd), GFP_KERNEL); 236 prtd = kzalloc(sizeof(*prtd), GFP_KERNEL);
237 if (prtd == NULL) { 237 if (prtd == NULL) {
238 ret = -ENOMEM; 238 ret = -ENOMEM;
239 goto out; 239 goto out;
@@ -354,6 +354,18 @@ struct snd_soc_platform omap_soc_platform = {
354}; 354};
355EXPORT_SYMBOL_GPL(omap_soc_platform); 355EXPORT_SYMBOL_GPL(omap_soc_platform);
356 356
357static int __init omap_soc_platform_init(void)
358{
359 return snd_soc_register_platform(&omap_soc_platform);
360}
361module_init(omap_soc_platform_init);
362
363static void __exit omap_soc_platform_exit(void)
364{
365 snd_soc_unregister_platform(&omap_soc_platform);
366}
367module_exit(omap_soc_platform_exit);
368
357MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>"); 369MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@nokia.com>");
358MODULE_DESCRIPTION("OMAP PCM DMA module"); 370MODULE_DESCRIPTION("OMAP PCM DMA module");
359MODULE_LICENSE("GPL"); 371MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
new file mode 100644
index 000000000000..0c2322dcf02a
--- /dev/null
+++ b/sound/soc/omap/omap2evm.c
@@ -0,0 +1,151 @@
1/*
2 * omap2evm.c -- SoC audio machine driver for omap2evm board
3 *
4 * Author: Arun KS <arunks@mistralsolutions.com>
5 *
6 * Based on sound/soc/omap/overo.c by Steve Sakoman
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#include <linux/clk.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30
31#include <asm/mach-types.h>
32#include <mach/hardware.h>
33#include <mach/gpio.h>
34#include <mach/mcbsp.h>
35
36#include "omap-mcbsp.h"
37#include "omap-pcm.h"
38#include "../codecs/twl4030.h"
39
40static int omap2evm_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params,
42 struct snd_soc_dai *dai)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
46 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
47 int ret;
48
49 /* Set codec DAI configuration */
50 ret = snd_soc_dai_set_fmt(codec_dai,
51 SND_SOC_DAIFMT_I2S |
52 SND_SOC_DAIFMT_NB_NF |
53 SND_SOC_DAIFMT_CBM_CFM);
54 if (ret < 0) {
55 printk(KERN_ERR "can't set codec DAI configuration\n");
56 return ret;
57 }
58
59 /* Set cpu DAI configuration */
60 ret = snd_soc_dai_set_fmt(cpu_dai,
61 SND_SOC_DAIFMT_I2S |
62 SND_SOC_DAIFMT_NB_NF |
63 SND_SOC_DAIFMT_CBM_CFM);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set cpu DAI configuration\n");
66 return ret;
67 }
68
69 /* Set the codec system clock for DAC and ADC */
70 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
71 SND_SOC_CLOCK_IN);
72 if (ret < 0) {
73 printk(KERN_ERR "can't set codec system clock\n");
74 return ret;
75 }
76
77 return 0;
78}
79
80static struct snd_soc_ops omap2evm_ops = {
81 .hw_params = omap2evm_hw_params,
82};
83
84/* Digital audio interface glue - connects codec <--> CPU */
85static struct snd_soc_dai_link omap2evm_dai = {
86 .name = "TWL4030",
87 .stream_name = "TWL4030",
88 .cpu_dai = &omap_mcbsp_dai[0],
89 .codec_dai = &twl4030_dai,
90 .ops = &omap2evm_ops,
91};
92
93/* Audio machine driver */
94static struct snd_soc_card snd_soc_omap2evm = {
95 .name = "omap2evm",
96 .platform = &omap_soc_platform,
97 .dai_link = &omap2evm_dai,
98 .num_links = 1,
99};
100
101/* Audio subsystem */
102static struct snd_soc_device omap2evm_snd_devdata = {
103 .card = &snd_soc_omap2evm,
104 .codec_dev = &soc_codec_dev_twl4030,
105};
106
107static struct platform_device *omap2evm_snd_device;
108
109static int __init omap2evm_soc_init(void)
110{
111 int ret;
112
113 if (!machine_is_omap2evm()) {
114 pr_debug("Not omap2evm!\n");
115 return -ENODEV;
116 }
117 printk(KERN_INFO "omap2evm SoC init\n");
118
119 omap2evm_snd_device = platform_device_alloc("soc-audio", -1);
120 if (!omap2evm_snd_device) {
121 printk(KERN_ERR "Platform device allocation failed\n");
122 return -ENOMEM;
123 }
124
125 platform_set_drvdata(omap2evm_snd_device, &omap2evm_snd_devdata);
126 omap2evm_snd_devdata.dev = &omap2evm_snd_device->dev;
127 *(unsigned int *)omap2evm_dai.cpu_dai->private_data = 1; /* McBSP2 */
128
129 ret = platform_device_add(omap2evm_snd_device);
130 if (ret)
131 goto err1;
132
133 return 0;
134
135err1:
136 printk(KERN_ERR "Unable to add platform device\n");
137 platform_device_put(omap2evm_snd_device);
138
139 return ret;
140}
141module_init(omap2evm_soc_init);
142
143static void __exit omap2evm_soc_exit(void)
144{
145 platform_device_unregister(omap2evm_snd_device);
146}
147module_exit(omap2evm_soc_exit);
148
149MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>");
150MODULE_DESCRIPTION("ALSA SoC omap2evm");
151MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
new file mode 100644
index 000000000000..fd24a4acd2f5
--- /dev/null
+++ b/sound/soc/omap/omap3beagle.c
@@ -0,0 +1,149 @@
1/*
2 * omap3beagle.c -- SoC audio for OMAP3 Beagle
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
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 <mach/mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38static int omap3beagle_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 omap3beagle_ops = {
78 .hw_params = omap3beagle_hw_params,
79};
80
81/* Digital audio interface glue - connects codec <--> CPU */
82static struct snd_soc_dai_link omap3beagle_dai = {
83 .name = "TWL4030",
84 .stream_name = "TWL4030",
85 .cpu_dai = &omap_mcbsp_dai[0],
86 .codec_dai = &twl4030_dai,
87 .ops = &omap3beagle_ops,
88};
89
90/* Audio machine driver */
91static struct snd_soc_card snd_soc_omap3beagle = {
92 .name = "omap3beagle",
93 .platform = &omap_soc_platform,
94 .dai_link = &omap3beagle_dai,
95 .num_links = 1,
96};
97
98/* Audio subsystem */
99static struct snd_soc_device omap3beagle_snd_devdata = {
100 .card = &snd_soc_omap3beagle,
101 .codec_dev = &soc_codec_dev_twl4030,
102};
103
104static struct platform_device *omap3beagle_snd_device;
105
106static int __init omap3beagle_soc_init(void)
107{
108 int ret;
109
110 if (!machine_is_omap3_beagle()) {
111 pr_debug("Not OMAP3 Beagle!\n");
112 return -ENODEV;
113 }
114 pr_info("OMAP3 Beagle SoC init\n");
115
116 omap3beagle_snd_device = platform_device_alloc("soc-audio", -1);
117 if (!omap3beagle_snd_device) {
118 printk(KERN_ERR "Platform device allocation failed\n");
119 return -ENOMEM;
120 }
121
122 platform_set_drvdata(omap3beagle_snd_device, &omap3beagle_snd_devdata);
123 omap3beagle_snd_devdata.dev = &omap3beagle_snd_device->dev;
124 *(unsigned int *)omap3beagle_dai.cpu_dai->private_data = 1; /* McBSP2 */
125
126 ret = platform_device_add(omap3beagle_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(omap3beagle_snd_device);
135
136 return ret;
137}
138
139static void __exit omap3beagle_soc_exit(void)
140{
141 platform_device_unregister(omap3beagle_snd_device);
142}
143
144module_init(omap3beagle_soc_init);
145module_exit(omap3beagle_soc_exit);
146
147MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
148MODULE_DESCRIPTION("ALSA SoC OMAP3 Beagle");
149MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
new file mode 100644
index 000000000000..bd91594496b1
--- /dev/null
+++ b/sound/soc/omap/omap3pandora.c
@@ -0,0 +1,311 @@
1/*
2 * omap3pandora.c -- SoC audio for Pandora Handheld Console
3 *
4 * Author: Gražvydas Ignotas <notasas@gmail.com>
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 <linux/gpio.h>
25#include <linux/delay.h>
26
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31
32#include <asm/mach-types.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38#define OMAP3_PANDORA_DAC_POWER_GPIO 118
39#define OMAP3_PANDORA_AMP_POWER_GPIO 14
40
41#define PREFIX "ASoC omap3pandora: "
42
43static int omap3pandora_cmn_hw_params(struct snd_soc_dai *codec_dai,
44 struct snd_soc_dai *cpu_dai, unsigned int fmt)
45{
46 int ret;
47
48 /* Set codec DAI configuration */
49 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
50 if (ret < 0) {
51 pr_err(PREFIX "can't set codec DAI configuration\n");
52 return ret;
53 }
54
55 /* Set cpu DAI configuration */
56 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
57 if (ret < 0) {
58 pr_err(PREFIX "can't set cpu DAI configuration\n");
59 return ret;
60 }
61
62 /* Set the codec system clock for DAC and ADC */
63 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
64 SND_SOC_CLOCK_IN);
65 if (ret < 0) {
66 pr_err(PREFIX "can't set codec system clock\n");
67 return ret;
68 }
69
70 /* Set McBSP clock to external */
71 ret = snd_soc_dai_set_sysclk(cpu_dai, OMAP_MCBSP_SYSCLK_CLKS_EXT, 0,
72 SND_SOC_CLOCK_IN);
73 if (ret < 0) {
74 pr_err(PREFIX "can't set cpu system clock\n");
75 return ret;
76 }
77
78 ret = snd_soc_dai_set_clkdiv(cpu_dai, OMAP_MCBSP_CLKGDV, 8);
79 if (ret < 0) {
80 pr_err(PREFIX "can't set SRG clock divider\n");
81 return ret;
82 }
83
84 return 0;
85}
86
87static int omap3pandora_out_hw_params(struct snd_pcm_substream *substream,
88 struct snd_pcm_hw_params *params)
89{
90 struct snd_soc_pcm_runtime *rtd = substream->private_data;
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 |
96 SND_SOC_DAIFMT_IB_NF |
97 SND_SOC_DAIFMT_CBS_CFS);
98}
99
100static int omap3pandora_in_hw_params(struct snd_pcm_substream *substream,
101 struct snd_pcm_hw_params *params)
102{
103 struct snd_soc_pcm_runtime *rtd = substream->private_data;
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 |
109 SND_SOC_DAIFMT_NB_NF |
110 SND_SOC_DAIFMT_CBS_CFS);
111}
112
113static int omap3pandora_hp_event(struct snd_soc_dapm_widget *w,
114 struct snd_kcontrol *k, int event)
115{
116 if (SND_SOC_DAPM_EVENT_ON(event)) {
117 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 1);
118 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 1);
119 } else {
120 gpio_set_value(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
121 mdelay(1);
122 gpio_set_value(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
123 }
124
125 return 0;
126}
127
128/*
129 * Audio paths on Pandora board:
130 *
131 * |O| ---> PCM DAC +-> AMP -> Headphone Jack
132 * |M| A +--------> Line Out
133 * |A| <~~clk~~+
134 * |P| <--- TWL4030 <--------- Line In and MICs
135 */
136static const struct snd_soc_dapm_widget omap3pandora_out_dapm_widgets[] = {
137 SND_SOC_DAPM_DAC("PCM DAC", "Playback", SND_SOC_NOPM, 0, 0),
138 SND_SOC_DAPM_PGA_E("Headphone Amplifier", SND_SOC_NOPM,
139 0, 0, NULL, 0, omap3pandora_hp_event,
140 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
141 SND_SOC_DAPM_HP("Headphone Jack", NULL),
142 SND_SOC_DAPM_LINE("Line Out", NULL),
143};
144
145static const struct snd_soc_dapm_widget omap3pandora_in_dapm_widgets[] = {
146 SND_SOC_DAPM_MIC("Mic (Internal)", NULL),
147 SND_SOC_DAPM_MIC("Mic (external)", NULL),
148 SND_SOC_DAPM_LINE("Line In", NULL),
149};
150
151static const struct snd_soc_dapm_route omap3pandora_out_map[] = {
152 {"Headphone Amplifier", NULL, "PCM DAC"},
153 {"Line Out", NULL, "PCM DAC"},
154 {"Headphone Jack", NULL, "Headphone Amplifier"},
155};
156
157static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
158 {"INL", NULL, "Line In"},
159 {"INR", NULL, "Line In"},
160 {"INL", NULL, "Mic (Internal)"},
161 {"INR", NULL, "Mic (external)"},
162};
163
164static int omap3pandora_out_init(struct snd_soc_codec *codec)
165{
166 int ret;
167
168 ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets,
169 ARRAY_SIZE(omap3pandora_out_dapm_widgets));
170 if (ret < 0)
171 return ret;
172
173 snd_soc_dapm_add_routes(codec, omap3pandora_out_map,
174 ARRAY_SIZE(omap3pandora_out_map));
175
176 return snd_soc_dapm_sync(codec);
177}
178
179static int omap3pandora_in_init(struct snd_soc_codec *codec)
180{
181 int ret;
182
183 ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets,
184 ARRAY_SIZE(omap3pandora_in_dapm_widgets));
185 if (ret < 0)
186 return ret;
187
188 snd_soc_dapm_add_routes(codec, omap3pandora_in_map,
189 ARRAY_SIZE(omap3pandora_in_map));
190
191 return snd_soc_dapm_sync(codec);
192}
193
194static struct snd_soc_ops omap3pandora_out_ops = {
195 .hw_params = omap3pandora_out_hw_params,
196};
197
198static struct snd_soc_ops omap3pandora_in_ops = {
199 .hw_params = omap3pandora_in_hw_params,
200};
201
202/* Digital audio interface glue - connects codec <--> CPU */
203static struct snd_soc_dai_link omap3pandora_dai[] = {
204 {
205 .name = "PCM1773",
206 .stream_name = "HiFi Out",
207 .cpu_dai = &omap_mcbsp_dai[0],
208 .codec_dai = &twl4030_dai,
209 .ops = &omap3pandora_out_ops,
210 .init = omap3pandora_out_init,
211 }, {
212 .name = "TWL4030",
213 .stream_name = "Line/Mic In",
214 .cpu_dai = &omap_mcbsp_dai[1],
215 .codec_dai = &twl4030_dai,
216 .ops = &omap3pandora_in_ops,
217 .init = omap3pandora_in_init,
218 }
219};
220
221/* SoC card */
222static struct snd_soc_card snd_soc_card_omap3pandora = {
223 .name = "omap3pandora",
224 .platform = &omap_soc_platform,
225 .dai_link = omap3pandora_dai,
226 .num_links = ARRAY_SIZE(omap3pandora_dai),
227};
228
229/* Audio subsystem */
230static struct snd_soc_device omap3pandora_snd_data = {
231 .card = &snd_soc_card_omap3pandora,
232 .codec_dev = &soc_codec_dev_twl4030,
233};
234
235static struct platform_device *omap3pandora_snd_device;
236
237static int __init omap3pandora_soc_init(void)
238{
239 int ret;
240
241 if (!machine_is_omap3_pandora()) {
242 pr_debug(PREFIX "Not OMAP3 Pandora\n");
243 return -ENODEV;
244 }
245 pr_info("OMAP3 Pandora SoC init\n");
246
247 ret = gpio_request(OMAP3_PANDORA_DAC_POWER_GPIO, "dac_power");
248 if (ret) {
249 pr_err(PREFIX "Failed to get DAC power GPIO\n");
250 return ret;
251 }
252
253 ret = gpio_direction_output(OMAP3_PANDORA_DAC_POWER_GPIO, 0);
254 if (ret) {
255 pr_err(PREFIX "Failed to set DAC power GPIO direction\n");
256 goto fail0;
257 }
258
259 ret = gpio_request(OMAP3_PANDORA_AMP_POWER_GPIO, "amp_power");
260 if (ret) {
261 pr_err(PREFIX "Failed to get amp power GPIO\n");
262 goto fail0;
263 }
264
265 ret = gpio_direction_output(OMAP3_PANDORA_AMP_POWER_GPIO, 0);
266 if (ret) {
267 pr_err(PREFIX "Failed to set amp power GPIO direction\n");
268 goto fail1;
269 }
270
271 omap3pandora_snd_device = platform_device_alloc("soc-audio", -1);
272 if (omap3pandora_snd_device == NULL) {
273 pr_err(PREFIX "Platform device allocation failed\n");
274 ret = -ENOMEM;
275 goto fail1;
276 }
277
278 platform_set_drvdata(omap3pandora_snd_device, &omap3pandora_snd_data);
279 omap3pandora_snd_data.dev = &omap3pandora_snd_device->dev;
280 *(unsigned int *)omap_mcbsp_dai[0].private_data = 1; /* McBSP2 */
281 *(unsigned int *)omap_mcbsp_dai[1].private_data = 3; /* McBSP4 */
282
283 ret = platform_device_add(omap3pandora_snd_device);
284 if (ret) {
285 pr_err(PREFIX "Unable to add platform device\n");
286 goto fail2;
287 }
288
289 return 0;
290
291fail2:
292 platform_device_put(omap3pandora_snd_device);
293fail1:
294 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
295fail0:
296 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
297 return ret;
298}
299module_init(omap3pandora_soc_init);
300
301static void __exit omap3pandora_soc_exit(void)
302{
303 platform_device_unregister(omap3pandora_snd_device);
304 gpio_free(OMAP3_PANDORA_AMP_POWER_GPIO);
305 gpio_free(OMAP3_PANDORA_DAC_POWER_GPIO);
306}
307module_exit(omap3pandora_soc_exit);
308
309MODULE_AUTHOR("Grazvydas Ignotas <notasas@gmail.com>");
310MODULE_DESCRIPTION("ALSA SoC OMAP3 Pandora");
311MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 0fe733796898..cd41a948df7b 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -61,7 +61,7 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
61 61
62 /* Set codec DAI configuration */ 62 /* Set codec DAI configuration */
63 err = snd_soc_dai_set_fmt(codec_dai, 63 err = snd_soc_dai_set_fmt(codec_dai,
64 SND_SOC_DAIFMT_DSP_A | 64 SND_SOC_DAIFMT_DSP_B |
65 SND_SOC_DAIFMT_NB_IF | 65 SND_SOC_DAIFMT_NB_IF |
66 SND_SOC_DAIFMT_CBM_CFM); 66 SND_SOC_DAIFMT_CBM_CFM);
67 if (err < 0) { 67 if (err < 0) {
@@ -71,7 +71,7 @@ static int osk_hw_params(struct snd_pcm_substream *substream,
71 71
72 /* Set cpu DAI configuration */ 72 /* Set cpu DAI configuration */
73 err = snd_soc_dai_set_fmt(cpu_dai, 73 err = snd_soc_dai_set_fmt(cpu_dai,
74 SND_SOC_DAIFMT_DSP_A | 74 SND_SOC_DAIFMT_DSP_B |
75 SND_SOC_DAIFMT_NB_IF | 75 SND_SOC_DAIFMT_NB_IF |
76 SND_SOC_DAIFMT_CBM_CFM); 76 SND_SOC_DAIFMT_CBM_CFM);
77 if (err < 0) { 77 if (err < 0) {
@@ -143,16 +143,16 @@ static struct snd_soc_dai_link osk_dai = {
143}; 143};
144 144
145/* Audio machine driver */ 145/* Audio machine driver */
146static struct snd_soc_machine snd_soc_machine_osk = { 146static struct snd_soc_card snd_soc_card_osk = {
147 .name = "OSK5912", 147 .name = "OSK5912",
148 .platform = &omap_soc_platform,
148 .dai_link = &osk_dai, 149 .dai_link = &osk_dai,
149 .num_links = 1, 150 .num_links = 1,
150}; 151};
151 152
152/* Audio subsystem */ 153/* Audio subsystem */
153static struct snd_soc_device osk_snd_devdata = { 154static struct snd_soc_device osk_snd_devdata = {
154 .machine = &snd_soc_machine_osk, 155 .card = &snd_soc_card_osk,
155 .platform = &omap_soc_platform,
156 .codec_dev = &soc_codec_dev_tlv320aic23, 156 .codec_dev = &soc_codec_dev_tlv320aic23,
157}; 157};
158 158
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
new file mode 100644
index 000000000000..a72dc4e159e5
--- /dev/null
+++ b/sound/soc/omap/overo.c
@@ -0,0 +1,148 @@
1/*
2 * overo.c -- SoC audio for Gumstix Overo
3 *
4 * Author: Steve Sakoman <steve@sakoman.com>
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 <mach/mcbsp.h>
33
34#include "omap-mcbsp.h"
35#include "omap-pcm.h"
36#include "../codecs/twl4030.h"
37
38static int overo_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 overo_ops = {
78 .hw_params = overo_hw_params,
79};
80
81/* Digital audio interface glue - connects codec <--> CPU */
82static struct snd_soc_dai_link overo_dai = {
83 .name = "TWL4030",
84 .stream_name = "TWL4030",
85 .cpu_dai = &omap_mcbsp_dai[0],
86 .codec_dai = &twl4030_dai,
87 .ops = &overo_ops,
88};
89
90/* Audio machine driver */
91static struct snd_soc_card snd_soc_card_overo = {
92 .name = "overo",
93 .platform = &omap_soc_platform,
94 .dai_link = &overo_dai,
95 .num_links = 1,
96};
97
98/* Audio subsystem */
99static struct snd_soc_device overo_snd_devdata = {
100 .card = &snd_soc_card_overo,
101 .codec_dev = &soc_codec_dev_twl4030,
102};
103
104static struct platform_device *overo_snd_device;
105
106static int __init overo_soc_init(void)
107{
108 int ret;
109
110 if (!machine_is_overo()) {
111 pr_debug("Not Overo!\n");
112 return -ENODEV;
113 }
114 printk(KERN_INFO "overo SoC init\n");
115
116 overo_snd_device = platform_device_alloc("soc-audio", -1);
117 if (!overo_snd_device) {
118 printk(KERN_ERR "Platform device allocation failed\n");
119 return -ENOMEM;
120 }
121
122 platform_set_drvdata(overo_snd_device, &overo_snd_devdata);
123 overo_snd_devdata.dev = &overo_snd_device->dev;
124 *(unsigned int *)overo_dai.cpu_dai->private_data = 1; /* McBSP2 */
125
126 ret = platform_device_add(overo_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(overo_snd_device);
135
136 return ret;
137}
138module_init(overo_soc_init);
139
140static void __exit overo_soc_exit(void)
141{
142 platform_device_unregister(overo_snd_device);
143}
144module_exit(overo_soc_exit);
145
146MODULE_AUTHOR("Steve Sakoman <steve@sakoman.com>");
147MODULE_DESCRIPTION("ALSA SoC overo");
148MODULE_LICENSE("GPL");
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
new file mode 100644
index 000000000000..ad97836818b1
--- /dev/null
+++ b/sound/soc/omap/sdp3430.c
@@ -0,0 +1,152 @@
1/*
2 * sdp3430.c -- SoC audio for TI OMAP3430 SDP
3 *
4 * Author: Misael Lopez Cruz <x0052729@ti.com>
5 *
6 * Based on:
7 * Author: Steve Sakoman <steve@sakoman.com>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25#include <linux/clk.h>
26#include <linux/platform_device.h>
27#include <sound/core.h>
28#include <sound/pcm.h>
29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31
32#include <asm/mach-types.h>
33#include <mach/hardware.h>
34#include <mach/gpio.h>
35#include <mach/mcbsp.h>
36
37#include "omap-mcbsp.h"
38#include "omap-pcm.h"
39#include "../codecs/twl4030.h"
40
41static int sdp3430_hw_params(struct snd_pcm_substream *substream,
42 struct snd_pcm_hw_params *params)
43{
44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
45 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
46 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
47 int ret;
48
49 /* Set codec DAI configuration */
50 ret = snd_soc_dai_set_fmt(codec_dai,
51 SND_SOC_DAIFMT_I2S |
52 SND_SOC_DAIFMT_NB_NF |
53 SND_SOC_DAIFMT_CBM_CFM);
54 if (ret < 0) {
55 printk(KERN_ERR "can't set codec DAI configuration\n");
56 return ret;
57 }
58
59 /* Set cpu DAI configuration */
60 ret = snd_soc_dai_set_fmt(cpu_dai,
61 SND_SOC_DAIFMT_I2S |
62 SND_SOC_DAIFMT_NB_NF |
63 SND_SOC_DAIFMT_CBM_CFM);
64 if (ret < 0) {
65 printk(KERN_ERR "can't set cpu DAI configuration\n");
66 return ret;
67 }
68
69 /* Set the codec system clock for DAC and ADC */
70 ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000,
71 SND_SOC_CLOCK_IN);
72 if (ret < 0) {
73 printk(KERN_ERR "can't set codec system clock\n");
74 return ret;
75 }
76
77 return 0;
78}
79
80static struct snd_soc_ops sdp3430_ops = {
81 .hw_params = sdp3430_hw_params,
82};
83
84/* Digital audio interface glue - connects codec <--> CPU */
85static struct snd_soc_dai_link sdp3430_dai = {
86 .name = "TWL4030",
87 .stream_name = "TWL4030",
88 .cpu_dai = &omap_mcbsp_dai[0],
89 .codec_dai = &twl4030_dai,
90 .ops = &sdp3430_ops,
91};
92
93/* Audio machine driver */
94static struct snd_soc_machine snd_soc_machine_sdp3430 = {
95 .name = "SDP3430",
96 .platform = &omap_soc_platform,
97 .dai_link = &sdp3430_dai,
98 .num_links = 1,
99};
100
101/* Audio subsystem */
102static struct snd_soc_device sdp3430_snd_devdata = {
103 .machine = &snd_soc_machine_sdp3430,
104 .codec_dev = &soc_codec_dev_twl4030,
105};
106
107static struct platform_device *sdp3430_snd_device;
108
109static int __init sdp3430_soc_init(void)
110{
111 int ret;
112
113 if (!machine_is_omap_3430sdp()) {
114 pr_debug("Not SDP3430!\n");
115 return -ENODEV;
116 }
117 printk(KERN_INFO "SDP3430 SoC init\n");
118
119 sdp3430_snd_device = platform_device_alloc("soc-audio", -1);
120 if (!sdp3430_snd_device) {
121 printk(KERN_ERR "Platform device allocation failed\n");
122 return -ENOMEM;
123 }
124
125 platform_set_drvdata(sdp3430_snd_device, &sdp3430_snd_devdata);
126 sdp3430_snd_devdata.dev = &sdp3430_snd_device->dev;
127 *(unsigned int *)sdp3430_dai.cpu_dai->private_data = 1; /* McBSP2 */
128
129 ret = platform_device_add(sdp3430_snd_device);
130 if (ret)
131 goto err1;
132
133 return 0;
134
135err1:
136 printk(KERN_ERR "Unable to add platform device\n");
137 platform_device_put(sdp3430_snd_device);
138
139 return ret;
140}
141module_init(sdp3430_soc_init);
142
143static void __exit sdp3430_soc_exit(void)
144{
145 platform_device_unregister(sdp3430_snd_device);
146}
147module_exit(sdp3430_soc_exit);
148
149MODULE_AUTHOR("Misael Lopez Cruz <x0052729@ti.com>");
150MODULE_DESCRIPTION("ALSA SoC SDP3430");
151MODULE_LICENSE("GPL");
152
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index f8c1cdd940ac..f82e10699471 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -21,6 +21,9 @@ config SND_PXA2XX_SOC_AC97
21config SND_PXA2XX_SOC_I2S 21config SND_PXA2XX_SOC_I2S
22 tristate 22 tristate
23 23
24config SND_PXA_SOC_SSP
25 tristate
26
24config SND_PXA2XX_SOC_CORGI 27config SND_PXA2XX_SOC_CORGI
25 tristate "SoC Audio support for Sharp Zaurus SL-C7x0" 28 tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
26 depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx 29 depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx
@@ -75,3 +78,22 @@ config SND_PXA2XX_SOC_EM_X270
75 help 78 help
76 Say Y if you want to add support for SoC audio on 79 Say Y if you want to add support for SoC audio on
77 CompuLab EM-x270. 80 CompuLab EM-x270.
81
82config SND_PXA2XX_SOC_PALM27X
83 bool "SoC Audio support for Palm T|X, T5 and LifeDrive"
84 depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || MACH_PALMT5)
85 select SND_PXA2XX_SOC_AC97
86 select SND_SOC_WM9712
87 help
88 Say Y if you want to add support for SoC audio on
89 Palm T|X, T5 or LifeDrive handheld computer.
90
91config SND_SOC_ZYLONITE
92 tristate "SoC Audio support for Marvell Zylonite"
93 depends on SND_PXA2XX_SOC && MACH_ZYLONITE
94 select SND_PXA2XX_SOC_AC97
95 select SND_PXA_SOC_SSP
96 select SND_SOC_WM9713
97 help
98 Say Y if you want to add support for SoC audio on the
99 Marvell Zylonite reference platform.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index 5bc8edf9dca9..08a9f2797729 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -2,10 +2,12 @@
2snd-soc-pxa2xx-objs := pxa2xx-pcm.o 2snd-soc-pxa2xx-objs := pxa2xx-pcm.o
3snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o 3snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
4snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o 4snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o
5snd-soc-pxa-ssp-objs := pxa-ssp.o
5 6
6obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o 7obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o
7obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o 8obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o
8obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o 9obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o
10obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
9 11
10# PXA Machine Support 12# PXA Machine Support
11snd-soc-corgi-objs := corgi.o 13snd-soc-corgi-objs := corgi.o
@@ -14,6 +16,8 @@ snd-soc-tosa-objs := tosa.o
14snd-soc-e800-objs := e800_wm9712.o 16snd-soc-e800-objs := e800_wm9712.o
15snd-soc-spitz-objs := spitz.o 17snd-soc-spitz-objs := spitz.o
16snd-soc-em-x270-objs := em-x270.o 18snd-soc-em-x270-objs := em-x270.o
19snd-soc-palm27x-objs := palm27x.o
20snd-soc-zylonite-objs := zylonite.o
17 21
18obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 22obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
19obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 23obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -21,3 +25,5 @@ obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o
21obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o 25obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o
22obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o 26obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o
23obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o 27obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o
28obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o
29obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index 2718eaf7895f..1ba25a559524 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -108,15 +108,11 @@ static int corgi_startup(struct snd_pcm_substream *substream)
108} 108}
109 109
110/* we need to unmute the HP at shutdown as the mute burns power on corgi */ 110/* we need to unmute the HP at shutdown as the mute burns power on corgi */
111static int corgi_shutdown(struct snd_pcm_substream *substream) 111static void corgi_shutdown(struct snd_pcm_substream *substream)
112{ 112{
113 struct snd_soc_pcm_runtime *rtd = substream->private_data;
114 struct snd_soc_codec *codec = rtd->socdev->codec;
115
116 /* set = unmute headphone */ 113 /* set = unmute headphone */
117 gpio_set_value(CORGI_GPIO_MUTE_L, 1); 114 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
118 gpio_set_value(CORGI_GPIO_MUTE_R, 1); 115 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
119 return 0;
120} 116}
121 117
122static int corgi_hw_params(struct snd_pcm_substream *substream, 118static int corgi_hw_params(struct snd_pcm_substream *substream,
@@ -314,8 +310,9 @@ static struct snd_soc_dai_link corgi_dai = {
314}; 310};
315 311
316/* corgi audio machine driver */ 312/* corgi audio machine driver */
317static struct snd_soc_machine snd_soc_machine_corgi = { 313static struct snd_soc_card snd_soc_corgi = {
318 .name = "Corgi", 314 .name = "Corgi",
315 .platform = &pxa2xx_soc_platform,
319 .dai_link = &corgi_dai, 316 .dai_link = &corgi_dai,
320 .num_links = 1, 317 .num_links = 1,
321}; 318};
@@ -328,8 +325,7 @@ static struct wm8731_setup_data corgi_wm8731_setup = {
328 325
329/* corgi audio subsystem */ 326/* corgi audio subsystem */
330static struct snd_soc_device corgi_snd_devdata = { 327static struct snd_soc_device corgi_snd_devdata = {
331 .machine = &snd_soc_machine_corgi, 328 .card = &snd_soc_corgi,
332 .platform = &pxa2xx_soc_platform,
333 .codec_dev = &soc_codec_dev_wm8731, 329 .codec_dev = &soc_codec_dev_wm8731,
334 .codec_data = &corgi_wm8731_setup, 330 .codec_data = &corgi_wm8731_setup,
335}; 331};
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index 6781c5be242f..2e3386dfa0f0 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -29,7 +29,7 @@
29#include "pxa2xx-pcm.h" 29#include "pxa2xx-pcm.h"
30#include "pxa2xx-ac97.h" 30#include "pxa2xx-ac97.h"
31 31
32static struct snd_soc_machine e800; 32static struct snd_soc_card e800;
33 33
34static struct snd_soc_dai_link e800_dai[] = { 34static struct snd_soc_dai_link e800_dai[] = {
35{ 35{
@@ -40,15 +40,15 @@ static struct snd_soc_dai_link e800_dai[] = {
40}, 40},
41}; 41};
42 42
43static struct snd_soc_machine e800 = { 43static struct snd_soc_card e800 = {
44 .name = "Toshiba e800", 44 .name = "Toshiba e800",
45 .platform = &pxa2xx_soc_platform,
45 .dai_link = e800_dai, 46 .dai_link = e800_dai,
46 .num_links = ARRAY_SIZE(e800_dai), 47 .num_links = ARRAY_SIZE(e800_dai),
47}; 48};
48 49
49static struct snd_soc_device e800_snd_devdata = { 50static struct snd_soc_device e800_snd_devdata = {
50 .machine = &e800, 51 .card = &e800,
51 .platform = &pxa2xx_soc_platform,
52 .codec_dev = &soc_codec_dev_wm9712, 52 .codec_dev = &soc_codec_dev_wm9712,
53}; 53};
54 54
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index e6ff6929ab4b..fe4a729ea648 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -23,7 +23,6 @@
23#include <linux/moduleparam.h> 23#include <linux/moduleparam.h>
24#include <linux/device.h> 24#include <linux/device.h>
25 25
26#include <sound/driver.h>
27#include <sound/core.h> 26#include <sound/core.h>
28#include <sound/pcm.h> 27#include <sound/pcm.h>
29#include <sound/soc.h> 28#include <sound/soc.h>
@@ -53,15 +52,15 @@ static struct snd_soc_dai_link em_x270_dai[] = {
53 }, 52 },
54}; 53};
55 54
56static struct snd_soc_machine em_x270 = { 55static struct snd_soc_card em_x270 = {
57 .name = "EM-X270", 56 .name = "EM-X270",
57 .platform = &pxa2xx_soc_platform,
58 .dai_link = em_x270_dai, 58 .dai_link = em_x270_dai,
59 .num_links = ARRAY_SIZE(em_x270_dai), 59 .num_links = ARRAY_SIZE(em_x270_dai),
60}; 60};
61 61
62static struct snd_soc_device em_x270_snd_devdata = { 62static struct snd_soc_device em_x270_snd_devdata = {
63 .machine = &em_x270, 63 .card = &em_x270,
64 .platform = &pxa2xx_soc_platform,
65 .codec_dev = &soc_codec_dev_wm9712, 64 .codec_dev = &soc_codec_dev_wm9712,
66}; 65};
67 66
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
new file mode 100644
index 000000000000..4a9cf3083af0
--- /dev/null
+++ b/sound/soc/pxa/palm27x.c
@@ -0,0 +1,269 @@
1/*
2 * linux/sound/soc/pxa/palm27x.c
3 *
4 * SoC Audio driver for Palm T|X, T5 and LifeDrive
5 *
6 * based on tosa.c
7 *
8 * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com>
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
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/device.h>
19#include <linux/gpio.h>
20#include <linux/interrupt.h>
21#include <linux/irq.h>
22
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27
28#include <asm/mach-types.h>
29#include <mach/audio.h>
30#include <mach/palmasoc.h>
31
32#include "../codecs/wm9712.h"
33#include "pxa2xx-pcm.h"
34#include "pxa2xx-ac97.h"
35
36static int palm27x_jack_func = 1;
37static int palm27x_spk_func = 1;
38static int palm27x_ep_gpio = -1;
39
40static void palm27x_ext_control(struct snd_soc_codec *codec)
41{
42 if (!palm27x_spk_func)
43 snd_soc_dapm_enable_pin(codec, "Speaker");
44 else
45 snd_soc_dapm_disable_pin(codec, "Speaker");
46
47 if (!palm27x_jack_func)
48 snd_soc_dapm_enable_pin(codec, "Headphone Jack");
49 else
50 snd_soc_dapm_disable_pin(codec, "Headphone Jack");
51
52 snd_soc_dapm_sync(codec);
53}
54
55static int palm27x_startup(struct snd_pcm_substream *substream)
56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58 struct snd_soc_codec *codec = rtd->socdev->codec;
59
60 /* check the jack status at stream startup */
61 palm27x_ext_control(codec);
62 return 0;
63}
64
65static struct snd_soc_ops palm27x_ops = {
66 .startup = palm27x_startup,
67};
68
69static irqreturn_t palm27x_interrupt(int irq, void *v)
70{
71 palm27x_spk_func = gpio_get_value(palm27x_ep_gpio);
72 palm27x_jack_func = !palm27x_spk_func;
73 return IRQ_HANDLED;
74}
75
76static int palm27x_get_jack(struct snd_kcontrol *kcontrol,
77 struct snd_ctl_elem_value *ucontrol)
78{
79 ucontrol->value.integer.value[0] = palm27x_jack_func;
80 return 0;
81}
82
83static int palm27x_set_jack(struct snd_kcontrol *kcontrol,
84 struct snd_ctl_elem_value *ucontrol)
85{
86 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
87
88 if (palm27x_jack_func == ucontrol->value.integer.value[0])
89 return 0;
90
91 palm27x_jack_func = ucontrol->value.integer.value[0];
92 palm27x_ext_control(codec);
93 return 1;
94}
95
96static int palm27x_get_spk(struct snd_kcontrol *kcontrol,
97 struct snd_ctl_elem_value *ucontrol)
98{
99 ucontrol->value.integer.value[0] = palm27x_spk_func;
100 return 0;
101}
102
103static int palm27x_set_spk(struct snd_kcontrol *kcontrol,
104 struct snd_ctl_elem_value *ucontrol)
105{
106 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
107
108 if (palm27x_spk_func == ucontrol->value.integer.value[0])
109 return 0;
110
111 palm27x_spk_func = ucontrol->value.integer.value[0];
112 palm27x_ext_control(codec);
113 return 1;
114}
115
116/* PalmTX machine dapm widgets */
117static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = {
118 SND_SOC_DAPM_HP("Headphone Jack", NULL),
119 SND_SOC_DAPM_SPK("Speaker", NULL),
120};
121
122/* PalmTX audio map */
123static const struct snd_soc_dapm_route audio_map[] = {
124 /* headphone connected to HPOUTL, HPOUTR */
125 {"Headphone Jack", NULL, "HPOUTL"},
126 {"Headphone Jack", NULL, "HPOUTR"},
127
128 /* ext speaker connected to ROUT2, LOUT2 */
129 {"Speaker", NULL, "LOUT2"},
130 {"Speaker", NULL, "ROUT2"},
131};
132
133static const char *jack_function[] = {"Headphone", "Off"};
134static const char *spk_function[] = {"On", "Off"};
135static const struct soc_enum palm27x_enum[] = {
136 SOC_ENUM_SINGLE_EXT(2, jack_function),
137 SOC_ENUM_SINGLE_EXT(2, spk_function),
138};
139
140static const struct snd_kcontrol_new palm27x_controls[] = {
141 SOC_ENUM_EXT("Jack Function", palm27x_enum[0], palm27x_get_jack,
142 palm27x_set_jack),
143 SOC_ENUM_EXT("Speaker Function", palm27x_enum[1], palm27x_get_spk,
144 palm27x_set_spk),
145};
146
147static int palm27x_ac97_init(struct snd_soc_codec *codec)
148{
149 int i, err;
150
151 snd_soc_dapm_nc_pin(codec, "OUT3");
152 snd_soc_dapm_nc_pin(codec, "MONOOUT");
153
154 /* add palm27x specific controls */
155 for (i = 0; i < ARRAY_SIZE(palm27x_controls); i++) {
156 err = snd_ctl_add(codec->card,
157 snd_soc_cnew(&palm27x_controls[i],
158 codec, NULL));
159 if (err < 0)
160 return err;
161 }
162
163 /* add palm27x specific widgets */
164 snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets,
165 ARRAY_SIZE(palm27x_dapm_widgets));
166
167 /* set up palm27x specific audio path audio_map */
168 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
169
170 snd_soc_dapm_sync(codec);
171 return 0;
172}
173
174static struct snd_soc_dai_link palm27x_dai[] = {
175{
176 .name = "AC97 HiFi",
177 .stream_name = "AC97 HiFi",
178 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
179 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_HIFI],
180 .init = palm27x_ac97_init,
181 .ops = &palm27x_ops,
182},
183{
184 .name = "AC97 Aux",
185 .stream_name = "AC97 Aux",
186 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
187 .codec_dai = &wm9712_dai[WM9712_DAI_AC97_AUX],
188 .ops = &palm27x_ops,
189},
190};
191
192static struct snd_soc_card palm27x_asoc = {
193 .name = "Palm/PXA27x",
194 .platform = &pxa2xx_soc_platform,
195 .dai_link = palm27x_dai,
196 .num_links = ARRAY_SIZE(palm27x_dai),
197};
198
199static struct snd_soc_device palm27x_snd_devdata = {
200 .card = &palm27x_asoc,
201 .codec_dev = &soc_codec_dev_wm9712,
202};
203
204static struct platform_device *palm27x_snd_device;
205
206static int __init palm27x_asoc_init(void)
207{
208 int ret;
209
210 if (!(machine_is_palmtx() || machine_is_palmt5() ||
211 machine_is_palmld()))
212 return -ENODEV;
213
214 ret = gpio_request(palm27x_ep_gpio, "Headphone Jack");
215 if (ret)
216 return ret;
217 ret = gpio_direction_input(palm27x_ep_gpio);
218 if (ret)
219 goto err_alloc;
220
221 if (request_irq(gpio_to_irq(palm27x_ep_gpio), palm27x_interrupt,
222 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
223 "Headphone jack", NULL))
224 goto err_alloc;
225
226 palm27x_snd_device = platform_device_alloc("soc-audio", -1);
227 if (!palm27x_snd_device) {
228 ret = -ENOMEM;
229 goto err_dev;
230 }
231
232 platform_set_drvdata(palm27x_snd_device, &palm27x_snd_devdata);
233 palm27x_snd_devdata.dev = &palm27x_snd_device->dev;
234 ret = platform_device_add(palm27x_snd_device);
235
236 if (ret != 0)
237 goto put_device;
238
239 return 0;
240
241put_device:
242 platform_device_put(palm27x_snd_device);
243err_dev:
244 free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
245err_alloc:
246 gpio_free(palm27x_ep_gpio);
247
248 return ret;
249}
250
251static void __exit palm27x_asoc_exit(void)
252{
253 free_irq(gpio_to_irq(palm27x_ep_gpio), NULL);
254 gpio_free(palm27x_ep_gpio);
255 platform_device_unregister(palm27x_snd_device);
256}
257
258void __init palm27x_asoc_set_pdata(struct palm27x_asoc_info *data)
259{
260 palm27x_ep_gpio = data->jack_gpio;
261}
262
263module_init(palm27x_asoc_init);
264module_exit(palm27x_asoc_exit);
265
266/* Module information */
267MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
268MODULE_DESCRIPTION("ALSA SoC Palm T|X, T5 and LifeDrive");
269MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 4d9930c52789..6e9827189fff 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -276,8 +276,9 @@ static struct snd_soc_dai_link poodle_dai = {
276}; 276};
277 277
278/* poodle audio machine driver */ 278/* poodle audio machine driver */
279static struct snd_soc_machine snd_soc_machine_poodle = { 279static struct snd_soc_card snd_soc_poodle = {
280 .name = "Poodle", 280 .name = "Poodle",
281 .platform = &pxa2xx_soc_platform,
281 .dai_link = &poodle_dai, 282 .dai_link = &poodle_dai,
282 .num_links = 1, 283 .num_links = 1,
283}; 284};
@@ -290,8 +291,7 @@ static struct wm8731_setup_data poodle_wm8731_setup = {
290 291
291/* poodle audio subsystem */ 292/* poodle audio subsystem */
292static struct snd_soc_device poodle_snd_devdata = { 293static struct snd_soc_device poodle_snd_devdata = {
293 .machine = &snd_soc_machine_poodle, 294 .card = &snd_soc_poodle,
294 .platform = &pxa2xx_soc_platform,
295 .codec_dev = &soc_codec_dev_wm8731, 295 .codec_dev = &soc_codec_dev_wm8731,
296 .codec_data = &poodle_wm8731_setup, 296 .codec_data = &poodle_wm8731_setup,
297}; 297};
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
new file mode 100644
index 000000000000..73cb6b4c2f2d
--- /dev/null
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -0,0 +1,931 @@
1#define DEBUG
2/*
3 * pxa-ssp.c -- ALSA Soc Audio Layer
4 *
5 * Copyright 2005,2008 Wolfson Microelectronics PLC.
6 * Author: Liam Girdwood
7 * Mark Brown <broonie@opensource.wolfsonmicro.com>
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 * TODO:
15 * o Test network mode for > 16bit sample size
16 */
17
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/initval.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/pxa2xx-lib.h>
30
31#include <mach/hardware.h>
32#include <mach/pxa-regs.h>
33#include <mach/regs-ssp.h>
34#include <mach/audio.h>
35#include <mach/ssp.h>
36
37#include "pxa2xx-pcm.h"
38#include "pxa-ssp.h"
39
40/*
41 * SSP audio private data
42 */
43struct ssp_priv {
44 struct ssp_dev dev;
45 unsigned int sysclk;
46 int dai_fmt;
47#ifdef CONFIG_PM
48 struct ssp_state state;
49#endif
50};
51
52#define PXA2xx_SSP1_BASE 0x41000000
53#define PXA27x_SSP2_BASE 0x41700000
54#define PXA27x_SSP3_BASE 0x41900000
55#define PXA3xx_SSP4_BASE 0x41a00000
56
57static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_out = {
58 .name = "SSP1 PCM Mono out",
59 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
60 .drcmr = &DRCMR(14),
61 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
62 DCMD_BURST16 | DCMD_WIDTH2,
63};
64
65static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_mono_in = {
66 .name = "SSP1 PCM Mono in",
67 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
68 .drcmr = &DRCMR(13),
69 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
70 DCMD_BURST16 | DCMD_WIDTH2,
71};
72
73static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_out = {
74 .name = "SSP1 PCM Stereo out",
75 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
76 .drcmr = &DRCMR(14),
77 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
78 DCMD_BURST16 | DCMD_WIDTH4,
79};
80
81static struct pxa2xx_pcm_dma_params pxa_ssp1_pcm_stereo_in = {
82 .name = "SSP1 PCM Stereo in",
83 .dev_addr = PXA2xx_SSP1_BASE + SSDR,
84 .drcmr = &DRCMR(13),
85 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
86 DCMD_BURST16 | DCMD_WIDTH4,
87};
88
89static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_out = {
90 .name = "SSP2 PCM Mono out",
91 .dev_addr = PXA27x_SSP2_BASE + SSDR,
92 .drcmr = &DRCMR(16),
93 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
94 DCMD_BURST16 | DCMD_WIDTH2,
95};
96
97static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_mono_in = {
98 .name = "SSP2 PCM Mono in",
99 .dev_addr = PXA27x_SSP2_BASE + SSDR,
100 .drcmr = &DRCMR(15),
101 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
102 DCMD_BURST16 | DCMD_WIDTH2,
103};
104
105static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_out = {
106 .name = "SSP2 PCM Stereo out",
107 .dev_addr = PXA27x_SSP2_BASE + SSDR,
108 .drcmr = &DRCMR(16),
109 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
110 DCMD_BURST16 | DCMD_WIDTH4,
111};
112
113static struct pxa2xx_pcm_dma_params pxa_ssp2_pcm_stereo_in = {
114 .name = "SSP2 PCM Stereo in",
115 .dev_addr = PXA27x_SSP2_BASE + SSDR,
116 .drcmr = &DRCMR(15),
117 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
118 DCMD_BURST16 | DCMD_WIDTH4,
119};
120
121static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_out = {
122 .name = "SSP3 PCM Mono out",
123 .dev_addr = PXA27x_SSP3_BASE + SSDR,
124 .drcmr = &DRCMR(67),
125 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
126 DCMD_BURST16 | DCMD_WIDTH2,
127};
128
129static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_mono_in = {
130 .name = "SSP3 PCM Mono in",
131 .dev_addr = PXA27x_SSP3_BASE + SSDR,
132 .drcmr = &DRCMR(66),
133 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
134 DCMD_BURST16 | DCMD_WIDTH2,
135};
136
137static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_out = {
138 .name = "SSP3 PCM Stereo out",
139 .dev_addr = PXA27x_SSP3_BASE + SSDR,
140 .drcmr = &DRCMR(67),
141 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
142 DCMD_BURST16 | DCMD_WIDTH4,
143};
144
145static struct pxa2xx_pcm_dma_params pxa_ssp3_pcm_stereo_in = {
146 .name = "SSP3 PCM Stereo in",
147 .dev_addr = PXA27x_SSP3_BASE + SSDR,
148 .drcmr = &DRCMR(66),
149 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
150 DCMD_BURST16 | DCMD_WIDTH4,
151};
152
153static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_out = {
154 .name = "SSP4 PCM Mono out",
155 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
156 .drcmr = &DRCMR(67),
157 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
158 DCMD_BURST16 | DCMD_WIDTH2,
159};
160
161static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_mono_in = {
162 .name = "SSP4 PCM Mono in",
163 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
164 .drcmr = &DRCMR(66),
165 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
166 DCMD_BURST16 | DCMD_WIDTH2,
167};
168
169static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_out = {
170 .name = "SSP4 PCM Stereo out",
171 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
172 .drcmr = &DRCMR(67),
173 .dcmd = DCMD_INCSRCADDR | DCMD_FLOWTRG |
174 DCMD_BURST16 | DCMD_WIDTH4,
175};
176
177static struct pxa2xx_pcm_dma_params pxa_ssp4_pcm_stereo_in = {
178 .name = "SSP4 PCM Stereo in",
179 .dev_addr = PXA3xx_SSP4_BASE + SSDR,
180 .drcmr = &DRCMR(66),
181 .dcmd = DCMD_INCTRGADDR | DCMD_FLOWSRC |
182 DCMD_BURST16 | DCMD_WIDTH4,
183};
184
185static void dump_registers(struct ssp_device *ssp)
186{
187 dev_dbg(&ssp->pdev->dev, "SSCR0 0x%08x SSCR1 0x%08x SSTO 0x%08x\n",
188 ssp_read_reg(ssp, SSCR0), ssp_read_reg(ssp, SSCR1),
189 ssp_read_reg(ssp, SSTO));
190
191 dev_dbg(&ssp->pdev->dev, "SSPSP 0x%08x SSSR 0x%08x SSACD 0x%08x\n",
192 ssp_read_reg(ssp, SSPSP), ssp_read_reg(ssp, SSSR),
193 ssp_read_reg(ssp, SSACD));
194}
195
196static struct pxa2xx_pcm_dma_params *ssp_dma_params[4][4] = {
197 {
198 &pxa_ssp1_pcm_mono_out, &pxa_ssp1_pcm_mono_in,
199 &pxa_ssp1_pcm_stereo_out, &pxa_ssp1_pcm_stereo_in,
200 },
201 {
202 &pxa_ssp2_pcm_mono_out, &pxa_ssp2_pcm_mono_in,
203 &pxa_ssp2_pcm_stereo_out, &pxa_ssp2_pcm_stereo_in,
204 },
205 {
206 &pxa_ssp3_pcm_mono_out, &pxa_ssp3_pcm_mono_in,
207 &pxa_ssp3_pcm_stereo_out, &pxa_ssp3_pcm_stereo_in,
208 },
209 {
210 &pxa_ssp4_pcm_mono_out, &pxa_ssp4_pcm_mono_in,
211 &pxa_ssp4_pcm_stereo_out, &pxa_ssp4_pcm_stereo_in,
212 },
213};
214
215static int pxa_ssp_startup(struct snd_pcm_substream *substream,
216 struct snd_soc_dai *dai)
217{
218 struct snd_soc_pcm_runtime *rtd = substream->private_data;
219 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
220 struct ssp_priv *priv = cpu_dai->private_data;
221 int ret = 0;
222
223 if (!cpu_dai->active) {
224 ret = ssp_init(&priv->dev, cpu_dai->id + 1, SSP_NO_IRQ);
225 if (ret < 0)
226 return ret;
227 ssp_disable(&priv->dev);
228 }
229 return ret;
230}
231
232static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
233 struct snd_soc_dai *dai)
234{
235 struct snd_soc_pcm_runtime *rtd = substream->private_data;
236 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
237 struct ssp_priv *priv = cpu_dai->private_data;
238
239 if (!cpu_dai->active) {
240 ssp_disable(&priv->dev);
241 ssp_exit(&priv->dev);
242 }
243}
244
245#ifdef CONFIG_PM
246
247static int pxa_ssp_suspend(struct snd_soc_dai *cpu_dai)
248{
249 struct ssp_priv *priv = cpu_dai->private_data;
250
251 if (!cpu_dai->active)
252 return 0;
253
254 ssp_save_state(&priv->dev, &priv->state);
255 clk_disable(priv->dev.ssp->clk);
256 return 0;
257}
258
259static int pxa_ssp_resume(struct snd_soc_dai *cpu_dai)
260{
261 struct ssp_priv *priv = cpu_dai->private_data;
262
263 if (!cpu_dai->active)
264 return 0;
265
266 clk_enable(priv->dev.ssp->clk);
267 ssp_restore_state(&priv->dev, &priv->state);
268 ssp_enable(&priv->dev);
269
270 return 0;
271}
272
273#else
274#define pxa_ssp_suspend NULL
275#define pxa_ssp_resume NULL
276#endif
277
278/**
279 * ssp_set_clkdiv - set SSP clock divider
280 * @div: serial clock rate divider
281 */
282static void ssp_set_scr(struct ssp_dev *dev, u32 div)
283{
284 struct ssp_device *ssp = dev->ssp;
285 u32 sscr0 = ssp_read_reg(dev->ssp, SSCR0) & ~SSCR0_SCR;
286
287 ssp_write_reg(ssp, SSCR0, (sscr0 | SSCR0_SerClkDiv(div)));
288}
289
290/*
291 * Set the SSP ports SYSCLK.
292 */
293static int pxa_ssp_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
294 int clk_id, unsigned int freq, int dir)
295{
296 struct ssp_priv *priv = cpu_dai->private_data;
297 struct ssp_device *ssp = priv->dev.ssp;
298 int val;
299
300 u32 sscr0 = ssp_read_reg(ssp, SSCR0) &
301 ~(SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC);
302
303 dev_dbg(&ssp->pdev->dev,
304 "pxa_ssp_set_dai_sysclk id: %d, clk_id %d, freq %d\n",
305 cpu_dai->id, clk_id, freq);
306
307 switch (clk_id) {
308 case PXA_SSP_CLK_NET_PLL:
309 sscr0 |= SSCR0_MOD;
310 break;
311 case PXA_SSP_CLK_PLL:
312 /* Internal PLL is fixed */
313 if (cpu_is_pxa25x())
314 priv->sysclk = 1843200;
315 else
316 priv->sysclk = 13000000;
317 break;
318 case PXA_SSP_CLK_EXT:
319 priv->sysclk = freq;
320 sscr0 |= SSCR0_ECS;
321 break;
322 case PXA_SSP_CLK_NET:
323 priv->sysclk = freq;
324 sscr0 |= SSCR0_NCS | SSCR0_MOD;
325 break;
326 case PXA_SSP_CLK_AUDIO:
327 priv->sysclk = 0;
328 ssp_set_scr(&priv->dev, 1);
329 sscr0 |= SSCR0_ADC;
330 break;
331 default:
332 return -ENODEV;
333 }
334
335 /* The SSP clock must be disabled when changing SSP clock mode
336 * on PXA2xx. On PXA3xx it must be enabled when doing so. */
337 if (!cpu_is_pxa3xx())
338 clk_disable(priv->dev.ssp->clk);
339 val = ssp_read_reg(ssp, SSCR0) | sscr0;
340 ssp_write_reg(ssp, SSCR0, val);
341 if (!cpu_is_pxa3xx())
342 clk_enable(priv->dev.ssp->clk);
343
344 return 0;
345}
346
347/*
348 * Set the SSP clock dividers.
349 */
350static int pxa_ssp_set_dai_clkdiv(struct snd_soc_dai *cpu_dai,
351 int div_id, int div)
352{
353 struct ssp_priv *priv = cpu_dai->private_data;
354 struct ssp_device *ssp = priv->dev.ssp;
355 int val;
356
357 switch (div_id) {
358 case PXA_SSP_AUDIO_DIV_ACDS:
359 val = (ssp_read_reg(ssp, SSACD) & ~0x7) | SSACD_ACDS(div);
360 ssp_write_reg(ssp, SSACD, val);
361 break;
362 case PXA_SSP_AUDIO_DIV_SCDB:
363 val = ssp_read_reg(ssp, SSACD);
364 val &= ~SSACD_SCDB;
365#if defined(CONFIG_PXA3xx)
366 if (cpu_is_pxa3xx())
367 val &= ~SSACD_SCDX8;
368#endif
369 switch (div) {
370 case PXA_SSP_CLK_SCDB_1:
371 val |= SSACD_SCDB;
372 break;
373 case PXA_SSP_CLK_SCDB_4:
374 break;
375#if defined(CONFIG_PXA3xx)
376 case PXA_SSP_CLK_SCDB_8:
377 if (cpu_is_pxa3xx())
378 val |= SSACD_SCDX8;
379 else
380 return -EINVAL;
381 break;
382#endif
383 default:
384 return -EINVAL;
385 }
386 ssp_write_reg(ssp, SSACD, val);
387 break;
388 case PXA_SSP_DIV_SCR:
389 ssp_set_scr(&priv->dev, div);
390 break;
391 default:
392 return -ENODEV;
393 }
394
395 return 0;
396}
397
398/*
399 * Configure the PLL frequency pxa27x and (afaik - pxa320 only)
400 */
401static int pxa_ssp_set_dai_pll(struct snd_soc_dai *cpu_dai,
402 int pll_id, unsigned int freq_in, unsigned int freq_out)
403{
404 struct ssp_priv *priv = cpu_dai->private_data;
405 struct ssp_device *ssp = priv->dev.ssp;
406 u32 ssacd = ssp_read_reg(ssp, SSACD) & ~0x70;
407
408#if defined(CONFIG_PXA3xx)
409 if (cpu_is_pxa3xx())
410 ssp_write_reg(ssp, SSACDD, 0);
411#endif
412
413 switch (freq_out) {
414 case 5622000:
415 break;
416 case 11345000:
417 ssacd |= (0x1 << 4);
418 break;
419 case 12235000:
420 ssacd |= (0x2 << 4);
421 break;
422 case 14857000:
423 ssacd |= (0x3 << 4);
424 break;
425 case 32842000:
426 ssacd |= (0x4 << 4);
427 break;
428 case 48000000:
429 ssacd |= (0x5 << 4);
430 break;
431 case 0:
432 /* Disable */
433 break;
434
435 default:
436#ifdef CONFIG_PXA3xx
437 /* PXA3xx has a clock ditherer which can be used to generate
438 * a wider range of frequencies - calculate a value for it.
439 */
440 if (cpu_is_pxa3xx()) {
441 u32 val;
442 u64 tmp = 19968;
443 tmp *= 1000000;
444 do_div(tmp, freq_out);
445 val = tmp;
446
447 val = (val << 16) | 64;;
448 ssp_write_reg(ssp, SSACDD, val);
449
450 ssacd |= (0x6 << 4);
451
452 dev_dbg(&ssp->pdev->dev,
453 "Using SSACDD %x to supply %dHz\n",
454 val, freq_out);
455 break;
456 }
457#endif
458
459 return -EINVAL;
460 }
461
462 ssp_write_reg(ssp, SSACD, ssacd);
463
464 return 0;
465}
466
467/*
468 * Set the active slots in TDM/Network mode
469 */
470static int pxa_ssp_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai,
471 unsigned int mask, int slots)
472{
473 struct ssp_priv *priv = cpu_dai->private_data;
474 struct ssp_device *ssp = priv->dev.ssp;
475 u32 sscr0;
476
477 sscr0 = ssp_read_reg(ssp, SSCR0) & ~SSCR0_SlotsPerFrm(7);
478
479 /* set number of active slots */
480 sscr0 |= SSCR0_SlotsPerFrm(slots);
481 ssp_write_reg(ssp, SSCR0, sscr0);
482
483 /* set active slot mask */
484 ssp_write_reg(ssp, SSTSA, mask);
485 ssp_write_reg(ssp, SSRSA, mask);
486 return 0;
487}
488
489/*
490 * Tristate the SSP DAI lines
491 */
492static int pxa_ssp_set_dai_tristate(struct snd_soc_dai *cpu_dai,
493 int tristate)
494{
495 struct ssp_priv *priv = cpu_dai->private_data;
496 struct ssp_device *ssp = priv->dev.ssp;
497 u32 sscr1;
498
499 sscr1 = ssp_read_reg(ssp, SSCR1);
500 if (tristate)
501 sscr1 &= ~SSCR1_TTE;
502 else
503 sscr1 |= SSCR1_TTE;
504 ssp_write_reg(ssp, SSCR1, sscr1);
505
506 return 0;
507}
508
509/*
510 * Set up the SSP DAI format.
511 * The SSP Port must be inactive before calling this function as the
512 * physical interface format is changed.
513 */
514static int pxa_ssp_set_dai_fmt(struct snd_soc_dai *cpu_dai,
515 unsigned int fmt)
516{
517 struct ssp_priv *priv = cpu_dai->private_data;
518 struct ssp_device *ssp = priv->dev.ssp;
519 u32 sscr0;
520 u32 sscr1;
521 u32 sspsp;
522
523 /* reset port settings */
524 sscr0 = ssp_read_reg(ssp, SSCR0) &
525 (SSCR0_ECS | SSCR0_NCS | SSCR0_MOD | SSCR0_ADC);
526 sscr1 = SSCR1_RxTresh(8) | SSCR1_TxTresh(7);
527 sspsp = 0;
528
529 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
530 case SND_SOC_DAIFMT_CBM_CFM:
531 sscr1 |= SSCR1_SCLKDIR | SSCR1_SFRMDIR;
532 break;
533 case SND_SOC_DAIFMT_CBM_CFS:
534 sscr1 |= SSCR1_SCLKDIR;
535 break;
536 case SND_SOC_DAIFMT_CBS_CFS:
537 break;
538 default:
539 return -EINVAL;
540 }
541
542 ssp_write_reg(ssp, SSCR0, sscr0);
543 ssp_write_reg(ssp, SSCR1, sscr1);
544 ssp_write_reg(ssp, SSPSP, sspsp);
545
546 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
547 case SND_SOC_DAIFMT_I2S:
548 sscr0 |= SSCR0_MOD | SSCR0_PSP;
549 sscr1 |= SSCR1_RWOT | SSCR1_TRAIL;
550
551 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
552 case SND_SOC_DAIFMT_NB_NF:
553 sspsp |= SSPSP_FSRT;
554 break;
555 case SND_SOC_DAIFMT_NB_IF:
556 sspsp |= SSPSP_SFRMP | SSPSP_FSRT;
557 break;
558 case SND_SOC_DAIFMT_IB_IF:
559 sspsp |= SSPSP_SFRMP;
560 break;
561 default:
562 return -EINVAL;
563 }
564 break;
565
566 case SND_SOC_DAIFMT_DSP_A:
567 sspsp |= SSPSP_FSRT;
568 case SND_SOC_DAIFMT_DSP_B:
569 sscr0 |= SSCR0_MOD | SSCR0_PSP;
570 sscr1 |= SSCR1_TRAIL | SSCR1_RWOT;
571
572 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
573 case SND_SOC_DAIFMT_NB_NF:
574 sspsp |= SSPSP_SFRMP;
575 break;
576 case SND_SOC_DAIFMT_IB_IF:
577 break;
578 default:
579 return -EINVAL;
580 }
581 break;
582
583 default:
584 return -EINVAL;
585 }
586
587 ssp_write_reg(ssp, SSCR0, sscr0);
588 ssp_write_reg(ssp, SSCR1, sscr1);
589 ssp_write_reg(ssp, SSPSP, sspsp);
590
591 dump_registers(ssp);
592
593 /* Since we are configuring the timings for the format by hand
594 * we have to defer some things until hw_params() where we
595 * know parameters like the sample size.
596 */
597 priv->dai_fmt = fmt;
598
599 return 0;
600}
601
602/*
603 * Set the SSP audio DMA parameters and sample size.
604 * Can be called multiple times by oss emulation.
605 */
606static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
607 struct snd_pcm_hw_params *params,
608 struct snd_soc_dai *dai)
609{
610 struct snd_soc_pcm_runtime *rtd = substream->private_data;
611 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
612 struct ssp_priv *priv = cpu_dai->private_data;
613 struct ssp_device *ssp = priv->dev.ssp;
614 int dma = 0, chn = params_channels(params);
615 u32 sscr0;
616 u32 sspsp;
617 int width = snd_pcm_format_physical_width(params_format(params));
618
619 /* select correct DMA params */
620 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
621 dma = 1; /* capture DMA offset is 1,3 */
622 if (chn == 2)
623 dma += 2; /* stereo DMA offset is 2, mono is 0 */
624 cpu_dai->dma_data = ssp_dma_params[cpu_dai->id][dma];
625
626 dev_dbg(&ssp->pdev->dev, "pxa_ssp_hw_params: dma %d\n", dma);
627
628 /* we can only change the settings if the port is not in use */
629 if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
630 return 0;
631
632 /* clear selected SSP bits */
633 sscr0 = ssp_read_reg(ssp, SSCR0) & ~(SSCR0_DSS | SSCR0_EDSS);
634 ssp_write_reg(ssp, SSCR0, sscr0);
635
636 /* bit size */
637 sscr0 = ssp_read_reg(ssp, SSCR0);
638 switch (params_format(params)) {
639 case SNDRV_PCM_FORMAT_S16_LE:
640#ifdef CONFIG_PXA3xx
641 if (cpu_is_pxa3xx())
642 sscr0 |= SSCR0_FPCKE;
643#endif
644 sscr0 |= SSCR0_DataSize(16);
645 if (params_channels(params) > 1)
646 sscr0 |= SSCR0_EDSS;
647 break;
648 case SNDRV_PCM_FORMAT_S24_LE:
649 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(8));
650 /* we must be in network mode (2 slots) for 24 bit stereo */
651 break;
652 case SNDRV_PCM_FORMAT_S32_LE:
653 sscr0 |= (SSCR0_EDSS | SSCR0_DataSize(16));
654 /* we must be in network mode (2 slots) for 32 bit stereo */
655 break;
656 }
657 ssp_write_reg(ssp, SSCR0, sscr0);
658
659 switch (priv->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
660 case SND_SOC_DAIFMT_I2S:
661 /* Cleared when the DAI format is set */
662 sspsp = ssp_read_reg(ssp, SSPSP) | SSPSP_SFRMWDTH(width);
663 ssp_write_reg(ssp, SSPSP, sspsp);
664 break;
665 default:
666 break;
667 }
668
669 /* We always use a network mode so we always require TDM slots
670 * - complain loudly and fail if they've not been set up yet.
671 */
672 if (!(ssp_read_reg(ssp, SSTSA) & 0xf)) {
673 dev_err(&ssp->pdev->dev, "No TDM timeslot configured\n");
674 return -EINVAL;
675 }
676
677 dump_registers(ssp);
678
679 return 0;
680}
681
682static int pxa_ssp_trigger(struct snd_pcm_substream *substream, int cmd,
683 struct snd_soc_dai *dai)
684{
685 struct snd_soc_pcm_runtime *rtd = substream->private_data;
686 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
687 int ret = 0;
688 struct ssp_priv *priv = cpu_dai->private_data;
689 struct ssp_device *ssp = priv->dev.ssp;
690 int val;
691
692 switch (cmd) {
693 case SNDRV_PCM_TRIGGER_RESUME:
694 ssp_enable(&priv->dev);
695 break;
696 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
697 val = ssp_read_reg(ssp, SSCR1);
698 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
699 val |= SSCR1_TSRE;
700 else
701 val |= SSCR1_RSRE;
702 ssp_write_reg(ssp, SSCR1, val);
703 val = ssp_read_reg(ssp, SSSR);
704 ssp_write_reg(ssp, SSSR, val);
705 break;
706 case SNDRV_PCM_TRIGGER_START:
707 val = ssp_read_reg(ssp, SSCR1);
708 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
709 val |= SSCR1_TSRE;
710 else
711 val |= SSCR1_RSRE;
712 ssp_write_reg(ssp, SSCR1, val);
713 ssp_enable(&priv->dev);
714 break;
715 case SNDRV_PCM_TRIGGER_STOP:
716 val = ssp_read_reg(ssp, SSCR1);
717 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
718 val &= ~SSCR1_TSRE;
719 else
720 val &= ~SSCR1_RSRE;
721 ssp_write_reg(ssp, SSCR1, val);
722 break;
723 case SNDRV_PCM_TRIGGER_SUSPEND:
724 ssp_disable(&priv->dev);
725 break;
726 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
727 val = ssp_read_reg(ssp, SSCR1);
728 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
729 val &= ~SSCR1_TSRE;
730 else
731 val &= ~SSCR1_RSRE;
732 ssp_write_reg(ssp, SSCR1, val);
733 break;
734
735 default:
736 ret = -EINVAL;
737 }
738
739 dump_registers(ssp);
740
741 return ret;
742}
743
744static int pxa_ssp_probe(struct platform_device *pdev,
745 struct snd_soc_dai *dai)
746{
747 struct ssp_priv *priv;
748 int ret;
749
750 priv = kzalloc(sizeof(struct ssp_priv), GFP_KERNEL);
751 if (!priv)
752 return -ENOMEM;
753
754 priv->dev.ssp = ssp_request(dai->id, "SoC audio");
755 if (priv->dev.ssp == NULL) {
756 ret = -ENODEV;
757 goto err_priv;
758 }
759
760 dai->private_data = priv;
761
762 return 0;
763
764err_priv:
765 kfree(priv);
766 return ret;
767}
768
769static void pxa_ssp_remove(struct platform_device *pdev,
770 struct snd_soc_dai *dai)
771{
772 struct ssp_priv *priv = dai->private_data;
773 ssp_free(priv->dev.ssp);
774}
775
776#define PXA_SSP_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
777 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
778 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
779 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
780
781#define PXA_SSP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
782 SNDRV_PCM_FMTBIT_S24_LE | \
783 SNDRV_PCM_FMTBIT_S32_LE)
784
785struct snd_soc_dai pxa_ssp_dai[] = {
786 {
787 .name = "pxa2xx-ssp1",
788 .id = 0,
789 .probe = pxa_ssp_probe,
790 .remove = pxa_ssp_remove,
791 .suspend = pxa_ssp_suspend,
792 .resume = pxa_ssp_resume,
793 .playback = {
794 .channels_min = 1,
795 .channels_max = 2,
796 .rates = PXA_SSP_RATES,
797 .formats = PXA_SSP_FORMATS,
798 },
799 .capture = {
800 .channels_min = 1,
801 .channels_max = 2,
802 .rates = PXA_SSP_RATES,
803 .formats = PXA_SSP_FORMATS,
804 },
805 .ops = {
806 .startup = pxa_ssp_startup,
807 .shutdown = pxa_ssp_shutdown,
808 .trigger = pxa_ssp_trigger,
809 .hw_params = pxa_ssp_hw_params,
810 .set_sysclk = pxa_ssp_set_dai_sysclk,
811 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
812 .set_pll = pxa_ssp_set_dai_pll,
813 .set_fmt = pxa_ssp_set_dai_fmt,
814 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
815 .set_tristate = pxa_ssp_set_dai_tristate,
816 },
817 },
818 { .name = "pxa2xx-ssp2",
819 .id = 1,
820 .probe = pxa_ssp_probe,
821 .remove = pxa_ssp_remove,
822 .suspend = pxa_ssp_suspend,
823 .resume = pxa_ssp_resume,
824 .playback = {
825 .channels_min = 1,
826 .channels_max = 2,
827 .rates = PXA_SSP_RATES,
828 .formats = PXA_SSP_FORMATS,
829 },
830 .capture = {
831 .channels_min = 1,
832 .channels_max = 2,
833 .rates = PXA_SSP_RATES,
834 .formats = PXA_SSP_FORMATS,
835 },
836 .ops = {
837 .startup = pxa_ssp_startup,
838 .shutdown = pxa_ssp_shutdown,
839 .trigger = pxa_ssp_trigger,
840 .hw_params = pxa_ssp_hw_params,
841 .set_sysclk = pxa_ssp_set_dai_sysclk,
842 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
843 .set_pll = pxa_ssp_set_dai_pll,
844 .set_fmt = pxa_ssp_set_dai_fmt,
845 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
846 .set_tristate = pxa_ssp_set_dai_tristate,
847 },
848 },
849 {
850 .name = "pxa2xx-ssp3",
851 .id = 2,
852 .probe = pxa_ssp_probe,
853 .remove = pxa_ssp_remove,
854 .suspend = pxa_ssp_suspend,
855 .resume = pxa_ssp_resume,
856 .playback = {
857 .channels_min = 1,
858 .channels_max = 2,
859 .rates = PXA_SSP_RATES,
860 .formats = PXA_SSP_FORMATS,
861 },
862 .capture = {
863 .channels_min = 1,
864 .channels_max = 2,
865 .rates = PXA_SSP_RATES,
866 .formats = PXA_SSP_FORMATS,
867 },
868 .ops = {
869 .startup = pxa_ssp_startup,
870 .shutdown = pxa_ssp_shutdown,
871 .trigger = pxa_ssp_trigger,
872 .hw_params = pxa_ssp_hw_params,
873 .set_sysclk = pxa_ssp_set_dai_sysclk,
874 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
875 .set_pll = pxa_ssp_set_dai_pll,
876 .set_fmt = pxa_ssp_set_dai_fmt,
877 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
878 .set_tristate = pxa_ssp_set_dai_tristate,
879 },
880 },
881 {
882 .name = "pxa2xx-ssp4",
883 .id = 3,
884 .probe = pxa_ssp_probe,
885 .remove = pxa_ssp_remove,
886 .suspend = pxa_ssp_suspend,
887 .resume = pxa_ssp_resume,
888 .playback = {
889 .channels_min = 1,
890 .channels_max = 2,
891 .rates = PXA_SSP_RATES,
892 .formats = PXA_SSP_FORMATS,
893 },
894 .capture = {
895 .channels_min = 1,
896 .channels_max = 2,
897 .rates = PXA_SSP_RATES,
898 .formats = PXA_SSP_FORMATS,
899 },
900 .ops = {
901 .startup = pxa_ssp_startup,
902 .shutdown = pxa_ssp_shutdown,
903 .trigger = pxa_ssp_trigger,
904 .hw_params = pxa_ssp_hw_params,
905 .set_sysclk = pxa_ssp_set_dai_sysclk,
906 .set_clkdiv = pxa_ssp_set_dai_clkdiv,
907 .set_pll = pxa_ssp_set_dai_pll,
908 .set_fmt = pxa_ssp_set_dai_fmt,
909 .set_tdm_slot = pxa_ssp_set_dai_tdm_slot,
910 .set_tristate = pxa_ssp_set_dai_tristate,
911 },
912 },
913};
914EXPORT_SYMBOL_GPL(pxa_ssp_dai);
915
916static int __init pxa_ssp_init(void)
917{
918 return snd_soc_register_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
919}
920module_init(pxa_ssp_init);
921
922static void __exit pxa_ssp_exit(void)
923{
924 snd_soc_unregister_dais(pxa_ssp_dai, ARRAY_SIZE(pxa_ssp_dai));
925}
926module_exit(pxa_ssp_exit);
927
928/* Module information */
929MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
930MODULE_DESCRIPTION("PXA SSP/PCM SoC Interface");
931MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa-ssp.h b/sound/soc/pxa/pxa-ssp.h
new file mode 100644
index 000000000000..91deadd55675
--- /dev/null
+++ b/sound/soc/pxa/pxa-ssp.h
@@ -0,0 +1,47 @@
1/*
2 * ASoC PXA SSP port support
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef _PXA_SSP_H
10#define _PXA_SSP_H
11
12/* pxa DAI SSP IDs */
13#define PXA_DAI_SSP1 0
14#define PXA_DAI_SSP2 1
15#define PXA_DAI_SSP3 2
16#define PXA_DAI_SSP4 3
17
18/* SSP clock sources */
19#define PXA_SSP_CLK_PLL 0
20#define PXA_SSP_CLK_EXT 1
21#define PXA_SSP_CLK_NET 2
22#define PXA_SSP_CLK_AUDIO 3
23#define PXA_SSP_CLK_NET_PLL 4
24
25/* SSP audio dividers */
26#define PXA_SSP_AUDIO_DIV_ACDS 0
27#define PXA_SSP_AUDIO_DIV_SCDB 1
28#define PXA_SSP_DIV_SCR 2
29
30/* SSP ACDS audio dividers values */
31#define PXA_SSP_CLK_AUDIO_DIV_1 0
32#define PXA_SSP_CLK_AUDIO_DIV_2 1
33#define PXA_SSP_CLK_AUDIO_DIV_4 2
34#define PXA_SSP_CLK_AUDIO_DIV_8 3
35#define PXA_SSP_CLK_AUDIO_DIV_16 4
36#define PXA_SSP_CLK_AUDIO_DIV_32 5
37
38/* SSP divider bypass */
39#define PXA_SSP_CLK_SCDB_4 0
40#define PXA_SSP_CLK_SCDB_1 1
41#define PXA_SSP_CLK_SCDB_8 2
42
43#define PXA_SSP_PLL_OUT 0
44
45extern struct snd_soc_dai pxa_ssp_dai[4];
46
47#endif
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c
index a7a3a9c5c6ff..780db6757ad2 100644
--- a/sound/soc/pxa/pxa2xx-ac97.c
+++ b/sound/soc/pxa/pxa2xx-ac97.c
@@ -87,14 +87,12 @@ static struct pxa2xx_pcm_dma_params pxa2xx_ac97_pcm_mic_mono_in = {
87}; 87};
88 88
89#ifdef CONFIG_PM 89#ifdef CONFIG_PM
90static int pxa2xx_ac97_suspend(struct platform_device *pdev, 90static int pxa2xx_ac97_suspend(struct snd_soc_dai *dai)
91 struct snd_soc_dai *dai)
92{ 91{
93 return pxa2xx_ac97_hw_suspend(); 92 return pxa2xx_ac97_hw_suspend();
94} 93}
95 94
96static int pxa2xx_ac97_resume(struct platform_device *pdev, 95static int pxa2xx_ac97_resume(struct snd_soc_dai *dai)
97 struct snd_soc_dai *dai)
98{ 96{
99 return pxa2xx_ac97_hw_resume(); 97 return pxa2xx_ac97_hw_resume();
100} 98}
@@ -117,7 +115,8 @@ static void pxa2xx_ac97_remove(struct platform_device *pdev,
117} 115}
118 116
119static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, 117static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
120 struct snd_pcm_hw_params *params) 118 struct snd_pcm_hw_params *params,
119 struct snd_soc_dai *dai)
121{ 120{
122 struct snd_soc_pcm_runtime *rtd = substream->private_data; 121 struct snd_soc_pcm_runtime *rtd = substream->private_data;
123 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 122 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -131,7 +130,8 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
131} 130}
132 131
133static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, 132static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
134 struct snd_pcm_hw_params *params) 133 struct snd_pcm_hw_params *params,
134 struct snd_soc_dai *dai)
135{ 135{
136 struct snd_soc_pcm_runtime *rtd = substream->private_data; 136 struct snd_soc_pcm_runtime *rtd = substream->private_data;
137 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 137 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -145,7 +145,8 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
145} 145}
146 146
147static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, 147static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
148 struct snd_pcm_hw_params *params) 148 struct snd_pcm_hw_params *params,
149 struct snd_soc_dai *dai)
149{ 150{
150 struct snd_soc_pcm_runtime *rtd = substream->private_data; 151 struct snd_soc_pcm_runtime *rtd = substream->private_data;
151 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 152 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -170,7 +171,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
170{ 171{
171 .name = "pxa2xx-ac97", 172 .name = "pxa2xx-ac97",
172 .id = 0, 173 .id = 0,
173 .type = SND_SOC_DAI_AC97, 174 .ac97_control = 1,
174 .probe = pxa2xx_ac97_probe, 175 .probe = pxa2xx_ac97_probe,
175 .remove = pxa2xx_ac97_remove, 176 .remove = pxa2xx_ac97_remove,
176 .suspend = pxa2xx_ac97_suspend, 177 .suspend = pxa2xx_ac97_suspend,
@@ -193,7 +194,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
193{ 194{
194 .name = "pxa2xx-ac97-aux", 195 .name = "pxa2xx-ac97-aux",
195 .id = 1, 196 .id = 1,
196 .type = SND_SOC_DAI_AC97, 197 .ac97_control = 1,
197 .playback = { 198 .playback = {
198 .stream_name = "AC97 Aux Playback", 199 .stream_name = "AC97 Aux Playback",
199 .channels_min = 1, 200 .channels_min = 1,
@@ -212,7 +213,7 @@ struct snd_soc_dai pxa_ac97_dai[] = {
212{ 213{
213 .name = "pxa2xx-ac97-mic", 214 .name = "pxa2xx-ac97-mic",
214 .id = 2, 215 .id = 2,
215 .type = SND_SOC_DAI_AC97, 216 .ac97_control = 1,
216 .capture = { 217 .capture = {
217 .stream_name = "AC97 Mic Capture", 218 .stream_name = "AC97 Mic Capture",
218 .channels_min = 1, 219 .channels_min = 1,
@@ -227,6 +228,18 @@ struct snd_soc_dai pxa_ac97_dai[] = {
227EXPORT_SYMBOL_GPL(pxa_ac97_dai); 228EXPORT_SYMBOL_GPL(pxa_ac97_dai);
228EXPORT_SYMBOL_GPL(soc_ac97_ops); 229EXPORT_SYMBOL_GPL(soc_ac97_ops);
229 230
231static int __init pxa_ac97_init(void)
232{
233 return snd_soc_register_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
234}
235module_init(pxa_ac97_init);
236
237static void __exit pxa_ac97_exit(void)
238{
239 snd_soc_unregister_dais(pxa_ac97_dai, ARRAY_SIZE(pxa_ac97_dai));
240}
241module_exit(pxa_ac97_exit);
242
230MODULE_AUTHOR("Nicolas Pitre"); 243MODULE_AUTHOR("Nicolas Pitre");
231MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip"); 244MODULE_DESCRIPTION("AC97 driver for the Intel PXA2xx chip");
232MODULE_LICENSE("GPL"); 245MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c
index e758034db5c3..517991fb1099 100644
--- a/sound/soc/pxa/pxa2xx-i2s.c
+++ b/sound/soc/pxa/pxa2xx-i2s.c
@@ -121,7 +121,8 @@ static struct pxa2xx_gpio gpio_bus[] = {
121 }, 121 },
122}; 122};
123 123
124static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream) 124static int pxa2xx_i2s_startup(struct snd_pcm_substream *substream,
125 struct snd_soc_dai *dai)
125{ 126{
126 struct snd_soc_pcm_runtime *rtd = substream->private_data; 127 struct snd_soc_pcm_runtime *rtd = substream->private_data;
127 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 128 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -187,7 +188,8 @@ static int pxa2xx_i2s_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
187} 188}
188 189
189static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, 190static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
190 struct snd_pcm_hw_params *params) 191 struct snd_pcm_hw_params *params,
192 struct snd_soc_dai *dai)
191{ 193{
192 struct snd_soc_pcm_runtime *rtd = substream->private_data; 194 struct snd_soc_pcm_runtime *rtd = substream->private_data;
193 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 195 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -248,7 +250,8 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
248 return 0; 250 return 0;
249} 251}
250 252
251static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 253static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
254 struct snd_soc_dai *dai)
252{ 255{
253 int ret = 0; 256 int ret = 0;
254 257
@@ -269,7 +272,8 @@ static int pxa2xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd)
269 return ret; 272 return ret;
270} 273}
271 274
272static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream) 275static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream,
276 struct snd_soc_dai *dai)
273{ 277{
274 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 278 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
275 SACR1 |= SACR1_DRPL; 279 SACR1 |= SACR1_DRPL;
@@ -289,8 +293,7 @@ static void pxa2xx_i2s_shutdown(struct snd_pcm_substream *substream)
289} 293}
290 294
291#ifdef CONFIG_PM 295#ifdef CONFIG_PM
292static int pxa2xx_i2s_suspend(struct platform_device *dev, 296static int pxa2xx_i2s_suspend(struct snd_soc_dai *dai)
293 struct snd_soc_dai *dai)
294{ 297{
295 if (!dai->active) 298 if (!dai->active)
296 return 0; 299 return 0;
@@ -307,8 +310,7 @@ static int pxa2xx_i2s_suspend(struct platform_device *dev,
307 return 0; 310 return 0;
308} 311}
309 312
310static int pxa2xx_i2s_resume(struct platform_device *pdev, 313static int pxa2xx_i2s_resume(struct snd_soc_dai *dai)
311 struct snd_soc_dai *dai)
312{ 314{
313 if (!dai->active) 315 if (!dai->active)
314 return 0; 316 return 0;
@@ -336,7 +338,6 @@ static int pxa2xx_i2s_resume(struct platform_device *pdev,
336struct snd_soc_dai pxa_i2s_dai = { 338struct snd_soc_dai pxa_i2s_dai = {
337 .name = "pxa2xx-i2s", 339 .name = "pxa2xx-i2s",
338 .id = 0, 340 .id = 0,
339 .type = SND_SOC_DAI_I2S,
340 .suspend = pxa2xx_i2s_suspend, 341 .suspend = pxa2xx_i2s_suspend,
341 .resume = pxa2xx_i2s_resume, 342 .resume = pxa2xx_i2s_resume,
342 .playback = { 343 .playback = {
@@ -353,8 +354,7 @@ struct snd_soc_dai pxa_i2s_dai = {
353 .startup = pxa2xx_i2s_startup, 354 .startup = pxa2xx_i2s_startup,
354 .shutdown = pxa2xx_i2s_shutdown, 355 .shutdown = pxa2xx_i2s_shutdown,
355 .trigger = pxa2xx_i2s_trigger, 356 .trigger = pxa2xx_i2s_trigger,
356 .hw_params = pxa2xx_i2s_hw_params,}, 357 .hw_params = pxa2xx_i2s_hw_params,
357 .dai_ops = {
358 .set_fmt = pxa2xx_i2s_set_dai_fmt, 358 .set_fmt = pxa2xx_i2s_set_dai_fmt,
359 .set_sysclk = pxa2xx_i2s_set_dai_sysclk, 359 .set_sysclk = pxa2xx_i2s_set_dai_sysclk,
360 }, 360 },
@@ -364,12 +364,23 @@ EXPORT_SYMBOL_GPL(pxa_i2s_dai);
364 364
365static int pxa2xx_i2s_probe(struct platform_device *dev) 365static int pxa2xx_i2s_probe(struct platform_device *dev)
366{ 366{
367 int ret;
368
367 clk_i2s = clk_get(&dev->dev, "I2SCLK"); 369 clk_i2s = clk_get(&dev->dev, "I2SCLK");
368 return IS_ERR(clk_i2s) ? PTR_ERR(clk_i2s) : 0; 370 if (IS_ERR(clk_i2s))
371 return PTR_ERR(clk_i2s);
372
373 pxa_i2s_dai.dev = &dev->dev;
374 ret = snd_soc_register_dai(&pxa_i2s_dai);
375 if (ret != 0)
376 clk_put(clk_i2s);
377
378 return ret;
369} 379}
370 380
371static int __devexit pxa2xx_i2s_remove(struct platform_device *dev) 381static int __devexit pxa2xx_i2s_remove(struct platform_device *dev)
372{ 382{
383 snd_soc_unregister_dai(&pxa_i2s_dai);
373 clk_put(clk_i2s); 384 clk_put(clk_i2s);
374 clk_i2s = ERR_PTR(-ENOENT); 385 clk_i2s = ERR_PTR(-ENOENT);
375 return 0; 386 return 0;
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c
index afcd892cd2fa..c670d08e7c9e 100644
--- a/sound/soc/pxa/pxa2xx-pcm.c
+++ b/sound/soc/pxa/pxa2xx-pcm.c
@@ -69,7 +69,7 @@ static int pxa2xx_pcm_hw_free(struct snd_pcm_substream *substream)
69 return 0; 69 return 0;
70} 70}
71 71
72struct snd_pcm_ops pxa2xx_pcm_ops = { 72static struct snd_pcm_ops pxa2xx_pcm_ops = {
73 .open = __pxa2xx_pcm_open, 73 .open = __pxa2xx_pcm_open,
74 .close = __pxa2xx_pcm_close, 74 .close = __pxa2xx_pcm_close,
75 .ioctl = snd_pcm_lib_ioctl, 75 .ioctl = snd_pcm_lib_ioctl,
@@ -118,6 +118,18 @@ struct snd_soc_platform pxa2xx_soc_platform = {
118}; 118};
119EXPORT_SYMBOL_GPL(pxa2xx_soc_platform); 119EXPORT_SYMBOL_GPL(pxa2xx_soc_platform);
120 120
121static int __init pxa2xx_soc_platform_init(void)
122{
123 return snd_soc_register_platform(&pxa2xx_soc_platform);
124}
125module_init(pxa2xx_soc_platform_init);
126
127static void __exit pxa2xx_soc_platform_exit(void)
128{
129 snd_soc_unregister_platform(&pxa2xx_soc_platform);
130}
131module_exit(pxa2xx_soc_platform_exit);
132
121MODULE_AUTHOR("Nicolas Pitre"); 133MODULE_AUTHOR("Nicolas Pitre");
122MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module"); 134MODULE_DESCRIPTION("Intel PXA2xx PCM DMA module");
123MODULE_LICENSE("GPL"); 135MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index d307b6757e95..a3b9e6bdf979 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -319,8 +319,9 @@ static struct snd_soc_dai_link spitz_dai = {
319}; 319};
320 320
321/* spitz audio machine driver */ 321/* spitz audio machine driver */
322static struct snd_soc_machine snd_soc_machine_spitz = { 322static struct snd_soc_card snd_soc_spitz = {
323 .name = "Spitz", 323 .name = "Spitz",
324 .platform = &pxa2xx_soc_platform,
324 .dai_link = &spitz_dai, 325 .dai_link = &spitz_dai,
325 .num_links = 1, 326 .num_links = 1,
326}; 327};
@@ -333,8 +334,7 @@ static struct wm8750_setup_data spitz_wm8750_setup = {
333 334
334/* spitz audio subsystem */ 335/* spitz audio subsystem */
335static struct snd_soc_device spitz_snd_devdata = { 336static struct snd_soc_device spitz_snd_devdata = {
336 .machine = &snd_soc_machine_spitz, 337 .card = &snd_soc_spitz,
337 .platform = &pxa2xx_soc_platform,
338 .codec_dev = &soc_codec_dev_wm8750, 338 .codec_dev = &soc_codec_dev_wm8750,
339 .codec_data = &spitz_wm8750_setup, 339 .codec_data = &spitz_wm8750_setup,
340}; 340};
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index afefe41b8c46..c77194f74c9b 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -38,7 +38,7 @@
38#include "pxa2xx-pcm.h" 38#include "pxa2xx-pcm.h"
39#include "pxa2xx-ac97.h" 39#include "pxa2xx-ac97.h"
40 40
41static struct snd_soc_machine tosa; 41static struct snd_soc_card tosa;
42 42
43#define TOSA_HP 0 43#define TOSA_HP 0
44#define TOSA_MIC_INT 1 44#define TOSA_MIC_INT 1
@@ -230,15 +230,37 @@ static struct snd_soc_dai_link tosa_dai[] = {
230}, 230},
231}; 231};
232 232
233static struct snd_soc_machine tosa = { 233static int tosa_probe(struct platform_device *dev)
234{
235 int ret;
236
237 ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
238 if (ret)
239 return ret;
240 ret = gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
241 if (ret)
242 gpio_free(TOSA_GPIO_L_MUTE);
243
244 return ret;
245}
246
247static int tosa_remove(struct platform_device *dev)
248{
249 gpio_free(TOSA_GPIO_L_MUTE);
250 return 0;
251}
252
253static struct snd_soc_card tosa = {
234 .name = "Tosa", 254 .name = "Tosa",
255 .platform = &pxa2xx_soc_platform,
235 .dai_link = tosa_dai, 256 .dai_link = tosa_dai,
236 .num_links = ARRAY_SIZE(tosa_dai), 257 .num_links = ARRAY_SIZE(tosa_dai),
258 .probe = tosa_probe,
259 .remove = tosa_remove,
237}; 260};
238 261
239static struct snd_soc_device tosa_snd_devdata = { 262static struct snd_soc_device tosa_snd_devdata = {
240 .machine = &tosa, 263 .card = &tosa,
241 .platform = &pxa2xx_soc_platform,
242 .codec_dev = &soc_codec_dev_wm9712, 264 .codec_dev = &soc_codec_dev_wm9712,
243}; 265};
244 266
@@ -251,11 +273,6 @@ static int __init tosa_init(void)
251 if (!machine_is_tosa()) 273 if (!machine_is_tosa())
252 return -ENODEV; 274 return -ENODEV;
253 275
254 ret = gpio_request(TOSA_GPIO_L_MUTE, "Headphone Jack");
255 if (ret)
256 return ret;
257 gpio_direction_output(TOSA_GPIO_L_MUTE, 0);
258
259 tosa_snd_device = platform_device_alloc("soc-audio", -1); 276 tosa_snd_device = platform_device_alloc("soc-audio", -1);
260 if (!tosa_snd_device) { 277 if (!tosa_snd_device) {
261 ret = -ENOMEM; 278 ret = -ENOMEM;
@@ -272,15 +289,12 @@ static int __init tosa_init(void)
272 platform_device_put(tosa_snd_device); 289 platform_device_put(tosa_snd_device);
273 290
274err_alloc: 291err_alloc:
275 gpio_free(TOSA_GPIO_L_MUTE);
276
277 return ret; 292 return ret;
278} 293}
279 294
280static void __exit tosa_exit(void) 295static void __exit tosa_exit(void)
281{ 296{
282 platform_device_unregister(tosa_snd_device); 297 platform_device_unregister(tosa_snd_device);
283 gpio_free(TOSA_GPIO_L_MUTE);
284} 298}
285 299
286module_init(tosa_init); 300module_init(tosa_init);
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
new file mode 100644
index 000000000000..f8e9ecd589d3
--- /dev/null
+++ b/sound/soc/pxa/zylonite.c
@@ -0,0 +1,219 @@
1/*
2 * zylonite.c -- SoC audio for Zylonite
3 *
4 * Copyright 2008 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/device.h>
17#include <linux/i2c.h>
18#include <sound/core.h>
19#include <sound/pcm.h>
20#include <sound/pcm_params.h>
21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23
24#include "../codecs/wm9713.h"
25#include "pxa2xx-pcm.h"
26#include "pxa2xx-ac97.h"
27#include "pxa-ssp.h"
28
29static struct snd_soc_card zylonite;
30
31static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = {
32 SND_SOC_DAPM_HP("Headphone", NULL),
33 SND_SOC_DAPM_MIC("Headset Microphone", NULL),
34 SND_SOC_DAPM_MIC("Handset Microphone", NULL),
35 SND_SOC_DAPM_SPK("Multiactor", NULL),
36 SND_SOC_DAPM_SPK("Headset Earpiece", NULL),
37};
38
39/* Currently supported audio map */
40static const struct snd_soc_dapm_route audio_map[] = {
41
42 /* Headphone output connected to HPL/HPR */
43 { "Headphone", NULL, "HPL" },
44 { "Headphone", NULL, "HPR" },
45
46 /* On-board earpiece */
47 { "Headset Earpiece", NULL, "OUT3" },
48
49 /* Headphone mic */
50 { "MIC2A", NULL, "Mic Bias" },
51 { "Mic Bias", NULL, "Headset Microphone" },
52
53 /* On-board mic */
54 { "MIC1", NULL, "Mic Bias" },
55 { "Mic Bias", NULL, "Handset Microphone" },
56
57 /* Multiactor differentially connected over SPKL/SPKR */
58 { "Multiactor", NULL, "SPKL" },
59 { "Multiactor", NULL, "SPKR" },
60};
61
62static int zylonite_wm9713_init(struct snd_soc_codec *codec)
63{
64 /* Currently we only support use of the AC97 clock here. If
65 * CLK_POUT is selected by SW15 then the clock API will need
66 * to be used to request and enable it here.
67 */
68
69 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets,
70 ARRAY_SIZE(zylonite_dapm_widgets));
71
72 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
73
74 /* Static setup for now */
75 snd_soc_dapm_enable_pin(codec, "Headphone");
76 snd_soc_dapm_enable_pin(codec, "Headset Earpiece");
77
78 snd_soc_dapm_sync(codec);
79 return 0;
80}
81
82static int zylonite_voice_hw_params(struct snd_pcm_substream *substream,
83 struct snd_pcm_hw_params *params)
84{
85 struct snd_soc_pcm_runtime *rtd = substream->private_data;
86 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
87 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
88 unsigned int pll_out = 0;
89 unsigned int acds = 0;
90 unsigned int wm9713_div = 0;
91 int ret = 0;
92
93 switch (params_rate(params)) {
94 case 8000:
95 wm9713_div = 12;
96 pll_out = 2048000;
97 break;
98 case 16000:
99 wm9713_div = 6;
100 pll_out = 4096000;
101 break;
102 case 48000:
103 default:
104 wm9713_div = 2;
105 pll_out = 12288000;
106 acds = 1;
107 break;
108 }
109
110 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
111 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
112 if (ret < 0)
113 return ret;
114
115 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
116 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
117 if (ret < 0)
118 return ret;
119
120 ret = snd_soc_dai_set_tdm_slot(cpu_dai,
121 params_channels(params),
122 params_channels(params));
123 if (ret < 0)
124 return ret;
125
126 ret = snd_soc_dai_set_pll(cpu_dai, 0, 0, pll_out);
127 if (ret < 0)
128 return ret;
129
130 ret = snd_soc_dai_set_clkdiv(cpu_dai, PXA_SSP_AUDIO_DIV_ACDS, acds);
131 if (ret < 0)
132 return ret;
133
134 ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1);
135 if (ret < 0)
136 return ret;
137
138 /* Note that if the PLL is in use the WM9713_PCMCLK_PLL_DIV needs
139 * to be set instead.
140 */
141 ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV,
142 WM9713_PCMDIV(wm9713_div));
143 if (ret < 0)
144 return ret;
145
146 return 0;
147}
148
149static struct snd_soc_ops zylonite_voice_ops = {
150 .hw_params = zylonite_voice_hw_params,
151};
152
153static struct snd_soc_dai_link zylonite_dai[] = {
154{
155 .name = "AC97",
156 .stream_name = "AC97 HiFi",
157 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_HIFI],
158 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_HIFI],
159 .init = zylonite_wm9713_init,
160},
161{
162 .name = "AC97 Aux",
163 .stream_name = "AC97 Aux",
164 .cpu_dai = &pxa_ac97_dai[PXA2XX_DAI_AC97_AUX],
165 .codec_dai = &wm9713_dai[WM9713_DAI_AC97_AUX],
166},
167{
168 .name = "WM9713 Voice",
169 .stream_name = "WM9713 Voice",
170 .cpu_dai = &pxa_ssp_dai[PXA_DAI_SSP3],
171 .codec_dai = &wm9713_dai[WM9713_DAI_PCM_VOICE],
172 .ops = &zylonite_voice_ops,
173},
174};
175
176static struct snd_soc_card zylonite = {
177 .name = "Zylonite",
178 .platform = &pxa2xx_soc_platform,
179 .dai_link = zylonite_dai,
180 .num_links = ARRAY_SIZE(zylonite_dai),
181};
182
183static struct snd_soc_device zylonite_snd_ac97_devdata = {
184 .card = &zylonite,
185 .codec_dev = &soc_codec_dev_wm9713,
186};
187
188static struct platform_device *zylonite_snd_ac97_device;
189
190static int __init zylonite_init(void)
191{
192 int ret;
193
194 zylonite_snd_ac97_device = platform_device_alloc("soc-audio", -1);
195 if (!zylonite_snd_ac97_device)
196 return -ENOMEM;
197
198 platform_set_drvdata(zylonite_snd_ac97_device,
199 &zylonite_snd_ac97_devdata);
200 zylonite_snd_ac97_devdata.dev = &zylonite_snd_ac97_device->dev;
201
202 ret = platform_device_add(zylonite_snd_ac97_device);
203 if (ret != 0)
204 platform_device_put(zylonite_snd_ac97_device);
205
206 return ret;
207}
208
209static void __exit zylonite_exit(void)
210{
211 platform_device_unregister(zylonite_snd_ac97_device);
212}
213
214module_init(zylonite_init);
215module_exit(zylonite_exit);
216
217MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
218MODULE_DESCRIPTION("ALSA SoC WM9713 Zylonite");
219MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
index b9f2353effeb..fcd03acf10f6 100644
--- a/sound/soc/s3c24xx/Kconfig
+++ b/sound/soc/s3c24xx/Kconfig
@@ -44,3 +44,8 @@ config SND_S3C24XX_SOC_LN2440SBC_ALC650
44 Say Y if you want to add support for SoC audio on ln2440sbc 44 Say Y if you want to add support for SoC audio on ln2440sbc
45 with the ALC650. 45 with the ALC650.
46 46
47config SND_S3C24XX_SOC_S3C24XX_UDA134X
48 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
49 depends on SND_S3C24XX_SOC
50 select SND_S3C24XX_SOC_I2S
51 select SND_SOC_UDA134X
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
index 0aa5fb0b9700..96b3f3f617d4 100644
--- a/sound/soc/s3c24xx/Makefile
+++ b/sound/soc/s3c24xx/Makefile
@@ -13,7 +13,9 @@ obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
13snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o 13snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
14snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o 14snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
15snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o 15snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
16snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
16 17
17obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o 18obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
18obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o 19obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
19obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o 20obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
21obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c
index 4eab2c19c454..12c71482d258 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c
@@ -27,7 +27,7 @@
27#include "s3c24xx-pcm.h" 27#include "s3c24xx-pcm.h"
28#include "s3c24xx-ac97.h" 28#include "s3c24xx-ac97.h"
29 29
30static struct snd_soc_machine ln2440sbc; 30static struct snd_soc_card ln2440sbc;
31 31
32static struct snd_soc_dai_link ln2440sbc_dai[] = { 32static struct snd_soc_dai_link ln2440sbc_dai[] = {
33{ 33{
@@ -38,15 +38,15 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
38}, 38},
39}; 39};
40 40
41static struct snd_soc_machine ln2440sbc = { 41static struct snd_soc_card ln2440sbc = {
42 .name = "LN2440SBC", 42 .name = "LN2440SBC",
43 .platform = &s3c24xx_soc_platform,
43 .dai_link = ln2440sbc_dai, 44 .dai_link = ln2440sbc_dai,
44 .num_links = ARRAY_SIZE(ln2440sbc_dai), 45 .num_links = ARRAY_SIZE(ln2440sbc_dai),
45}; 46};
46 47
47static struct snd_soc_device ln2440sbc_snd_ac97_devdata = { 48static struct snd_soc_device ln2440sbc_snd_ac97_devdata = {
48 .machine = &ln2440sbc, 49 .card = &ln2440sbc,
49 .platform = &s3c24xx_soc_platform,
50 .codec_dev = &soc_codec_dev_ac97, 50 .codec_dev = &soc_codec_dev_ac97,
51}; 51};
52 52
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c
index 87ddfefcc2fb..45bb12e8ea44 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/s3c24xx/neo1973_wm8753.c
@@ -59,7 +59,7 @@
59#define NEO_CAPTURE_HEADSET 7 59#define NEO_CAPTURE_HEADSET 7
60#define NEO_CAPTURE_BLUETOOTH 8 60#define NEO_CAPTURE_BLUETOOTH 8
61 61
62static struct snd_soc_machine neo1973; 62static struct snd_soc_card neo1973;
63static struct i2c_client *i2c; 63static struct i2c_client *i2c;
64 64
65static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, 65static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream,
@@ -548,7 +548,6 @@ static int neo1973_wm8753_init(struct snd_soc_codec *codec)
548static struct snd_soc_dai bt_dai = { 548static struct snd_soc_dai bt_dai = {
549 .name = "Bluetooth", 549 .name = "Bluetooth",
550 .id = 0, 550 .id = 0,
551 .type = SND_SOC_DAI_PCM,
552 .playback = { 551 .playback = {
553 .channels_min = 1, 552 .channels_min = 1,
554 .channels_max = 1, 553 .channels_max = 1,
@@ -579,8 +578,9 @@ static struct snd_soc_dai_link neo1973_dai[] = {
579}, 578},
580}; 579};
581 580
582static struct snd_soc_machine neo1973 = { 581static struct snd_soc_card neo1973 = {
583 .name = "neo1973", 582 .name = "neo1973",
583 .platform = &s3c24xx_soc_platform,
584 .dai_link = neo1973_dai, 584 .dai_link = neo1973_dai,
585 .num_links = ARRAY_SIZE(neo1973_dai), 585 .num_links = ARRAY_SIZE(neo1973_dai),
586}; 586};
@@ -591,8 +591,7 @@ static struct wm8753_setup_data neo1973_wm8753_setup = {
591}; 591};
592 592
593static struct snd_soc_device neo1973_snd_devdata = { 593static struct snd_soc_device neo1973_snd_devdata = {
594 .machine = &neo1973, 594 .card = &neo1973,
595 .platform = &s3c24xx_soc_platform,
596 .codec_dev = &soc_codec_dev_wm8753, 595 .codec_dev = &soc_codec_dev_wm8753,
597 .codec_data = &neo1973_wm8753_setup, 596 .codec_data = &neo1973_wm8753_setup,
598}; 597};
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c
index ded7d995a922..f3fc0aba0aaf 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/s3c24xx/s3c2412-i2s.c
@@ -343,7 +343,8 @@ static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
343} 343}
344 344
345static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, 345static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
346 struct snd_pcm_hw_params *params) 346 struct snd_pcm_hw_params *params,
347 struct snd_soc_dai *dai)
347{ 348{
348 struct snd_soc_pcm_runtime *rtd = substream->private_data; 349 struct snd_soc_pcm_runtime *rtd = substream->private_data;
349 u32 iismod; 350 u32 iismod;
@@ -373,7 +374,8 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
373 return 0; 374 return 0;
374} 375}
375 376
376static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 377static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
378 struct snd_soc_dai *dai)
377{ 379{
378 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); 380 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
379 unsigned long irqs; 381 unsigned long irqs;
@@ -647,8 +649,7 @@ static int s3c2412_i2s_probe(struct platform_device *pdev,
647} 649}
648 650
649#ifdef CONFIG_PM 651#ifdef CONFIG_PM
650static int s3c2412_i2s_suspend(struct platform_device *dev, 652static int s3c2412_i2s_suspend(struct snd_soc_dai *dai)
651 struct snd_soc_dai *dai)
652{ 653{
653 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 654 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
654 u32 iismod; 655 u32 iismod;
@@ -663,25 +664,24 @@ static int s3c2412_i2s_suspend(struct platform_device *dev,
663 iismod = readl(i2s->regs + S3C2412_IISMOD); 664 iismod = readl(i2s->regs + S3C2412_IISMOD);
664 665
665 if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) 666 if (iismod & S3C2412_IISCON_RXDMA_ACTIVE)
666 dev_warn(&dev->dev, "%s: RXDMA active?\n", __func__); 667 pr_warning("%s: RXDMA active?\n", __func__);
667 668
668 if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) 669 if (iismod & S3C2412_IISCON_TXDMA_ACTIVE)
669 dev_warn(&dev->dev, "%s: TXDMA active?\n", __func__); 670 pr_warning("%s: TXDMA active?\n", __func__);
670 671
671 if (iismod & S3C2412_IISCON_IIS_ACTIVE) 672 if (iismod & S3C2412_IISCON_IIS_ACTIVE)
672 dev_warn(&dev->dev, "%s: IIS active\n", __func__); 673 pr_warning("%s: IIS active\n", __func__);
673 } 674 }
674 675
675 return 0; 676 return 0;
676} 677}
677 678
678static int s3c2412_i2s_resume(struct platform_device *pdev, 679static int s3c2412_i2s_resume(struct snd_soc_dai *dai)
679 struct snd_soc_dai *dai)
680{ 680{
681 struct s3c2412_i2s_info *i2s = &s3c2412_i2s; 681 struct s3c2412_i2s_info *i2s = &s3c2412_i2s;
682 682
683 dev_info(&pdev->dev, "dai_active %d, IISMOD %08x, IISCON %08x\n", 683 pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n",
684 dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); 684 dai->active, i2s->suspend_iismod, i2s->suspend_iiscon);
685 685
686 if (dai->active) { 686 if (dai->active) {
687 writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); 687 writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON);
@@ -711,7 +711,6 @@ static int s3c2412_i2s_resume(struct platform_device *pdev,
711struct snd_soc_dai s3c2412_i2s_dai = { 711struct snd_soc_dai s3c2412_i2s_dai = {
712 .name = "s3c2412-i2s", 712 .name = "s3c2412-i2s",
713 .id = 0, 713 .id = 0,
714 .type = SND_SOC_DAI_I2S,
715 .probe = s3c2412_i2s_probe, 714 .probe = s3c2412_i2s_probe,
716 .suspend = s3c2412_i2s_suspend, 715 .suspend = s3c2412_i2s_suspend,
717 .resume = s3c2412_i2s_resume, 716 .resume = s3c2412_i2s_resume,
@@ -730,8 +729,6 @@ struct snd_soc_dai s3c2412_i2s_dai = {
730 .ops = { 729 .ops = {
731 .trigger = s3c2412_i2s_trigger, 730 .trigger = s3c2412_i2s_trigger,
732 .hw_params = s3c2412_i2s_hw_params, 731 .hw_params = s3c2412_i2s_hw_params,
733 },
734 .dai_ops = {
735 .set_fmt = s3c2412_i2s_set_fmt, 732 .set_fmt = s3c2412_i2s_set_fmt,
736 .set_clkdiv = s3c2412_i2s_set_clkdiv, 733 .set_clkdiv = s3c2412_i2s_set_clkdiv,
737 .set_sysclk = s3c2412_i2s_set_sysclk, 734 .set_sysclk = s3c2412_i2s_set_sysclk,
@@ -739,6 +736,19 @@ struct snd_soc_dai s3c2412_i2s_dai = {
739}; 736};
740EXPORT_SYMBOL_GPL(s3c2412_i2s_dai); 737EXPORT_SYMBOL_GPL(s3c2412_i2s_dai);
741 738
739static int __init s3c2412_i2s_init(void)
740{
741 return snd_soc_register_dai(&s3c2412_i2s_dai);
742}
743module_init(s3c2412_i2s_init);
744
745static void __exit s3c2412_i2s_exit(void)
746{
747 snd_soc_unregister_dai(&s3c2412_i2s_dai);
748}
749module_exit(s3c2412_i2s_exit);
750
751
742/* Module information */ 752/* Module information */
743MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 753MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
744MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); 754MODULE_DESCRIPTION("S3C2412 I2S SoC Interface");
diff --git a/sound/soc/s3c24xx/s3c2443-ac97.c b/sound/soc/s3c24xx/s3c2443-ac97.c
index 19c5c3cf5d8c..1bfce40bb2e4 100644
--- a/sound/soc/s3c24xx/s3c2443-ac97.c
+++ b/sound/soc/s3c24xx/s3c2443-ac97.c
@@ -271,7 +271,8 @@ static void s3c2443_ac97_remove(struct platform_device *pdev,
271} 271}
272 272
273static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream, 273static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
274 struct snd_pcm_hw_params *params) 274 struct snd_pcm_hw_params *params,
275 struct snd_soc_dai *dai)
275{ 276{
276 struct snd_soc_pcm_runtime *rtd = substream->private_data; 277 struct snd_soc_pcm_runtime *rtd = substream->private_data;
277 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 278 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -284,7 +285,8 @@ static int s3c2443_ac97_hw_params(struct snd_pcm_substream *substream,
284 return 0; 285 return 0;
285} 286}
286 287
287static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd) 288static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
289 struct snd_soc_dai *dai)
288{ 290{
289 u32 ac_glbctrl; 291 u32 ac_glbctrl;
290 292
@@ -313,7 +315,8 @@ static int s3c2443_ac97_trigger(struct snd_pcm_substream *substream, int cmd)
313} 315}
314 316
315static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream, 317static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
316 struct snd_pcm_hw_params *params) 318 struct snd_pcm_hw_params *params,
319 struct snd_soc_dai *dai)
317{ 320{
318 struct snd_soc_pcm_runtime *rtd = substream->private_data; 321 struct snd_soc_pcm_runtime *rtd = substream->private_data;
319 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 322 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
@@ -327,7 +330,7 @@ static int s3c2443_ac97_hw_mic_params(struct snd_pcm_substream *substream,
327} 330}
328 331
329static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream, 332static int s3c2443_ac97_mic_trigger(struct snd_pcm_substream *substream,
330 int cmd) 333 int cmd, struct snd_soc_dai *dai)
331{ 334{
332 u32 ac_glbctrl; 335 u32 ac_glbctrl;
333 336
@@ -356,7 +359,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
356{ 359{
357 .name = "s3c2443-ac97", 360 .name = "s3c2443-ac97",
358 .id = 0, 361 .id = 0,
359 .type = SND_SOC_DAI_AC97, 362 .ac97_control = 1,
360 .probe = s3c2443_ac97_probe, 363 .probe = s3c2443_ac97_probe,
361 .remove = s3c2443_ac97_remove, 364 .remove = s3c2443_ac97_remove,
362 .playback = { 365 .playback = {
@@ -378,7 +381,7 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
378{ 381{
379 .name = "pxa2xx-ac97-mic", 382 .name = "pxa2xx-ac97-mic",
380 .id = 1, 383 .id = 1,
381 .type = SND_SOC_DAI_AC97, 384 .ac97_control = 1,
382 .capture = { 385 .capture = {
383 .stream_name = "AC97 Mic Capture", 386 .stream_name = "AC97 Mic Capture",
384 .channels_min = 1, 387 .channels_min = 1,
@@ -393,6 +396,21 @@ struct snd_soc_dai s3c2443_ac97_dai[] = {
393EXPORT_SYMBOL_GPL(s3c2443_ac97_dai); 396EXPORT_SYMBOL_GPL(s3c2443_ac97_dai);
394EXPORT_SYMBOL_GPL(soc_ac97_ops); 397EXPORT_SYMBOL_GPL(soc_ac97_ops);
395 398
399static int __init s3c2443_ac97_init(void)
400{
401 return snd_soc_register_dais(s3c2443_ac97_dai,
402 ARRAY_SIZE(s3c2443_ac97_dai));
403}
404module_init(s3c2443_ac97_init);
405
406static void __exit s3c2443_ac97_exit(void)
407{
408 snd_soc_unregister_dais(s3c2443_ac97_dai,
409 ARRAY_SIZE(s3c2443_ac97_dai));
410}
411module_exit(s3c2443_ac97_exit);
412
413
396MODULE_AUTHOR("Graeme Gregory"); 414MODULE_AUTHOR("Graeme Gregory");
397MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip"); 415MODULE_DESCRIPTION("AC97 driver for the Samsung s3c2443 chip");
398MODULE_LICENSE("GPL"); 416MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c
index ba4476b55fbc..6f4d439b57aa 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/s3c24xx/s3c24xx-i2s.c
@@ -243,7 +243,8 @@ static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
243} 243}
244 244
245static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, 245static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
246 struct snd_pcm_hw_params *params) 246 struct snd_pcm_hw_params *params,
247 struct snd_soc_dai *dai)
247{ 248{
248 struct snd_soc_pcm_runtime *rtd = substream->private_data; 249 struct snd_soc_pcm_runtime *rtd = substream->private_data;
249 u32 iismod; 250 u32 iismod;
@@ -261,10 +262,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
261 262
262 switch (params_format(params)) { 263 switch (params_format(params)) {
263 case SNDRV_PCM_FORMAT_S8: 264 case SNDRV_PCM_FORMAT_S8:
265 iismod &= ~S3C2410_IISMOD_16BIT;
266 ((struct s3c24xx_pcm_dma_params *)
267 rtd->dai->cpu_dai->dma_data)->dma_size = 1;
264 break; 268 break;
265 case SNDRV_PCM_FORMAT_S16_LE: 269 case SNDRV_PCM_FORMAT_S16_LE:
266 iismod |= S3C2410_IISMOD_16BIT; 270 iismod |= S3C2410_IISMOD_16BIT;
271 ((struct s3c24xx_pcm_dma_params *)
272 rtd->dai->cpu_dai->dma_data)->dma_size = 2;
267 break; 273 break;
274 default:
275 return -EINVAL;
268 } 276 }
269 277
270 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); 278 writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
@@ -272,7 +280,8 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
272 return 0; 280 return 0;
273} 281}
274 282
275static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd) 283static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
284 struct snd_soc_dai *dai)
276{ 285{
277 int ret = 0; 286 int ret = 0;
278 287
@@ -410,8 +419,7 @@ static int s3c24xx_i2s_probe(struct platform_device *pdev,
410} 419}
411 420
412#ifdef CONFIG_PM 421#ifdef CONFIG_PM
413static int s3c24xx_i2s_suspend(struct platform_device *pdev, 422static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai)
414 struct snd_soc_dai *cpu_dai)
415{ 423{
416 DBG("Entered %s\n", __func__); 424 DBG("Entered %s\n", __func__);
417 425
@@ -425,8 +433,7 @@ static int s3c24xx_i2s_suspend(struct platform_device *pdev,
425 return 0; 433 return 0;
426} 434}
427 435
428static int s3c24xx_i2s_resume(struct platform_device *pdev, 436static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)
429 struct snd_soc_dai *cpu_dai)
430{ 437{
431 DBG("Entered %s\n", __func__); 438 DBG("Entered %s\n", __func__);
432 clk_enable(s3c24xx_i2s.iis_clk); 439 clk_enable(s3c24xx_i2s.iis_clk);
@@ -452,7 +459,6 @@ static int s3c24xx_i2s_resume(struct platform_device *pdev,
452struct snd_soc_dai s3c24xx_i2s_dai = { 459struct snd_soc_dai s3c24xx_i2s_dai = {
453 .name = "s3c24xx-i2s", 460 .name = "s3c24xx-i2s",
454 .id = 0, 461 .id = 0,
455 .type = SND_SOC_DAI_I2S,
456 .probe = s3c24xx_i2s_probe, 462 .probe = s3c24xx_i2s_probe,
457 .suspend = s3c24xx_i2s_suspend, 463 .suspend = s3c24xx_i2s_suspend,
458 .resume = s3c24xx_i2s_resume, 464 .resume = s3c24xx_i2s_resume,
@@ -468,8 +474,7 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
468 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, 474 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,},
469 .ops = { 475 .ops = {
470 .trigger = s3c24xx_i2s_trigger, 476 .trigger = s3c24xx_i2s_trigger,
471 .hw_params = s3c24xx_i2s_hw_params,}, 477 .hw_params = s3c24xx_i2s_hw_params,
472 .dai_ops = {
473 .set_fmt = s3c24xx_i2s_set_fmt, 478 .set_fmt = s3c24xx_i2s_set_fmt,
474 .set_clkdiv = s3c24xx_i2s_set_clkdiv, 479 .set_clkdiv = s3c24xx_i2s_set_clkdiv,
475 .set_sysclk = s3c24xx_i2s_set_sysclk, 480 .set_sysclk = s3c24xx_i2s_set_sysclk,
@@ -477,6 +482,18 @@ struct snd_soc_dai s3c24xx_i2s_dai = {
477}; 482};
478EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai); 483EXPORT_SYMBOL_GPL(s3c24xx_i2s_dai);
479 484
485static int __init s3c24xx_i2s_init(void)
486{
487 return snd_soc_register_dai(&s3c24xx_i2s_dai);
488}
489module_init(s3c24xx_i2s_init);
490
491static void __exit s3c24xx_i2s_exit(void)
492{
493 snd_soc_unregister_dai(&s3c24xx_i2s_dai);
494}
495module_exit(s3c24xx_i2s_exit);
496
480/* Module information */ 497/* Module information */
481MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 498MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
482MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); 499MODULE_DESCRIPTION("s3c24xx I2S SoC Interface");
diff --git a/sound/soc/s3c24xx/s3c24xx-pcm.c b/sound/soc/s3c24xx/s3c24xx-pcm.c
index e13e614bada9..7c64d31d067e 100644
--- a/sound/soc/s3c24xx/s3c24xx-pcm.c
+++ b/sound/soc/s3c24xx/s3c24xx-pcm.c
@@ -465,6 +465,18 @@ struct snd_soc_platform s3c24xx_soc_platform = {
465}; 465};
466EXPORT_SYMBOL_GPL(s3c24xx_soc_platform); 466EXPORT_SYMBOL_GPL(s3c24xx_soc_platform);
467 467
468static int __init s3c24xx_soc_platform_init(void)
469{
470 return snd_soc_register_platform(&s3c24xx_soc_platform);
471}
472module_init(s3c24xx_soc_platform_init);
473
474static void __exit s3c24xx_soc_platform_exit(void)
475{
476 snd_soc_unregister_platform(&s3c24xx_soc_platform);
477}
478module_exit(s3c24xx_soc_platform_exit);
479
468MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 480MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
469MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module"); 481MODULE_DESCRIPTION("Samsung S3C24XX PCM DMA module");
470MODULE_LICENSE("GPL"); 482MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c
new file mode 100644
index 000000000000..a0a4d1832a14
--- /dev/null
+++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c
@@ -0,0 +1,373 @@
1/*
2 * Modifications by Christian Pellegrin <chripell@evolware.org>
3 *
4 * s3c24xx_uda134x.c -- S3C24XX_UDA134X ALSA SoC Audio board driver
5 *
6 * Copyright 2007 Dension Audio Systems Ltd.
7 * Author: Zoltan Devai
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/module.h>
15#include <linux/clk.h>
16#include <linux/mutex.h>
17#include <linux/gpio.h>
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/s3c24xx_uda134x.h>
23#include <sound/uda134x.h>
24
25#include <asm/plat-s3c24xx/regs-iis.h>
26
27#include "s3c24xx-pcm.h"
28#include "s3c24xx-i2s.h"
29#include "../codecs/uda134x.h"
30
31
32/* #define ENFORCE_RATES 1 */
33/*
34 Unfortunately the S3C24XX in master mode has a limited capacity of
35 generating the clock for the codec. If you define this only rates
36 that are really available will be enforced. But be careful, most
37 user level application just want the usual sampling frequencies (8,
38 11.025, 22.050, 44.1 kHz) and anyway resampling is a costly
39 operation for embedded systems. So if you aren't very lucky or your
40 hardware engineer wasn't very forward-looking it's better to leave
41 this undefined. If you do so an approximate value for the requested
42 sampling rate in the range -/+ 5% will be chosen. If this in not
43 possible an error will be returned.
44*/
45
46static struct clk *xtal;
47static struct clk *pclk;
48/* this is need because we don't have a place where to keep the
49 * pointers to the clocks in each substream. We get the clocks only
50 * when we are actually using them so we don't block stuff like
51 * frequency change or oscillator power-off */
52static int clk_users;
53static DEFINE_MUTEX(clk_lock);
54
55static unsigned int rates[33 * 2];
56#ifdef ENFORCE_RATES
57static struct snd_pcm_hw_constraint_list hw_constraints_rates = {
58 .count = ARRAY_SIZE(rates),
59 .list = rates,
60 .mask = 0,
61};
62#endif
63
64static struct platform_device *s3c24xx_uda134x_snd_device;
65
66static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream)
67{
68 int ret = 0;
69#ifdef ENFORCE_RATES
70 struct snd_pcm_runtime *runtime = substream->runtime;;
71#endif
72
73 mutex_lock(&clk_lock);
74 pr_debug("%s %d\n", __func__, clk_users);
75 if (clk_users == 0) {
76 xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal");
77 if (!xtal) {
78 printk(KERN_ERR "%s cannot get xtal\n", __func__);
79 ret = -EBUSY;
80 } else {
81 pclk = clk_get(&s3c24xx_uda134x_snd_device->dev,
82 "pclk");
83 if (!pclk) {
84 printk(KERN_ERR "%s cannot get pclk\n",
85 __func__);
86 clk_put(xtal);
87 ret = -EBUSY;
88 }
89 }
90 if (!ret) {
91 int i, j;
92
93 for (i = 0; i < 2; i++) {
94 int fs = i ? 256 : 384;
95
96 rates[i*33] = clk_get_rate(xtal) / fs;
97 for (j = 1; j < 33; j++)
98 rates[i*33 + j] = clk_get_rate(pclk) /
99 (j * fs);
100 }
101 }
102 }
103 clk_users += 1;
104 mutex_unlock(&clk_lock);
105 if (!ret) {
106#ifdef ENFORCE_RATES
107 ret = snd_pcm_hw_constraint_list(runtime, 0,
108 SNDRV_PCM_HW_PARAM_RATE,
109 &hw_constraints_rates);
110 if (ret < 0)
111 printk(KERN_ERR "%s cannot set constraints\n",
112 __func__);
113#endif
114 }
115 return ret;
116}
117
118static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream)
119{
120 mutex_lock(&clk_lock);
121 pr_debug("%s %d\n", __func__, clk_users);
122 clk_users -= 1;
123 if (clk_users == 0) {
124 clk_put(xtal);
125 xtal = NULL;
126 clk_put(pclk);
127 pclk = NULL;
128 }
129 mutex_unlock(&clk_lock);
130}
131
132static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream,
133 struct snd_pcm_hw_params *params)
134{
135 struct snd_soc_pcm_runtime *rtd = substream->private_data;
136 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai;
137 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
138 unsigned int clk = 0;
139 int ret = 0;
140 int clk_source, fs_mode;
141 unsigned long rate = params_rate(params);
142 long err, cerr;
143 unsigned int div;
144 int i, bi;
145
146 err = 999999;
147 bi = 0;
148 for (i = 0; i < 2*33; i++) {
149 cerr = rates[i] - rate;
150 if (cerr < 0)
151 cerr = -cerr;
152 if (cerr < err) {
153 err = cerr;
154 bi = i;
155 }
156 }
157 if (bi / 33 == 1)
158 fs_mode = S3C2410_IISMOD_256FS;
159 else
160 fs_mode = S3C2410_IISMOD_384FS;
161 if (bi % 33 == 0) {
162 clk_source = S3C24XX_CLKSRC_MPLL;
163 div = 1;
164 } else {
165 clk_source = S3C24XX_CLKSRC_PCLK;
166 div = bi % 33;
167 }
168 pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi);
169
170 clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate;
171 pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__,
172 fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS",
173 clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK",
174 div, clk, err);
175
176 if ((err * 100 / rate) > 5) {
177 printk(KERN_ERR "S3C24XX_UDA134X: effective frequency "
178 "too different from desired (%ld%%)\n",
179 err * 100 / rate);
180 return -EINVAL;
181 }
182
183 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
184 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
185 if (ret < 0)
186 return ret;
187
188 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
189 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
190 if (ret < 0)
191 return ret;
192
193 ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk,
194 SND_SOC_CLOCK_IN);
195 if (ret < 0)
196 return ret;
197
198 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, fs_mode);
199 if (ret < 0)
200 return ret;
201
202 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
203 S3C2410_IISMOD_32FS);
204 if (ret < 0)
205 return ret;
206
207 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
208 S3C24XX_PRESCALE(div, div));
209 if (ret < 0)
210 return ret;
211
212 /* set the codec system clock for DAC and ADC */
213 ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk,
214 SND_SOC_CLOCK_OUT);
215 if (ret < 0)
216 return ret;
217
218 return 0;
219}
220
221static struct snd_soc_ops s3c24xx_uda134x_ops = {
222 .startup = s3c24xx_uda134x_startup,
223 .shutdown = s3c24xx_uda134x_shutdown,
224 .hw_params = s3c24xx_uda134x_hw_params,
225};
226
227static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
228 .name = "UDA134X",
229 .stream_name = "UDA134X",
230 .codec_dai = &uda134x_dai,
231 .cpu_dai = &s3c24xx_i2s_dai,
232 .ops = &s3c24xx_uda134x_ops,
233};
234
235static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
236 .name = "S3C24XX_UDA134X",
237 .platform = &s3c24xx_soc_platform,
238 .dai_link = &s3c24xx_uda134x_dai_link,
239 .num_links = 1,
240};
241
242static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins;
243
244static void setdat(int v)
245{
246 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0);
247}
248
249static void setclk(int v)
250{
251 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0);
252}
253
254static void setmode(int v)
255{
256 gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0);
257}
258
259static struct uda134x_platform_data s3c24xx_uda134x = {
260 .l3 = {
261 .setdat = setdat,
262 .setclk = setclk,
263 .setmode = setmode,
264 .data_hold = 1,
265 .data_setup = 1,
266 .clock_high = 1,
267 .mode_hold = 1,
268 .mode = 1,
269 .mode_setup = 1,
270 },
271};
272
273static struct snd_soc_device s3c24xx_uda134x_snd_devdata = {
274 .card = &snd_soc_s3c24xx_uda134x,
275 .codec_dev = &soc_codec_dev_uda134x,
276 .codec_data = &s3c24xx_uda134x,
277};
278
279static int s3c24xx_uda134x_setup_pin(int pin, char *fun)
280{
281 if (gpio_request(pin, "s3c24xx_uda134x") < 0) {
282 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
283 "l3 %s pin already in use", fun);
284 return -EBUSY;
285 }
286 gpio_direction_output(pin, 0);
287 return 0;
288}
289
290static int s3c24xx_uda134x_probe(struct platform_device *pdev)
291{
292 int ret;
293
294 printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n");
295
296 s3c24xx_uda134x_l3_pins = pdev->dev.platform_data;
297 if (s3c24xx_uda134x_l3_pins == NULL) {
298 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
299 "unable to find platform data\n");
300 return -ENODEV;
301 }
302 s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power;
303 s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model;
304
305 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data,
306 "data") < 0)
307 return -EBUSY;
308 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk,
309 "clk") < 0) {
310 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
311 return -EBUSY;
312 }
313 if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode,
314 "mode") < 0) {
315 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
316 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
317 return -EBUSY;
318 }
319
320 s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1);
321 if (!s3c24xx_uda134x_snd_device) {
322 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: "
323 "Unable to register\n");
324 return -ENOMEM;
325 }
326
327 platform_set_drvdata(s3c24xx_uda134x_snd_device,
328 &s3c24xx_uda134x_snd_devdata);
329 s3c24xx_uda134x_snd_devdata.dev = &s3c24xx_uda134x_snd_device->dev;
330 ret = platform_device_add(s3c24xx_uda134x_snd_device);
331 if (ret) {
332 printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n");
333 platform_device_put(s3c24xx_uda134x_snd_device);
334 }
335
336 return ret;
337}
338
339static int s3c24xx_uda134x_remove(struct platform_device *pdev)
340{
341 platform_device_unregister(s3c24xx_uda134x_snd_device);
342 gpio_free(s3c24xx_uda134x_l3_pins->l3_data);
343 gpio_free(s3c24xx_uda134x_l3_pins->l3_clk);
344 gpio_free(s3c24xx_uda134x_l3_pins->l3_mode);
345 return 0;
346}
347
348static struct platform_driver s3c24xx_uda134x_driver = {
349 .probe = s3c24xx_uda134x_probe,
350 .remove = s3c24xx_uda134x_remove,
351 .driver = {
352 .name = "s3c24xx_uda134x",
353 .owner = THIS_MODULE,
354 },
355};
356
357static int __init s3c24xx_uda134x_init(void)
358{
359 return platform_driver_register(&s3c24xx_uda134x_driver);
360}
361
362static void __exit s3c24xx_uda134x_exit(void)
363{
364 platform_driver_unregister(&s3c24xx_uda134x_driver);
365}
366
367
368module_init(s3c24xx_uda134x_init);
369module_exit(s3c24xx_uda134x_exit);
370
371MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>");
372MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver");
373MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c
index 8515d6ff03f2..a2a4f5323c17 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/s3c24xx/smdk2443_wm9710.c
@@ -23,7 +23,7 @@
23#include "s3c24xx-pcm.h" 23#include "s3c24xx-pcm.h"
24#include "s3c24xx-ac97.h" 24#include "s3c24xx-ac97.h"
25 25
26static struct snd_soc_machine smdk2443; 26static struct snd_soc_card smdk2443;
27 27
28static struct snd_soc_dai_link smdk2443_dai[] = { 28static struct snd_soc_dai_link smdk2443_dai[] = {
29{ 29{
@@ -34,15 +34,15 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
34}, 34},
35}; 35};
36 36
37static struct snd_soc_machine smdk2443 = { 37static struct snd_soc_card smdk2443 = {
38 .name = "SMDK2443", 38 .name = "SMDK2443",
39 .platform = &s3c24xx_soc_platform,
39 .dai_link = smdk2443_dai, 40 .dai_link = smdk2443_dai,
40 .num_links = ARRAY_SIZE(smdk2443_dai), 41 .num_links = ARRAY_SIZE(smdk2443_dai),
41}; 42};
42 43
43static struct snd_soc_device smdk2443_snd_ac97_devdata = { 44static struct snd_soc_device smdk2443_snd_ac97_devdata = {
44 .machine = &smdk2443, 45 .card = &smdk2443,
45 .platform = &s3c24xx_soc_platform,
46 .codec_dev = &soc_codec_dev_ac97, 46 .codec_dev = &soc_codec_dev_ac97,
47}; 47};
48 48
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c
index 9faa12622d09..0dad3a0bb920 100644
--- a/sound/soc/sh/dma-sh7760.c
+++ b/sound/soc/sh/dma-sh7760.c
@@ -348,6 +348,18 @@ struct snd_soc_platform sh7760_soc_platform = {
348}; 348};
349EXPORT_SYMBOL_GPL(sh7760_soc_platform); 349EXPORT_SYMBOL_GPL(sh7760_soc_platform);
350 350
351static int __init sh7760_soc_platform_init(void)
352{
353 return snd_soc_register_platform(&sh7760_soc_platform);
354}
355module_init(sh7760_soc_platform_init);
356
357static void __exit sh7760_soc_platform_exit(void)
358{
359 snd_soc_unregister_platform(&sh7760_soc_platform);
360}
361module_exit(sh7760_soc_platform_exit);
362
351MODULE_LICENSE("GPL"); 363MODULE_LICENSE("GPL");
352MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver"); 364MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver");
353MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 365MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c
index df7bc345c320..eab31838badf 100644
--- a/sound/soc/sh/hac.c
+++ b/sound/soc/sh/hac.c
@@ -236,7 +236,8 @@ struct snd_ac97_bus_ops soc_ac97_ops = {
236EXPORT_SYMBOL_GPL(soc_ac97_ops); 236EXPORT_SYMBOL_GPL(soc_ac97_ops);
237 237
238static int hac_hw_params(struct snd_pcm_substream *substream, 238static int hac_hw_params(struct snd_pcm_substream *substream,
239 struct snd_pcm_hw_params *params) 239 struct snd_pcm_hw_params *params,
240 struct snd_soc_dai *dai)
240{ 241{
241 struct snd_soc_pcm_runtime *rtd = substream->private_data; 242 struct snd_soc_pcm_runtime *rtd = substream->private_data;
242 struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id]; 243 struct hac_priv *hac = &hac_cpu_data[rtd->dai->cpu_dai->id];
@@ -270,7 +271,7 @@ struct snd_soc_dai sh4_hac_dai[] = {
270{ 271{
271 .name = "HAC0", 272 .name = "HAC0",
272 .id = 0, 273 .id = 0,
273 .type = SND_SOC_DAI_AC97, 274 .ac97_control = 1,
274 .playback = { 275 .playback = {
275 .rates = AC97_RATES, 276 .rates = AC97_RATES,
276 .formats = AC97_FMTS, 277 .formats = AC97_FMTS,
@@ -290,8 +291,8 @@ struct snd_soc_dai sh4_hac_dai[] = {
290#ifdef CONFIG_CPU_SUBTYPE_SH7760 291#ifdef CONFIG_CPU_SUBTYPE_SH7760
291{ 292{
292 .name = "HAC1", 293 .name = "HAC1",
294 .ac97_control = 1,
293 .id = 1, 295 .id = 1,
294 .type = SND_SOC_DAI_AC97,
295 .playback = { 296 .playback = {
296 .rates = AC97_RATES, 297 .rates = AC97_RATES,
297 .formats = AC97_FMTS, 298 .formats = AC97_FMTS,
@@ -313,6 +314,18 @@ struct snd_soc_dai sh4_hac_dai[] = {
313}; 314};
314EXPORT_SYMBOL_GPL(sh4_hac_dai); 315EXPORT_SYMBOL_GPL(sh4_hac_dai);
315 316
317static int __init sh4_hac_init(void)
318{
319 return snd_soc_register_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
320}
321module_init(sh4_hac_init);
322
323static void __exit sh4_hac_exit(void)
324{
325 snd_soc_unregister_dais(sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai));
326}
327module_exit(sh4_hac_exit);
328
316MODULE_LICENSE("GPL"); 329MODULE_LICENSE("GPL");
317MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver"); 330MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver");
318MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 331MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index 92bfaf4774a7..ce7f95b59de3 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -38,15 +38,15 @@ static struct snd_soc_dai_link sh7760_ac97_dai = {
38 .ops = NULL, 38 .ops = NULL,
39}; 39};
40 40
41static struct snd_soc_machine sh7760_ac97_soc_machine = { 41static struct snd_soc_card sh7760_ac97_soc_machine = {
42 .name = "SH7760 AC97", 42 .name = "SH7760 AC97",
43 .platform = &sh7760_soc_platform,
43 .dai_link = &sh7760_ac97_dai, 44 .dai_link = &sh7760_ac97_dai,
44 .num_links = 1, 45 .num_links = 1,
45}; 46};
46 47
47static struct snd_soc_device sh7760_ac97_snd_devdata = { 48static struct snd_soc_device sh7760_ac97_snd_devdata = {
48 .machine = &sh7760_ac97_soc_machine, 49 .card = &sh7760_ac97_soc_machine,
49 .platform = &sh7760_soc_platform,
50 .codec_dev = &soc_codec_dev_ac97, 50 .codec_dev = &soc_codec_dev_ac97,
51}; 51};
52 52
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c
index 55c3464163ab..d1e5390fddeb 100644
--- a/sound/soc/sh/ssi.c
+++ b/sound/soc/sh/ssi.c
@@ -89,7 +89,8 @@ struct ssi_priv {
89 * track usage of the SSI; it is simplex-only so prevent attempts of 89 * track usage of the SSI; it is simplex-only so prevent attempts of
90 * concurrent playback + capture. FIXME: any locking required? 90 * concurrent playback + capture. FIXME: any locking required?
91 */ 91 */
92static int ssi_startup(struct snd_pcm_substream *substream) 92static int ssi_startup(struct snd_pcm_substream *substream,
93 struct snd_soc_dai *dai)
93{ 94{
94 struct snd_soc_pcm_runtime *rtd = substream->private_data; 95 struct snd_soc_pcm_runtime *rtd = substream->private_data;
95 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 96 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -101,7 +102,8 @@ static int ssi_startup(struct snd_pcm_substream *substream)
101 return 0; 102 return 0;
102} 103}
103 104
104static void ssi_shutdown(struct snd_pcm_substream *substream) 105static void ssi_shutdown(struct snd_pcm_substream *substream,
106 struct snd_soc_dai *dai)
105{ 107{
106 struct snd_soc_pcm_runtime *rtd = substream->private_data; 108 struct snd_soc_pcm_runtime *rtd = substream->private_data;
107 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 109 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -109,7 +111,8 @@ static void ssi_shutdown(struct snd_pcm_substream *substream)
109 ssi->inuse = 0; 111 ssi->inuse = 0;
110} 112}
111 113
112static int ssi_trigger(struct snd_pcm_substream *substream, int cmd) 114static int ssi_trigger(struct snd_pcm_substream *substream, int cmd,
115 struct snd_soc_dai *dai)
113{ 116{
114 struct snd_soc_pcm_runtime *rtd = substream->private_data; 117 struct snd_soc_pcm_runtime *rtd = substream->private_data;
115 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 118 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -129,7 +132,8 @@ static int ssi_trigger(struct snd_pcm_substream *substream, int cmd)
129} 132}
130 133
131static int ssi_hw_params(struct snd_pcm_substream *substream, 134static int ssi_hw_params(struct snd_pcm_substream *substream,
132 struct snd_pcm_hw_params *params) 135 struct snd_pcm_hw_params *params,
136 struct snd_soc_dai *dai)
133{ 137{
134 struct snd_soc_pcm_runtime *rtd = substream->private_data; 138 struct snd_soc_pcm_runtime *rtd = substream->private_data;
135 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id]; 139 struct ssi_priv *ssi = &ssi_cpu_data[rtd->dai->cpu_dai->id];
@@ -336,7 +340,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
336{ 340{
337 .name = "SSI0", 341 .name = "SSI0",
338 .id = 0, 342 .id = 0,
339 .type = SND_SOC_DAI_I2S,
340 .playback = { 343 .playback = {
341 .rates = SSI_RATES, 344 .rates = SSI_RATES,
342 .formats = SSI_FMTS, 345 .formats = SSI_FMTS,
@@ -354,8 +357,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
354 .shutdown = ssi_shutdown, 357 .shutdown = ssi_shutdown,
355 .trigger = ssi_trigger, 358 .trigger = ssi_trigger,
356 .hw_params = ssi_hw_params, 359 .hw_params = ssi_hw_params,
357 },
358 .dai_ops = {
359 .set_sysclk = ssi_set_sysclk, 360 .set_sysclk = ssi_set_sysclk,
360 .set_clkdiv = ssi_set_clkdiv, 361 .set_clkdiv = ssi_set_clkdiv,
361 .set_fmt = ssi_set_fmt, 362 .set_fmt = ssi_set_fmt,
@@ -365,7 +366,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
365{ 366{
366 .name = "SSI1", 367 .name = "SSI1",
367 .id = 1, 368 .id = 1,
368 .type = SND_SOC_DAI_I2S,
369 .playback = { 369 .playback = {
370 .rates = SSI_RATES, 370 .rates = SSI_RATES,
371 .formats = SSI_FMTS, 371 .formats = SSI_FMTS,
@@ -383,8 +383,6 @@ struct snd_soc_dai sh4_ssi_dai[] = {
383 .shutdown = ssi_shutdown, 383 .shutdown = ssi_shutdown,
384 .trigger = ssi_trigger, 384 .trigger = ssi_trigger,
385 .hw_params = ssi_hw_params, 385 .hw_params = ssi_hw_params,
386 },
387 .dai_ops = {
388 .set_sysclk = ssi_set_sysclk, 386 .set_sysclk = ssi_set_sysclk,
389 .set_clkdiv = ssi_set_clkdiv, 387 .set_clkdiv = ssi_set_clkdiv,
390 .set_fmt = ssi_set_fmt, 388 .set_fmt = ssi_set_fmt,
@@ -394,6 +392,18 @@ struct snd_soc_dai sh4_ssi_dai[] = {
394}; 392};
395EXPORT_SYMBOL_GPL(sh4_ssi_dai); 393EXPORT_SYMBOL_GPL(sh4_ssi_dai);
396 394
395static int __init sh4_ssi_init(void)
396{
397 return snd_soc_register_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
398}
399module_init(sh4_ssi_init);
400
401static void __exit sh4_ssi_exit(void)
402{
403 snd_soc_unregister_dais(sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai));
404}
405module_exit(sh4_ssi_exit);
406
397MODULE_LICENSE("GPL"); 407MODULE_LICENSE("GPL");
398MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver"); 408MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver");
399MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>"); 409MODULE_AUTHOR("Manuel Lauss <mano@roarinelk.homelinux.net>");
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 16c7453f4946..b098c0b4c584 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -26,6 +26,7 @@
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/pm.h> 27#include <linux/pm.h>
28#include <linux/bitops.h> 28#include <linux/bitops.h>
29#include <linux/debugfs.h>
29#include <linux/platform_device.h> 30#include <linux/platform_device.h>
30#include <sound/core.h> 31#include <sound/core.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
@@ -34,18 +35,23 @@
34#include <sound/soc-dapm.h> 35#include <sound/soc-dapm.h>
35#include <sound/initval.h> 36#include <sound/initval.h>
36 37
37/* debug */
38#define SOC_DEBUG 0
39#if SOC_DEBUG
40#define dbg(format, arg...) printk(format, ## arg)
41#else
42#define dbg(format, arg...)
43#endif
44
45static DEFINE_MUTEX(pcm_mutex); 38static DEFINE_MUTEX(pcm_mutex);
46static DEFINE_MUTEX(io_mutex); 39static DEFINE_MUTEX(io_mutex);
47static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq); 40static DECLARE_WAIT_QUEUE_HEAD(soc_pm_waitq);
48 41
42#ifdef CONFIG_DEBUG_FS
43static struct dentry *debugfs_root;
44#endif
45
46static DEFINE_MUTEX(client_mutex);
47static LIST_HEAD(card_list);
48static LIST_HEAD(dai_list);
49static LIST_HEAD(platform_list);
50static LIST_HEAD(codec_list);
51
52static int snd_soc_register_card(struct snd_soc_card *card);
53static int snd_soc_unregister_card(struct snd_soc_card *card);
54
49/* 55/*
50 * This is a timeout to do a DAPM powerdown after a stream is closed(). 56 * This is a timeout to do a DAPM powerdown after a stream is closed().
51 * It can be used to eliminate pops between different playback streams, e.g. 57 * It can be used to eliminate pops between different playback streams, e.g.
@@ -107,20 +113,6 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec)
107} 113}
108#endif 114#endif
109 115
110static inline const char *get_dai_name(int type)
111{
112 switch (type) {
113 case SND_SOC_DAI_AC97_BUS:
114 case SND_SOC_DAI_AC97:
115 return "AC97";
116 case SND_SOC_DAI_I2S:
117 return "I2S";
118 case SND_SOC_DAI_PCM:
119 return "PCM";
120 }
121 return NULL;
122}
123
124/* 116/*
125 * Called by ALSA when a PCM substream is opened, the runtime->hw record is 117 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
126 * then initialized and any private data can be allocated. This also calls 118 * then initialized and any private data can be allocated. This also calls
@@ -130,9 +122,10 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
130{ 122{
131 struct snd_soc_pcm_runtime *rtd = substream->private_data; 123 struct snd_soc_pcm_runtime *rtd = substream->private_data;
132 struct snd_soc_device *socdev = rtd->socdev; 124 struct snd_soc_device *socdev = rtd->socdev;
125 struct snd_soc_card *card = socdev->card;
133 struct snd_pcm_runtime *runtime = substream->runtime; 126 struct snd_pcm_runtime *runtime = substream->runtime;
134 struct snd_soc_dai_link *machine = rtd->dai; 127 struct snd_soc_dai_link *machine = rtd->dai;
135 struct snd_soc_platform *platform = socdev->platform; 128 struct snd_soc_platform *platform = card->platform;
136 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 129 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
137 struct snd_soc_dai *codec_dai = machine->codec_dai; 130 struct snd_soc_dai *codec_dai = machine->codec_dai;
138 int ret = 0; 131 int ret = 0;
@@ -141,7 +134,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
141 134
142 /* startup the audio subsystem */ 135 /* startup the audio subsystem */
143 if (cpu_dai->ops.startup) { 136 if (cpu_dai->ops.startup) {
144 ret = cpu_dai->ops.startup(substream); 137 ret = cpu_dai->ops.startup(substream, cpu_dai);
145 if (ret < 0) { 138 if (ret < 0) {
146 printk(KERN_ERR "asoc: can't open interface %s\n", 139 printk(KERN_ERR "asoc: can't open interface %s\n",
147 cpu_dai->name); 140 cpu_dai->name);
@@ -158,7 +151,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
158 } 151 }
159 152
160 if (codec_dai->ops.startup) { 153 if (codec_dai->ops.startup) {
161 ret = codec_dai->ops.startup(substream); 154 ret = codec_dai->ops.startup(substream, codec_dai);
162 if (ret < 0) { 155 if (ret < 0) {
163 printk(KERN_ERR "asoc: can't open codec %s\n", 156 printk(KERN_ERR "asoc: can't open codec %s\n",
164 codec_dai->name); 157 codec_dai->name);
@@ -228,12 +221,12 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
228 goto machine_err; 221 goto machine_err;
229 } 222 }
230 223
231 dbg("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); 224 pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
232 dbg("asoc: rate mask 0x%x\n", runtime->hw.rates); 225 pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates);
233 dbg("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, 226 pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min,
234 runtime->hw.channels_max); 227 runtime->hw.channels_max);
235 dbg("asoc: min rate %d max rate %d\n", runtime->hw.rate_min, 228 pr_debug("asoc: min rate %d max rate %d\n", runtime->hw.rate_min,
236 runtime->hw.rate_max); 229 runtime->hw.rate_max);
237 230
238 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 231 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
239 cpu_dai->playback.active = codec_dai->playback.active = 1; 232 cpu_dai->playback.active = codec_dai->playback.active = 1;
@@ -255,7 +248,7 @@ codec_dai_err:
255 248
256platform_err: 249platform_err:
257 if (cpu_dai->ops.shutdown) 250 if (cpu_dai->ops.shutdown)
258 cpu_dai->ops.shutdown(substream); 251 cpu_dai->ops.shutdown(substream, cpu_dai);
259out: 252out:
260 mutex_unlock(&pcm_mutex); 253 mutex_unlock(&pcm_mutex);
261 return ret; 254 return ret;
@@ -268,8 +261,9 @@ out:
268 */ 261 */
269static void close_delayed_work(struct work_struct *work) 262static void close_delayed_work(struct work_struct *work)
270{ 263{
271 struct snd_soc_device *socdev = 264 struct snd_soc_card *card = container_of(work, struct snd_soc_card,
272 container_of(work, struct snd_soc_device, delayed_work.work); 265 delayed_work.work);
266 struct snd_soc_device *socdev = card->socdev;
273 struct snd_soc_codec *codec = socdev->codec; 267 struct snd_soc_codec *codec = socdev->codec;
274 struct snd_soc_dai *codec_dai; 268 struct snd_soc_dai *codec_dai;
275 int i; 269 int i;
@@ -278,18 +272,18 @@ static void close_delayed_work(struct work_struct *work)
278 for (i = 0; i < codec->num_dai; i++) { 272 for (i = 0; i < codec->num_dai; i++) {
279 codec_dai = &codec->dai[i]; 273 codec_dai = &codec->dai[i];
280 274
281 dbg("pop wq checking: %s status: %s waiting: %s\n", 275 pr_debug("pop wq checking: %s status: %s waiting: %s\n",
282 codec_dai->playback.stream_name, 276 codec_dai->playback.stream_name,
283 codec_dai->playback.active ? "active" : "inactive", 277 codec_dai->playback.active ? "active" : "inactive",
284 codec_dai->pop_wait ? "yes" : "no"); 278 codec_dai->pop_wait ? "yes" : "no");
285 279
286 /* are we waiting on this codec DAI stream */ 280 /* are we waiting on this codec DAI stream */
287 if (codec_dai->pop_wait == 1) { 281 if (codec_dai->pop_wait == 1) {
288 282
289 /* Reduce power if no longer active */ 283 /* Reduce power if no longer active */
290 if (codec->active == 0) { 284 if (codec->active == 0) {
291 dbg("pop wq D1 %s %s\n", codec->name, 285 pr_debug("pop wq D1 %s %s\n", codec->name,
292 codec_dai->playback.stream_name); 286 codec_dai->playback.stream_name);
293 snd_soc_dapm_set_bias_level(socdev, 287 snd_soc_dapm_set_bias_level(socdev,
294 SND_SOC_BIAS_PREPARE); 288 SND_SOC_BIAS_PREPARE);
295 } 289 }
@@ -301,8 +295,8 @@ static void close_delayed_work(struct work_struct *work)
301 295
302 /* Fall into standby if no longer active */ 296 /* Fall into standby if no longer active */
303 if (codec->active == 0) { 297 if (codec->active == 0) {
304 dbg("pop wq D3 %s %s\n", codec->name, 298 pr_debug("pop wq D3 %s %s\n", codec->name,
305 codec_dai->playback.stream_name); 299 codec_dai->playback.stream_name);
306 snd_soc_dapm_set_bias_level(socdev, 300 snd_soc_dapm_set_bias_level(socdev,
307 SND_SOC_BIAS_STANDBY); 301 SND_SOC_BIAS_STANDBY);
308 } 302 }
@@ -320,8 +314,9 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
320{ 314{
321 struct snd_soc_pcm_runtime *rtd = substream->private_data; 315 struct snd_soc_pcm_runtime *rtd = substream->private_data;
322 struct snd_soc_device *socdev = rtd->socdev; 316 struct snd_soc_device *socdev = rtd->socdev;
317 struct snd_soc_card *card = socdev->card;
323 struct snd_soc_dai_link *machine = rtd->dai; 318 struct snd_soc_dai_link *machine = rtd->dai;
324 struct snd_soc_platform *platform = socdev->platform; 319 struct snd_soc_platform *platform = card->platform;
325 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 320 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
326 struct snd_soc_dai *codec_dai = machine->codec_dai; 321 struct snd_soc_dai *codec_dai = machine->codec_dai;
327 struct snd_soc_codec *codec = socdev->codec; 322 struct snd_soc_codec *codec = socdev->codec;
@@ -346,10 +341,10 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
346 snd_soc_dai_digital_mute(codec_dai, 1); 341 snd_soc_dai_digital_mute(codec_dai, 1);
347 342
348 if (cpu_dai->ops.shutdown) 343 if (cpu_dai->ops.shutdown)
349 cpu_dai->ops.shutdown(substream); 344 cpu_dai->ops.shutdown(substream, cpu_dai);
350 345
351 if (codec_dai->ops.shutdown) 346 if (codec_dai->ops.shutdown)
352 codec_dai->ops.shutdown(substream); 347 codec_dai->ops.shutdown(substream, codec_dai);
353 348
354 if (machine->ops && machine->ops->shutdown) 349 if (machine->ops && machine->ops->shutdown)
355 machine->ops->shutdown(substream); 350 machine->ops->shutdown(substream);
@@ -361,7 +356,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
361 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 356 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
362 /* start delayed pop wq here for playback streams */ 357 /* start delayed pop wq here for playback streams */
363 codec_dai->pop_wait = 1; 358 codec_dai->pop_wait = 1;
364 schedule_delayed_work(&socdev->delayed_work, 359 schedule_delayed_work(&card->delayed_work,
365 msecs_to_jiffies(pmdown_time)); 360 msecs_to_jiffies(pmdown_time));
366 } else { 361 } else {
367 /* capture streams can be powered down now */ 362 /* capture streams can be powered down now */
@@ -387,8 +382,9 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
387{ 382{
388 struct snd_soc_pcm_runtime *rtd = substream->private_data; 383 struct snd_soc_pcm_runtime *rtd = substream->private_data;
389 struct snd_soc_device *socdev = rtd->socdev; 384 struct snd_soc_device *socdev = rtd->socdev;
385 struct snd_soc_card *card = socdev->card;
390 struct snd_soc_dai_link *machine = rtd->dai; 386 struct snd_soc_dai_link *machine = rtd->dai;
391 struct snd_soc_platform *platform = socdev->platform; 387 struct snd_soc_platform *platform = card->platform;
392 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 388 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
393 struct snd_soc_dai *codec_dai = machine->codec_dai; 389 struct snd_soc_dai *codec_dai = machine->codec_dai;
394 struct snd_soc_codec *codec = socdev->codec; 390 struct snd_soc_codec *codec = socdev->codec;
@@ -413,7 +409,7 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
413 } 409 }
414 410
415 if (codec_dai->ops.prepare) { 411 if (codec_dai->ops.prepare) {
416 ret = codec_dai->ops.prepare(substream); 412 ret = codec_dai->ops.prepare(substream, codec_dai);
417 if (ret < 0) { 413 if (ret < 0) {
418 printk(KERN_ERR "asoc: codec DAI prepare error\n"); 414 printk(KERN_ERR "asoc: codec DAI prepare error\n");
419 goto out; 415 goto out;
@@ -421,58 +417,49 @@ static int soc_pcm_prepare(struct snd_pcm_substream *substream)
421 } 417 }
422 418
423 if (cpu_dai->ops.prepare) { 419 if (cpu_dai->ops.prepare) {
424 ret = cpu_dai->ops.prepare(substream); 420 ret = cpu_dai->ops.prepare(substream, cpu_dai);
425 if (ret < 0) { 421 if (ret < 0) {
426 printk(KERN_ERR "asoc: cpu DAI prepare error\n"); 422 printk(KERN_ERR "asoc: cpu DAI prepare error\n");
427 goto out; 423 goto out;
428 } 424 }
429 } 425 }
430 426
431 /* we only want to start a DAPM playback stream if we are not waiting 427 /* cancel any delayed stream shutdown that is pending */
432 * on an existing one stopping */ 428 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
433 if (codec_dai->pop_wait) { 429 codec_dai->pop_wait) {
434 /* we are waiting for the delayed work to start */ 430 codec_dai->pop_wait = 0;
435 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) 431 cancel_delayed_work(&card->delayed_work);
436 snd_soc_dapm_stream_event(socdev->codec, 432 }
437 codec_dai->capture.stream_name,
438 SND_SOC_DAPM_STREAM_START);
439 else {
440 codec_dai->pop_wait = 0;
441 cancel_delayed_work(&socdev->delayed_work);
442 snd_soc_dai_digital_mute(codec_dai, 0);
443 }
444 } else {
445 /* no delayed work - do we need to power up codec */
446 if (codec->bias_level != SND_SOC_BIAS_ON) {
447 433
448 snd_soc_dapm_set_bias_level(socdev, 434 /* do we need to power up codec */
449 SND_SOC_BIAS_PREPARE); 435 if (codec->bias_level != SND_SOC_BIAS_ON) {
436 snd_soc_dapm_set_bias_level(socdev,
437 SND_SOC_BIAS_PREPARE);
450 438
451 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 439 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
452 snd_soc_dapm_stream_event(codec, 440 snd_soc_dapm_stream_event(codec,
453 codec_dai->playback.stream_name, 441 codec_dai->playback.stream_name,
454 SND_SOC_DAPM_STREAM_START); 442 SND_SOC_DAPM_STREAM_START);
455 else 443 else
456 snd_soc_dapm_stream_event(codec, 444 snd_soc_dapm_stream_event(codec,
457 codec_dai->capture.stream_name, 445 codec_dai->capture.stream_name,
458 SND_SOC_DAPM_STREAM_START); 446 SND_SOC_DAPM_STREAM_START);
459 447
460 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON); 448 snd_soc_dapm_set_bias_level(socdev, SND_SOC_BIAS_ON);
461 snd_soc_dai_digital_mute(codec_dai, 0); 449 snd_soc_dai_digital_mute(codec_dai, 0);
462 450
463 } else { 451 } else {
464 /* codec already powered - power on widgets */ 452 /* codec already powered - power on widgets */
465 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 453 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
466 snd_soc_dapm_stream_event(codec, 454 snd_soc_dapm_stream_event(codec,
467 codec_dai->playback.stream_name, 455 codec_dai->playback.stream_name,
468 SND_SOC_DAPM_STREAM_START); 456 SND_SOC_DAPM_STREAM_START);
469 else 457 else
470 snd_soc_dapm_stream_event(codec, 458 snd_soc_dapm_stream_event(codec,
471 codec_dai->capture.stream_name, 459 codec_dai->capture.stream_name,
472 SND_SOC_DAPM_STREAM_START); 460 SND_SOC_DAPM_STREAM_START);
473 461
474 snd_soc_dai_digital_mute(codec_dai, 0); 462 snd_soc_dai_digital_mute(codec_dai, 0);
475 }
476 } 463 }
477 464
478out: 465out:
@@ -491,7 +478,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
491 struct snd_soc_pcm_runtime *rtd = substream->private_data; 478 struct snd_soc_pcm_runtime *rtd = substream->private_data;
492 struct snd_soc_device *socdev = rtd->socdev; 479 struct snd_soc_device *socdev = rtd->socdev;
493 struct snd_soc_dai_link *machine = rtd->dai; 480 struct snd_soc_dai_link *machine = rtd->dai;
494 struct snd_soc_platform *platform = socdev->platform; 481 struct snd_soc_card *card = socdev->card;
482 struct snd_soc_platform *platform = card->platform;
495 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 483 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
496 struct snd_soc_dai *codec_dai = machine->codec_dai; 484 struct snd_soc_dai *codec_dai = machine->codec_dai;
497 int ret = 0; 485 int ret = 0;
@@ -507,7 +495,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
507 } 495 }
508 496
509 if (codec_dai->ops.hw_params) { 497 if (codec_dai->ops.hw_params) {
510 ret = codec_dai->ops.hw_params(substream, params); 498 ret = codec_dai->ops.hw_params(substream, params, codec_dai);
511 if (ret < 0) { 499 if (ret < 0) {
512 printk(KERN_ERR "asoc: can't set codec %s hw params\n", 500 printk(KERN_ERR "asoc: can't set codec %s hw params\n",
513 codec_dai->name); 501 codec_dai->name);
@@ -516,7 +504,7 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
516 } 504 }
517 505
518 if (cpu_dai->ops.hw_params) { 506 if (cpu_dai->ops.hw_params) {
519 ret = cpu_dai->ops.hw_params(substream, params); 507 ret = cpu_dai->ops.hw_params(substream, params, cpu_dai);
520 if (ret < 0) { 508 if (ret < 0) {
521 printk(KERN_ERR "asoc: interface %s hw params failed\n", 509 printk(KERN_ERR "asoc: interface %s hw params failed\n",
522 cpu_dai->name); 510 cpu_dai->name);
@@ -539,11 +527,11 @@ out:
539 527
540platform_err: 528platform_err:
541 if (cpu_dai->ops.hw_free) 529 if (cpu_dai->ops.hw_free)
542 cpu_dai->ops.hw_free(substream); 530 cpu_dai->ops.hw_free(substream, cpu_dai);
543 531
544interface_err: 532interface_err:
545 if (codec_dai->ops.hw_free) 533 if (codec_dai->ops.hw_free)
546 codec_dai->ops.hw_free(substream); 534 codec_dai->ops.hw_free(substream, codec_dai);
547 535
548codec_err: 536codec_err:
549 if (machine->ops && machine->ops->hw_free) 537 if (machine->ops && machine->ops->hw_free)
@@ -561,7 +549,8 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
561 struct snd_soc_pcm_runtime *rtd = substream->private_data; 549 struct snd_soc_pcm_runtime *rtd = substream->private_data;
562 struct snd_soc_device *socdev = rtd->socdev; 550 struct snd_soc_device *socdev = rtd->socdev;
563 struct snd_soc_dai_link *machine = rtd->dai; 551 struct snd_soc_dai_link *machine = rtd->dai;
564 struct snd_soc_platform *platform = socdev->platform; 552 struct snd_soc_card *card = socdev->card;
553 struct snd_soc_platform *platform = card->platform;
565 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 554 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
566 struct snd_soc_dai *codec_dai = machine->codec_dai; 555 struct snd_soc_dai *codec_dai = machine->codec_dai;
567 struct snd_soc_codec *codec = socdev->codec; 556 struct snd_soc_codec *codec = socdev->codec;
@@ -582,10 +571,10 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
582 571
583 /* now free hw params for the DAI's */ 572 /* now free hw params for the DAI's */
584 if (codec_dai->ops.hw_free) 573 if (codec_dai->ops.hw_free)
585 codec_dai->ops.hw_free(substream); 574 codec_dai->ops.hw_free(substream, codec_dai);
586 575
587 if (cpu_dai->ops.hw_free) 576 if (cpu_dai->ops.hw_free)
588 cpu_dai->ops.hw_free(substream); 577 cpu_dai->ops.hw_free(substream, cpu_dai);
589 578
590 mutex_unlock(&pcm_mutex); 579 mutex_unlock(&pcm_mutex);
591 return 0; 580 return 0;
@@ -595,14 +584,15 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
595{ 584{
596 struct snd_soc_pcm_runtime *rtd = substream->private_data; 585 struct snd_soc_pcm_runtime *rtd = substream->private_data;
597 struct snd_soc_device *socdev = rtd->socdev; 586 struct snd_soc_device *socdev = rtd->socdev;
587 struct snd_soc_card *card= socdev->card;
598 struct snd_soc_dai_link *machine = rtd->dai; 588 struct snd_soc_dai_link *machine = rtd->dai;
599 struct snd_soc_platform *platform = socdev->platform; 589 struct snd_soc_platform *platform = card->platform;
600 struct snd_soc_dai *cpu_dai = machine->cpu_dai; 590 struct snd_soc_dai *cpu_dai = machine->cpu_dai;
601 struct snd_soc_dai *codec_dai = machine->codec_dai; 591 struct snd_soc_dai *codec_dai = machine->codec_dai;
602 int ret; 592 int ret;
603 593
604 if (codec_dai->ops.trigger) { 594 if (codec_dai->ops.trigger) {
605 ret = codec_dai->ops.trigger(substream, cmd); 595 ret = codec_dai->ops.trigger(substream, cmd, codec_dai);
606 if (ret < 0) 596 if (ret < 0)
607 return ret; 597 return ret;
608 } 598 }
@@ -614,7 +604,7 @@ static int soc_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
614 } 604 }
615 605
616 if (cpu_dai->ops.trigger) { 606 if (cpu_dai->ops.trigger) {
617 ret = cpu_dai->ops.trigger(substream, cmd); 607 ret = cpu_dai->ops.trigger(substream, cmd, cpu_dai);
618 if (ret < 0) 608 if (ret < 0)
619 return ret; 609 return ret;
620 } 610 }
@@ -636,8 +626,8 @@ static struct snd_pcm_ops soc_pcm_ops = {
636static int soc_suspend(struct platform_device *pdev, pm_message_t state) 626static int soc_suspend(struct platform_device *pdev, pm_message_t state)
637{ 627{
638 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 628 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
639 struct snd_soc_machine *machine = socdev->machine; 629 struct snd_soc_card *card = socdev->card;
640 struct snd_soc_platform *platform = socdev->platform; 630 struct snd_soc_platform *platform = card->platform;
641 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 631 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
642 struct snd_soc_codec *codec = socdev->codec; 632 struct snd_soc_codec *codec = socdev->codec;
643 int i; 633 int i;
@@ -653,29 +643,29 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
653 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D3hot); 643 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D3hot);
654 644
655 /* mute any active DAC's */ 645 /* mute any active DAC's */
656 for (i = 0; i < machine->num_links; i++) { 646 for (i = 0; i < card->num_links; i++) {
657 struct snd_soc_dai *dai = machine->dai_link[i].codec_dai; 647 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
658 if (dai->dai_ops.digital_mute && dai->playback.active) 648 if (dai->ops.digital_mute && dai->playback.active)
659 dai->dai_ops.digital_mute(dai, 1); 649 dai->ops.digital_mute(dai, 1);
660 } 650 }
661 651
662 /* suspend all pcms */ 652 /* suspend all pcms */
663 for (i = 0; i < machine->num_links; i++) 653 for (i = 0; i < card->num_links; i++)
664 snd_pcm_suspend_all(machine->dai_link[i].pcm); 654 snd_pcm_suspend_all(card->dai_link[i].pcm);
665 655
666 if (machine->suspend_pre) 656 if (card->suspend_pre)
667 machine->suspend_pre(pdev, state); 657 card->suspend_pre(pdev, state);
668 658
669 for (i = 0; i < machine->num_links; i++) { 659 for (i = 0; i < card->num_links; i++) {
670 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 660 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
671 if (cpu_dai->suspend && cpu_dai->type != SND_SOC_DAI_AC97) 661 if (cpu_dai->suspend && !cpu_dai->ac97_control)
672 cpu_dai->suspend(pdev, cpu_dai); 662 cpu_dai->suspend(cpu_dai);
673 if (platform->suspend) 663 if (platform->suspend)
674 platform->suspend(pdev, cpu_dai); 664 platform->suspend(cpu_dai);
675 } 665 }
676 666
677 /* close any waiting streams and save state */ 667 /* close any waiting streams and save state */
678 run_delayed_work(&socdev->delayed_work); 668 run_delayed_work(&card->delayed_work);
679 codec->suspend_bias_level = codec->bias_level; 669 codec->suspend_bias_level = codec->bias_level;
680 670
681 for (i = 0; i < codec->num_dai; i++) { 671 for (i = 0; i < codec->num_dai; i++) {
@@ -692,14 +682,14 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
692 if (codec_dev->suspend) 682 if (codec_dev->suspend)
693 codec_dev->suspend(pdev, state); 683 codec_dev->suspend(pdev, state);
694 684
695 for (i = 0; i < machine->num_links; i++) { 685 for (i = 0; i < card->num_links; i++) {
696 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 686 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
697 if (cpu_dai->suspend && cpu_dai->type == SND_SOC_DAI_AC97) 687 if (cpu_dai->suspend && cpu_dai->ac97_control)
698 cpu_dai->suspend(pdev, cpu_dai); 688 cpu_dai->suspend(cpu_dai);
699 } 689 }
700 690
701 if (machine->suspend_post) 691 if (card->suspend_post)
702 machine->suspend_post(pdev, state); 692 card->suspend_post(pdev, state);
703 693
704 return 0; 694 return 0;
705} 695}
@@ -709,11 +699,11 @@ static int soc_suspend(struct platform_device *pdev, pm_message_t state)
709 */ 699 */
710static void soc_resume_deferred(struct work_struct *work) 700static void soc_resume_deferred(struct work_struct *work)
711{ 701{
712 struct snd_soc_device *socdev = container_of(work, 702 struct snd_soc_card *card = container_of(work,
713 struct snd_soc_device, 703 struct snd_soc_card,
714 deferred_resume_work); 704 deferred_resume_work);
715 struct snd_soc_machine *machine = socdev->machine; 705 struct snd_soc_device *socdev = card->socdev;
716 struct snd_soc_platform *platform = socdev->platform; 706 struct snd_soc_platform *platform = card->platform;
717 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 707 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
718 struct snd_soc_codec *codec = socdev->codec; 708 struct snd_soc_codec *codec = socdev->codec;
719 struct platform_device *pdev = to_platform_device(socdev->dev); 709 struct platform_device *pdev = to_platform_device(socdev->dev);
@@ -723,15 +713,15 @@ static void soc_resume_deferred(struct work_struct *work)
723 * so userspace apps are blocked from touching us 713 * so userspace apps are blocked from touching us
724 */ 714 */
725 715
726 dev_info(socdev->dev, "starting resume work\n"); 716 dev_dbg(socdev->dev, "starting resume work\n");
727 717
728 if (machine->resume_pre) 718 if (card->resume_pre)
729 machine->resume_pre(pdev); 719 card->resume_pre(pdev);
730 720
731 for (i = 0; i < machine->num_links; i++) { 721 for (i = 0; i < card->num_links; i++) {
732 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 722 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
733 if (cpu_dai->resume && cpu_dai->type == SND_SOC_DAI_AC97) 723 if (cpu_dai->resume && cpu_dai->ac97_control)
734 cpu_dai->resume(pdev, cpu_dai); 724 cpu_dai->resume(cpu_dai);
735 } 725 }
736 726
737 if (codec_dev->resume) 727 if (codec_dev->resume)
@@ -749,24 +739,24 @@ static void soc_resume_deferred(struct work_struct *work)
749 } 739 }
750 740
751 /* unmute any active DACs */ 741 /* unmute any active DACs */
752 for (i = 0; i < machine->num_links; i++) { 742 for (i = 0; i < card->num_links; i++) {
753 struct snd_soc_dai *dai = machine->dai_link[i].codec_dai; 743 struct snd_soc_dai *dai = card->dai_link[i].codec_dai;
754 if (dai->dai_ops.digital_mute && dai->playback.active) 744 if (dai->ops.digital_mute && dai->playback.active)
755 dai->dai_ops.digital_mute(dai, 0); 745 dai->ops.digital_mute(dai, 0);
756 } 746 }
757 747
758 for (i = 0; i < machine->num_links; i++) { 748 for (i = 0; i < card->num_links; i++) {
759 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 749 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
760 if (cpu_dai->resume && cpu_dai->type != SND_SOC_DAI_AC97) 750 if (cpu_dai->resume && !cpu_dai->ac97_control)
761 cpu_dai->resume(pdev, cpu_dai); 751 cpu_dai->resume(cpu_dai);
762 if (platform->resume) 752 if (platform->resume)
763 platform->resume(pdev, cpu_dai); 753 platform->resume(cpu_dai);
764 } 754 }
765 755
766 if (machine->resume_post) 756 if (card->resume_post)
767 machine->resume_post(pdev); 757 card->resume_post(pdev);
768 758
769 dev_info(socdev->dev, "resume work completed\n"); 759 dev_dbg(socdev->dev, "resume work completed\n");
770 760
771 /* userspace can access us now we are back as we were before */ 761 /* userspace can access us now we are back as we were before */
772 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D0); 762 snd_power_change_state(codec->card, SNDRV_CTL_POWER_D0);
@@ -776,11 +766,12 @@ static void soc_resume_deferred(struct work_struct *work)
776static int soc_resume(struct platform_device *pdev) 766static int soc_resume(struct platform_device *pdev)
777{ 767{
778 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 768 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
769 struct snd_soc_card *card = socdev->card;
779 770
780 dev_info(socdev->dev, "scheduling resume work\n"); 771 dev_dbg(socdev->dev, "scheduling resume work\n");
781 772
782 if (!schedule_work(&socdev->deferred_resume_work)) 773 if (!schedule_work(&card->deferred_resume_work))
783 dev_err(socdev->dev, "work item may be lost\n"); 774 dev_err(socdev->dev, "resume work item may be lost\n");
784 775
785 return 0; 776 return 0;
786} 777}
@@ -790,23 +781,83 @@ static int soc_resume(struct platform_device *pdev)
790#define soc_resume NULL 781#define soc_resume NULL
791#endif 782#endif
792 783
793/* probes a new socdev */ 784static void snd_soc_instantiate_card(struct snd_soc_card *card)
794static int soc_probe(struct platform_device *pdev)
795{ 785{
796 int ret = 0, i; 786 struct platform_device *pdev = container_of(card->dev,
797 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 787 struct platform_device,
798 struct snd_soc_machine *machine = socdev->machine; 788 dev);
799 struct snd_soc_platform *platform = socdev->platform; 789 struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
800 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 790 struct snd_soc_platform *platform;
791 struct snd_soc_dai *dai;
792 int i, found, ret, ac97;
793
794 if (card->instantiated)
795 return;
796
797 found = 0;
798 list_for_each_entry(platform, &platform_list, list)
799 if (card->platform == platform) {
800 found = 1;
801 break;
802 }
803 if (!found) {
804 dev_dbg(card->dev, "Platform %s not registered\n",
805 card->platform->name);
806 return;
807 }
808
809 ac97 = 0;
810 for (i = 0; i < card->num_links; i++) {
811 found = 0;
812 list_for_each_entry(dai, &dai_list, list)
813 if (card->dai_link[i].cpu_dai == dai) {
814 found = 1;
815 break;
816 }
817 if (!found) {
818 dev_dbg(card->dev, "DAI %s not registered\n",
819 card->dai_link[i].cpu_dai->name);
820 return;
821 }
801 822
802 if (machine->probe) { 823 if (card->dai_link[i].cpu_dai->ac97_control)
803 ret = machine->probe(pdev); 824 ac97 = 1;
825 }
826
827 /* If we have AC97 in the system then don't wait for the
828 * codec. This will need revisiting if we have to handle
829 * systems with mixed AC97 and non-AC97 parts. Only check for
830 * DAIs currently; we can't do this per link since some AC97
831 * codecs have non-AC97 DAIs.
832 */
833 if (!ac97)
834 for (i = 0; i < card->num_links; i++) {
835 found = 0;
836 list_for_each_entry(dai, &dai_list, list)
837 if (card->dai_link[i].codec_dai == dai) {
838 found = 1;
839 break;
840 }
841 if (!found) {
842 dev_dbg(card->dev, "DAI %s not registered\n",
843 card->dai_link[i].codec_dai->name);
844 return;
845 }
846 }
847
848 /* Note that we do not current check for codec components */
849
850 dev_dbg(card->dev, "All components present, instantiating\n");
851
852 /* Found everything, bring it up */
853 if (card->probe) {
854 ret = card->probe(pdev);
804 if (ret < 0) 855 if (ret < 0)
805 return ret; 856 return;
806 } 857 }
807 858
808 for (i = 0; i < machine->num_links; i++) { 859 for (i = 0; i < card->num_links; i++) {
809 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 860 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
810 if (cpu_dai->probe) { 861 if (cpu_dai->probe) {
811 ret = cpu_dai->probe(pdev, cpu_dai); 862 ret = cpu_dai->probe(pdev, cpu_dai);
812 if (ret < 0) 863 if (ret < 0)
@@ -827,13 +878,15 @@ static int soc_probe(struct platform_device *pdev)
827 } 878 }
828 879
829 /* DAPM stream work */ 880 /* DAPM stream work */
830 INIT_DELAYED_WORK(&socdev->delayed_work, close_delayed_work); 881 INIT_DELAYED_WORK(&card->delayed_work, close_delayed_work);
831#ifdef CONFIG_PM 882#ifdef CONFIG_PM
832 /* deferred resume work */ 883 /* deferred resume work */
833 INIT_WORK(&socdev->deferred_resume_work, soc_resume_deferred); 884 INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
834#endif 885#endif
835 886
836 return 0; 887 card->instantiated = 1;
888
889 return;
837 890
838platform_err: 891platform_err:
839 if (codec_dev->remove) 892 if (codec_dev->remove)
@@ -841,15 +894,45 @@ platform_err:
841 894
842cpu_dai_err: 895cpu_dai_err:
843 for (i--; i >= 0; i--) { 896 for (i--; i >= 0; i--) {
844 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 897 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
845 if (cpu_dai->remove) 898 if (cpu_dai->remove)
846 cpu_dai->remove(pdev, cpu_dai); 899 cpu_dai->remove(pdev, cpu_dai);
847 } 900 }
848 901
849 if (machine->remove) 902 if (card->remove)
850 machine->remove(pdev); 903 card->remove(pdev);
904}
851 905
852 return ret; 906/*
907 * Attempt to initialise any uninitalised cards. Must be called with
908 * client_mutex.
909 */
910static void snd_soc_instantiate_cards(void)
911{
912 struct snd_soc_card *card;
913 list_for_each_entry(card, &card_list, list)
914 snd_soc_instantiate_card(card);
915}
916
917/* probes a new socdev */
918static int soc_probe(struct platform_device *pdev)
919{
920 int ret = 0;
921 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
922 struct snd_soc_card *card = socdev->card;
923
924 /* Bodge while we push things out of socdev */
925 card->socdev = socdev;
926
927 /* Bodge while we unpick instantiation */
928 card->dev = &pdev->dev;
929 ret = snd_soc_register_card(card);
930 if (ret != 0) {
931 dev_err(&pdev->dev, "Failed to register card\n");
932 return ret;
933 }
934
935 return 0;
853} 936}
854 937
855/* removes a socdev */ 938/* removes a socdev */
@@ -857,11 +940,11 @@ static int soc_remove(struct platform_device *pdev)
857{ 940{
858 int i; 941 int i;
859 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 942 struct snd_soc_device *socdev = platform_get_drvdata(pdev);
860 struct snd_soc_machine *machine = socdev->machine; 943 struct snd_soc_card *card = socdev->card;
861 struct snd_soc_platform *platform = socdev->platform; 944 struct snd_soc_platform *platform = card->platform;
862 struct snd_soc_codec_device *codec_dev = socdev->codec_dev; 945 struct snd_soc_codec_device *codec_dev = socdev->codec_dev;
863 946
864 run_delayed_work(&socdev->delayed_work); 947 run_delayed_work(&card->delayed_work);
865 948
866 if (platform->remove) 949 if (platform->remove)
867 platform->remove(pdev); 950 platform->remove(pdev);
@@ -869,14 +952,16 @@ static int soc_remove(struct platform_device *pdev)
869 if (codec_dev->remove) 952 if (codec_dev->remove)
870 codec_dev->remove(pdev); 953 codec_dev->remove(pdev);
871 954
872 for (i = 0; i < machine->num_links; i++) { 955 for (i = 0; i < card->num_links; i++) {
873 struct snd_soc_dai *cpu_dai = machine->dai_link[i].cpu_dai; 956 struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
874 if (cpu_dai->remove) 957 if (cpu_dai->remove)
875 cpu_dai->remove(pdev, cpu_dai); 958 cpu_dai->remove(pdev, cpu_dai);
876 } 959 }
877 960
878 if (machine->remove) 961 if (card->remove)
879 machine->remove(pdev); 962 card->remove(pdev);
963
964 snd_soc_unregister_card(card);
880 965
881 return 0; 966 return 0;
882} 967}
@@ -898,6 +983,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
898 struct snd_soc_dai_link *dai_link, int num) 983 struct snd_soc_dai_link *dai_link, int num)
899{ 984{
900 struct snd_soc_codec *codec = socdev->codec; 985 struct snd_soc_codec *codec = socdev->codec;
986 struct snd_soc_card *card = socdev->card;
987 struct snd_soc_platform *platform = card->platform;
901 struct snd_soc_dai *codec_dai = dai_link->codec_dai; 988 struct snd_soc_dai *codec_dai = dai_link->codec_dai;
902 struct snd_soc_dai *cpu_dai = dai_link->cpu_dai; 989 struct snd_soc_dai *cpu_dai = dai_link->cpu_dai;
903 struct snd_soc_pcm_runtime *rtd; 990 struct snd_soc_pcm_runtime *rtd;
@@ -914,8 +1001,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
914 codec_dai->codec = socdev->codec; 1001 codec_dai->codec = socdev->codec;
915 1002
916 /* check client and interface hw capabilities */ 1003 /* check client and interface hw capabilities */
917 sprintf(new_name, "%s %s-%s-%d", dai_link->stream_name, codec_dai->name, 1004 sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name,
918 get_dai_name(cpu_dai->type), num); 1005 num);
919 1006
920 if (codec_dai->playback.channels_min) 1007 if (codec_dai->playback.channels_min)
921 playback = 1; 1008 playback = 1;
@@ -933,13 +1020,13 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
933 1020
934 dai_link->pcm = pcm; 1021 dai_link->pcm = pcm;
935 pcm->private_data = rtd; 1022 pcm->private_data = rtd;
936 soc_pcm_ops.mmap = socdev->platform->pcm_ops->mmap; 1023 soc_pcm_ops.mmap = platform->pcm_ops->mmap;
937 soc_pcm_ops.pointer = socdev->platform->pcm_ops->pointer; 1024 soc_pcm_ops.pointer = platform->pcm_ops->pointer;
938 soc_pcm_ops.ioctl = socdev->platform->pcm_ops->ioctl; 1025 soc_pcm_ops.ioctl = platform->pcm_ops->ioctl;
939 soc_pcm_ops.copy = socdev->platform->pcm_ops->copy; 1026 soc_pcm_ops.copy = platform->pcm_ops->copy;
940 soc_pcm_ops.silence = socdev->platform->pcm_ops->silence; 1027 soc_pcm_ops.silence = platform->pcm_ops->silence;
941 soc_pcm_ops.ack = socdev->platform->pcm_ops->ack; 1028 soc_pcm_ops.ack = platform->pcm_ops->ack;
942 soc_pcm_ops.page = socdev->platform->pcm_ops->page; 1029 soc_pcm_ops.page = platform->pcm_ops->page;
943 1030
944 if (playback) 1031 if (playback)
945 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops); 1032 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
@@ -947,24 +1034,22 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
947 if (capture) 1034 if (capture)
948 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops); 1035 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
949 1036
950 ret = socdev->platform->pcm_new(codec->card, codec_dai, pcm); 1037 ret = platform->pcm_new(codec->card, codec_dai, pcm);
951 if (ret < 0) { 1038 if (ret < 0) {
952 printk(KERN_ERR "asoc: platform pcm constructor failed\n"); 1039 printk(KERN_ERR "asoc: platform pcm constructor failed\n");
953 kfree(rtd); 1040 kfree(rtd);
954 return ret; 1041 return ret;
955 } 1042 }
956 1043
957 pcm->private_free = socdev->platform->pcm_free; 1044 pcm->private_free = platform->pcm_free;
958 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 1045 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name,
959 cpu_dai->name); 1046 cpu_dai->name);
960 return ret; 1047 return ret;
961} 1048}
962 1049
963/* codec register dump */ 1050/* codec register dump */
964static ssize_t codec_reg_show(struct device *dev, 1051static ssize_t soc_codec_reg_show(struct snd_soc_device *devdata, char *buf)
965 struct device_attribute *attr, char *buf)
966{ 1052{
967 struct snd_soc_device *devdata = dev_get_drvdata(dev);
968 struct snd_soc_codec *codec = devdata->codec; 1053 struct snd_soc_codec *codec = devdata->codec;
969 int i, step = 1, count = 0; 1054 int i, step = 1, count = 0;
970 1055
@@ -1001,8 +1086,110 @@ static ssize_t codec_reg_show(struct device *dev,
1001 1086
1002 return count; 1087 return count;
1003} 1088}
1089static ssize_t codec_reg_show(struct device *dev,
1090 struct device_attribute *attr, char *buf)
1091{
1092 struct snd_soc_device *devdata = dev_get_drvdata(dev);
1093 return soc_codec_reg_show(devdata, buf);
1094}
1095
1004static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL); 1096static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
1005 1097
1098#ifdef CONFIG_DEBUG_FS
1099static int codec_reg_open_file(struct inode *inode, struct file *file)
1100{
1101 file->private_data = inode->i_private;
1102 return 0;
1103}
1104
1105static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
1106 size_t count, loff_t *ppos)
1107{
1108 ssize_t ret;
1109 struct snd_soc_codec *codec = file->private_data;
1110 struct device *card_dev = codec->card->dev;
1111 struct snd_soc_device *devdata = card_dev->driver_data;
1112 char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
1113 if (!buf)
1114 return -ENOMEM;
1115 ret = soc_codec_reg_show(devdata, buf);
1116 if (ret >= 0)
1117 ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
1118 kfree(buf);
1119 return ret;
1120}
1121
1122static ssize_t codec_reg_write_file(struct file *file,
1123 const char __user *user_buf, size_t count, loff_t *ppos)
1124{
1125 char buf[32];
1126 int buf_size;
1127 char *start = buf;
1128 unsigned long reg, value;
1129 int step = 1;
1130 struct snd_soc_codec *codec = file->private_data;
1131
1132 buf_size = min(count, (sizeof(buf)-1));
1133 if (copy_from_user(buf, user_buf, buf_size))
1134 return -EFAULT;
1135 buf[buf_size] = 0;
1136
1137 if (codec->reg_cache_step)
1138 step = codec->reg_cache_step;
1139
1140 while (*start == ' ')
1141 start++;
1142 reg = simple_strtoul(start, &start, 16);
1143 if ((reg >= codec->reg_cache_size) || (reg % step))
1144 return -EINVAL;
1145 while (*start == ' ')
1146 start++;
1147 if (strict_strtoul(start, 16, &value))
1148 return -EINVAL;
1149 codec->write(codec, reg, value);
1150 return buf_size;
1151}
1152
1153static const struct file_operations codec_reg_fops = {
1154 .open = codec_reg_open_file,
1155 .read = codec_reg_read_file,
1156 .write = codec_reg_write_file,
1157};
1158
1159static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1160{
1161 codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
1162 debugfs_root, codec,
1163 &codec_reg_fops);
1164 if (!codec->debugfs_reg)
1165 printk(KERN_WARNING
1166 "ASoC: Failed to create codec register debugfs file\n");
1167
1168 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
1169 debugfs_root,
1170 &codec->pop_time);
1171 if (!codec->debugfs_pop_time)
1172 printk(KERN_WARNING
1173 "Failed to create pop time debugfs file\n");
1174}
1175
1176static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1177{
1178 debugfs_remove(codec->debugfs_pop_time);
1179 debugfs_remove(codec->debugfs_reg);
1180}
1181
1182#else
1183
1184static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
1185{
1186}
1187
1188static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
1189{
1190}
1191#endif
1192
1006/** 1193/**
1007 * snd_soc_new_ac97_codec - initailise AC97 device 1194 * snd_soc_new_ac97_codec - initailise AC97 device
1008 * @codec: audio codec 1195 * @codec: audio codec
@@ -1121,7 +1308,7 @@ EXPORT_SYMBOL_GPL(snd_soc_test_bits);
1121int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) 1308int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1122{ 1309{
1123 struct snd_soc_codec *codec = socdev->codec; 1310 struct snd_soc_codec *codec = socdev->codec;
1124 struct snd_soc_machine *machine = socdev->machine; 1311 struct snd_soc_card *card = socdev->card;
1125 int ret = 0, i; 1312 int ret = 0, i;
1126 1313
1127 mutex_lock(&codec->mutex); 1314 mutex_lock(&codec->mutex);
@@ -1140,11 +1327,11 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1140 strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver)); 1327 strncpy(codec->card->driver, codec->name, sizeof(codec->card->driver));
1141 1328
1142 /* create the pcms */ 1329 /* create the pcms */
1143 for (i = 0; i < machine->num_links; i++) { 1330 for (i = 0; i < card->num_links; i++) {
1144 ret = soc_new_pcm(socdev, &machine->dai_link[i], i); 1331 ret = soc_new_pcm(socdev, &card->dai_link[i], i);
1145 if (ret < 0) { 1332 if (ret < 0) {
1146 printk(KERN_ERR "asoc: can't create pcm %s\n", 1333 printk(KERN_ERR "asoc: can't create pcm %s\n",
1147 machine->dai_link[i].stream_name); 1334 card->dai_link[i].stream_name);
1148 mutex_unlock(&codec->mutex); 1335 mutex_unlock(&codec->mutex);
1149 return ret; 1336 return ret;
1150 } 1337 }
@@ -1156,7 +1343,7 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
1156EXPORT_SYMBOL_GPL(snd_soc_new_pcms); 1343EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1157 1344
1158/** 1345/**
1159 * snd_soc_register_card - register sound card 1346 * snd_soc_init_card - register sound card
1160 * @socdev: the SoC audio device 1347 * @socdev: the SoC audio device
1161 * 1348 *
1162 * Register a SoC sound card. Also registers an AC97 device if the 1349 * Register a SoC sound card. Also registers an AC97 device if the
@@ -1164,29 +1351,28 @@ EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
1164 * 1351 *
1165 * Returns 0 for success, else error. 1352 * Returns 0 for success, else error.
1166 */ 1353 */
1167int snd_soc_register_card(struct snd_soc_device *socdev) 1354int snd_soc_init_card(struct snd_soc_device *socdev)
1168{ 1355{
1169 struct snd_soc_codec *codec = socdev->codec; 1356 struct snd_soc_codec *codec = socdev->codec;
1170 struct snd_soc_machine *machine = socdev->machine; 1357 struct snd_soc_card *card = socdev->card;
1171 int ret = 0, i, ac97 = 0, err = 0; 1358 int ret = 0, i, ac97 = 0, err = 0;
1172 1359
1173 for (i = 0; i < machine->num_links; i++) { 1360 for (i = 0; i < card->num_links; i++) {
1174 if (socdev->machine->dai_link[i].init) { 1361 if (card->dai_link[i].init) {
1175 err = socdev->machine->dai_link[i].init(codec); 1362 err = card->dai_link[i].init(codec);
1176 if (err < 0) { 1363 if (err < 0) {
1177 printk(KERN_ERR "asoc: failed to init %s\n", 1364 printk(KERN_ERR "asoc: failed to init %s\n",
1178 socdev->machine->dai_link[i].stream_name); 1365 card->dai_link[i].stream_name);
1179 continue; 1366 continue;
1180 } 1367 }
1181 } 1368 }
1182 if (socdev->machine->dai_link[i].codec_dai->type == 1369 if (card->dai_link[i].codec_dai->ac97_control)
1183 SND_SOC_DAI_AC97_BUS)
1184 ac97 = 1; 1370 ac97 = 1;
1185 } 1371 }
1186 snprintf(codec->card->shortname, sizeof(codec->card->shortname), 1372 snprintf(codec->card->shortname, sizeof(codec->card->shortname),
1187 "%s", machine->name); 1373 "%s", card->name);
1188 snprintf(codec->card->longname, sizeof(codec->card->longname), 1374 snprintf(codec->card->longname, sizeof(codec->card->longname),
1189 "%s (%s)", machine->name, codec->name); 1375 "%s (%s)", card->name, codec->name);
1190 1376
1191 ret = snd_card_register(codec->card); 1377 ret = snd_card_register(codec->card);
1192 if (ret < 0) { 1378 if (ret < 0) {
@@ -1216,12 +1402,13 @@ int snd_soc_register_card(struct snd_soc_device *socdev)
1216 if (err < 0) 1402 if (err < 0)
1217 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); 1403 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1218 1404
1405 soc_init_codec_debugfs(socdev->codec);
1219 mutex_unlock(&codec->mutex); 1406 mutex_unlock(&codec->mutex);
1220 1407
1221out: 1408out:
1222 return ret; 1409 return ret;
1223} 1410}
1224EXPORT_SYMBOL_GPL(snd_soc_register_card); 1411EXPORT_SYMBOL_GPL(snd_soc_init_card);
1225 1412
1226/** 1413/**
1227 * snd_soc_free_pcms - free sound card and pcms 1414 * snd_soc_free_pcms - free sound card and pcms
@@ -1239,10 +1426,11 @@ void snd_soc_free_pcms(struct snd_soc_device *socdev)
1239#endif 1426#endif
1240 1427
1241 mutex_lock(&codec->mutex); 1428 mutex_lock(&codec->mutex);
1429 soc_cleanup_codec_debugfs(socdev->codec);
1242#ifdef CONFIG_SND_SOC_AC97_BUS 1430#ifdef CONFIG_SND_SOC_AC97_BUS
1243 for (i = 0; i < codec->num_dai; i++) { 1431 for (i = 0; i < codec->num_dai; i++) {
1244 codec_dai = &codec->dai[i]; 1432 codec_dai = &codec->dai[i];
1245 if (codec_dai->type == SND_SOC_DAI_AC97_BUS && codec->ac97) { 1433 if (codec_dai->ac97_control && codec->ac97) {
1246 soc_ac97_dev_unregister(codec); 1434 soc_ac97_dev_unregister(codec);
1247 goto free_card; 1435 goto free_card;
1248 } 1436 }
@@ -1756,8 +1944,8 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
1756int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, 1944int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id,
1757 unsigned int freq, int dir) 1945 unsigned int freq, int dir)
1758{ 1946{
1759 if (dai->dai_ops.set_sysclk) 1947 if (dai->ops.set_sysclk)
1760 return dai->dai_ops.set_sysclk(dai, clk_id, freq, dir); 1948 return dai->ops.set_sysclk(dai, clk_id, freq, dir);
1761 else 1949 else
1762 return -EINVAL; 1950 return -EINVAL;
1763} 1951}
@@ -1776,8 +1964,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk);
1776int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, 1964int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai,
1777 int div_id, int div) 1965 int div_id, int div)
1778{ 1966{
1779 if (dai->dai_ops.set_clkdiv) 1967 if (dai->ops.set_clkdiv)
1780 return dai->dai_ops.set_clkdiv(dai, div_id, div); 1968 return dai->ops.set_clkdiv(dai, div_id, div);
1781 else 1969 else
1782 return -EINVAL; 1970 return -EINVAL;
1783} 1971}
@@ -1795,8 +1983,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv);
1795int snd_soc_dai_set_pll(struct snd_soc_dai *dai, 1983int snd_soc_dai_set_pll(struct snd_soc_dai *dai,
1796 int pll_id, unsigned int freq_in, unsigned int freq_out) 1984 int pll_id, unsigned int freq_in, unsigned int freq_out)
1797{ 1985{
1798 if (dai->dai_ops.set_pll) 1986 if (dai->ops.set_pll)
1799 return dai->dai_ops.set_pll(dai, pll_id, freq_in, freq_out); 1987 return dai->ops.set_pll(dai, pll_id, freq_in, freq_out);
1800 else 1988 else
1801 return -EINVAL; 1989 return -EINVAL;
1802} 1990}
@@ -1805,15 +1993,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll);
1805/** 1993/**
1806 * snd_soc_dai_set_fmt - configure DAI hardware audio format. 1994 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
1807 * @dai: DAI 1995 * @dai: DAI
1808 * @clk_id: DAI specific clock ID
1809 * @fmt: SND_SOC_DAIFMT_ format value. 1996 * @fmt: SND_SOC_DAIFMT_ format value.
1810 * 1997 *
1811 * Configures the DAI hardware format and clocking. 1998 * Configures the DAI hardware format and clocking.
1812 */ 1999 */
1813int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 2000int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
1814{ 2001{
1815 if (dai->dai_ops.set_fmt) 2002 if (dai->ops.set_fmt)
1816 return dai->dai_ops.set_fmt(dai, fmt); 2003 return dai->ops.set_fmt(dai, fmt);
1817 else 2004 else
1818 return -EINVAL; 2005 return -EINVAL;
1819} 2006}
@@ -1831,8 +2018,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt);
1831int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, 2018int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai,
1832 unsigned int mask, int slots) 2019 unsigned int mask, int slots)
1833{ 2020{
1834 if (dai->dai_ops.set_sysclk) 2021 if (dai->ops.set_sysclk)
1835 return dai->dai_ops.set_tdm_slot(dai, mask, slots); 2022 return dai->ops.set_tdm_slot(dai, mask, slots);
1836 else 2023 else
1837 return -EINVAL; 2024 return -EINVAL;
1838} 2025}
@@ -1847,8 +2034,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot);
1847 */ 2034 */
1848int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate) 2035int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate)
1849{ 2036{
1850 if (dai->dai_ops.set_sysclk) 2037 if (dai->ops.set_sysclk)
1851 return dai->dai_ops.set_tristate(dai, tristate); 2038 return dai->ops.set_tristate(dai, tristate);
1852 else 2039 else
1853 return -EINVAL; 2040 return -EINVAL;
1854} 2041}
@@ -1863,21 +2050,242 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate);
1863 */ 2050 */
1864int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute) 2051int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute)
1865{ 2052{
1866 if (dai->dai_ops.digital_mute) 2053 if (dai->ops.digital_mute)
1867 return dai->dai_ops.digital_mute(dai, mute); 2054 return dai->ops.digital_mute(dai, mute);
1868 else 2055 else
1869 return -EINVAL; 2056 return -EINVAL;
1870} 2057}
1871EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute); 2058EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
1872 2059
1873static int __devinit snd_soc_init(void) 2060/**
2061 * snd_soc_register_card - Register a card with the ASoC core
2062 *
2063 * @param card Card to register
2064 *
2065 * Note that currently this is an internal only function: it will be
2066 * exposed to machine drivers after further backporting of ASoC v2
2067 * registration APIs.
2068 */
2069static int snd_soc_register_card(struct snd_soc_card *card)
2070{
2071 if (!card->name || !card->dev)
2072 return -EINVAL;
2073
2074 INIT_LIST_HEAD(&card->list);
2075 card->instantiated = 0;
2076
2077 mutex_lock(&client_mutex);
2078 list_add(&card->list, &card_list);
2079 snd_soc_instantiate_cards();
2080 mutex_unlock(&client_mutex);
2081
2082 dev_dbg(card->dev, "Registered card '%s'\n", card->name);
2083
2084 return 0;
2085}
2086
2087/**
2088 * snd_soc_unregister_card - Unregister a card with the ASoC core
2089 *
2090 * @param card Card to unregister
2091 *
2092 * Note that currently this is an internal only function: it will be
2093 * exposed to machine drivers after further backporting of ASoC v2
2094 * registration APIs.
2095 */
2096static int snd_soc_unregister_card(struct snd_soc_card *card)
2097{
2098 mutex_lock(&client_mutex);
2099 list_del(&card->list);
2100 mutex_unlock(&client_mutex);
2101
2102 dev_dbg(card->dev, "Unregistered card '%s'\n", card->name);
2103
2104 return 0;
2105}
2106
2107/**
2108 * snd_soc_register_dai - Register a DAI with the ASoC core
2109 *
2110 * @param dai DAI to register
2111 */
2112int snd_soc_register_dai(struct snd_soc_dai *dai)
2113{
2114 if (!dai->name)
2115 return -EINVAL;
2116
2117 /* The device should become mandatory over time */
2118 if (!dai->dev)
2119 printk(KERN_WARNING "No device for DAI %s\n", dai->name);
2120
2121 INIT_LIST_HEAD(&dai->list);
2122
2123 mutex_lock(&client_mutex);
2124 list_add(&dai->list, &dai_list);
2125 snd_soc_instantiate_cards();
2126 mutex_unlock(&client_mutex);
2127
2128 pr_debug("Registered DAI '%s'\n", dai->name);
2129
2130 return 0;
2131}
2132EXPORT_SYMBOL_GPL(snd_soc_register_dai);
2133
2134/**
2135 * snd_soc_unregister_dai - Unregister a DAI from the ASoC core
2136 *
2137 * @param dai DAI to unregister
2138 */
2139void snd_soc_unregister_dai(struct snd_soc_dai *dai)
2140{
2141 mutex_lock(&client_mutex);
2142 list_del(&dai->list);
2143 mutex_unlock(&client_mutex);
2144
2145 pr_debug("Unregistered DAI '%s'\n", dai->name);
2146}
2147EXPORT_SYMBOL_GPL(snd_soc_unregister_dai);
2148
2149/**
2150 * snd_soc_register_dais - Register multiple DAIs with the ASoC core
2151 *
2152 * @param dai Array of DAIs to register
2153 * @param count Number of DAIs
2154 */
2155int snd_soc_register_dais(struct snd_soc_dai *dai, size_t count)
2156{
2157 int i, ret;
2158
2159 for (i = 0; i < count; i++) {
2160 ret = snd_soc_register_dai(&dai[i]);
2161 if (ret != 0)
2162 goto err;
2163 }
2164
2165 return 0;
2166
2167err:
2168 for (i--; i >= 0; i--)
2169 snd_soc_unregister_dai(&dai[i]);
2170
2171 return ret;
2172}
2173EXPORT_SYMBOL_GPL(snd_soc_register_dais);
2174
2175/**
2176 * snd_soc_unregister_dais - Unregister multiple DAIs from the ASoC core
2177 *
2178 * @param dai Array of DAIs to unregister
2179 * @param count Number of DAIs
2180 */
2181void snd_soc_unregister_dais(struct snd_soc_dai *dai, size_t count)
2182{
2183 int i;
2184
2185 for (i = 0; i < count; i++)
2186 snd_soc_unregister_dai(&dai[i]);
2187}
2188EXPORT_SYMBOL_GPL(snd_soc_unregister_dais);
2189
2190/**
2191 * snd_soc_register_platform - Register a platform with the ASoC core
2192 *
2193 * @param platform platform to register
2194 */
2195int snd_soc_register_platform(struct snd_soc_platform *platform)
2196{
2197 if (!platform->name)
2198 return -EINVAL;
2199
2200 INIT_LIST_HEAD(&platform->list);
2201
2202 mutex_lock(&client_mutex);
2203 list_add(&platform->list, &platform_list);
2204 snd_soc_instantiate_cards();
2205 mutex_unlock(&client_mutex);
2206
2207 pr_debug("Registered platform '%s'\n", platform->name);
2208
2209 return 0;
2210}
2211EXPORT_SYMBOL_GPL(snd_soc_register_platform);
2212
2213/**
2214 * snd_soc_unregister_platform - Unregister a platform from the ASoC core
2215 *
2216 * @param platform platform to unregister
2217 */
2218void snd_soc_unregister_platform(struct snd_soc_platform *platform)
1874{ 2219{
1875 printk(KERN_INFO "ASoC version %s\n", SND_SOC_VERSION); 2220 mutex_lock(&client_mutex);
2221 list_del(&platform->list);
2222 mutex_unlock(&client_mutex);
2223
2224 pr_debug("Unregistered platform '%s'\n", platform->name);
2225}
2226EXPORT_SYMBOL_GPL(snd_soc_unregister_platform);
2227
2228/**
2229 * snd_soc_register_codec - Register a codec with the ASoC core
2230 *
2231 * @param codec codec to register
2232 */
2233int snd_soc_register_codec(struct snd_soc_codec *codec)
2234{
2235 if (!codec->name)
2236 return -EINVAL;
2237
2238 /* The device should become mandatory over time */
2239 if (!codec->dev)
2240 printk(KERN_WARNING "No device for codec %s\n", codec->name);
2241
2242 INIT_LIST_HEAD(&codec->list);
2243
2244 mutex_lock(&client_mutex);
2245 list_add(&codec->list, &codec_list);
2246 snd_soc_instantiate_cards();
2247 mutex_unlock(&client_mutex);
2248
2249 pr_debug("Registered codec '%s'\n", codec->name);
2250
2251 return 0;
2252}
2253EXPORT_SYMBOL_GPL(snd_soc_register_codec);
2254
2255/**
2256 * snd_soc_unregister_codec - Unregister a codec from the ASoC core
2257 *
2258 * @param codec codec to unregister
2259 */
2260void snd_soc_unregister_codec(struct snd_soc_codec *codec)
2261{
2262 mutex_lock(&client_mutex);
2263 list_del(&codec->list);
2264 mutex_unlock(&client_mutex);
2265
2266 pr_debug("Unregistered codec '%s'\n", codec->name);
2267}
2268EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
2269
2270static int __init snd_soc_init(void)
2271{
2272#ifdef CONFIG_DEBUG_FS
2273 debugfs_root = debugfs_create_dir("asoc", NULL);
2274 if (IS_ERR(debugfs_root) || !debugfs_root) {
2275 printk(KERN_WARNING
2276 "ASoC: Failed to create debugfs directory\n");
2277 debugfs_root = NULL;
2278 }
2279#endif
2280
1876 return platform_driver_register(&soc_driver); 2281 return platform_driver_register(&soc_driver);
1877} 2282}
1878 2283
1879static void snd_soc_exit(void) 2284static void __exit snd_soc_exit(void)
1880{ 2285{
2286#ifdef CONFIG_DEBUG_FS
2287 debugfs_remove_recursive(debugfs_root);
2288#endif
1881 platform_driver_unregister(&soc_driver); 2289 platform_driver_unregister(&soc_driver);
1882} 2290}
1883 2291
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 7351db9606e4..8863eddbac02 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -37,7 +37,6 @@
37#include <linux/bitops.h> 37#include <linux/bitops.h>
38#include <linux/platform_device.h> 38#include <linux/platform_device.h>
39#include <linux/jiffies.h> 39#include <linux/jiffies.h>
40#include <linux/debugfs.h>
41#include <sound/core.h> 40#include <sound/core.h>
42#include <sound/pcm.h> 41#include <sound/pcm.h>
43#include <sound/pcm_params.h> 42#include <sound/pcm_params.h>
@@ -67,17 +66,13 @@ static int dapm_status = 1;
67module_param(dapm_status, int, 0); 66module_param(dapm_status, int, 0);
68MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries"); 67MODULE_PARM_DESC(dapm_status, "enable DPM sysfs entries");
69 68
70static struct dentry *asoc_debugfs; 69static void pop_wait(u32 pop_time)
71
72static u32 pop_time;
73
74static void pop_wait(void)
75{ 70{
76 if (pop_time) 71 if (pop_time)
77 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); 72 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
78} 73}
79 74
80static void pop_dbg(const char *fmt, ...) 75static void pop_dbg(u32 pop_time, const char *fmt, ...)
81{ 76{
82 va_list args; 77 va_list args;
83 78
@@ -85,7 +80,7 @@ static void pop_dbg(const char *fmt, ...)
85 80
86 if (pop_time) { 81 if (pop_time) {
87 vprintk(fmt, args); 82 vprintk(fmt, args);
88 pop_wait(); 83 pop_wait(pop_time);
89 } 84 }
90 85
91 va_end(args); 86 va_end(args);
@@ -230,10 +225,11 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
230 225
231 change = old != new; 226 change = old != new;
232 if (change) { 227 if (change) {
233 pop_dbg("pop test %s : %s in %d ms\n", widget->name, 228 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n",
234 widget->power ? "on" : "off", pop_time); 229 widget->name, widget->power ? "on" : "off",
230 codec->pop_time);
235 snd_soc_write(codec, widget->reg, new); 231 snd_soc_write(codec, widget->reg, new);
236 pop_wait(); 232 pop_wait(codec->pop_time);
237 } 233 }
238 pr_debug("reg %x old %x new %x change %d\n", widget->reg, 234 pr_debug("reg %x old %x new %x change %d\n", widget->reg,
239 old, new, change); 235 old, new, change);
@@ -293,7 +289,7 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
293 struct snd_soc_dapm_widget *w) 289 struct snd_soc_dapm_widget *w)
294{ 290{
295 int i, ret = 0; 291 int i, ret = 0;
296 char name[32]; 292 size_t name_len;
297 struct snd_soc_dapm_path *path; 293 struct snd_soc_dapm_path *path;
298 294
299 /* add kcontrol */ 295 /* add kcontrol */
@@ -307,11 +303,16 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
307 continue; 303 continue;
308 304
309 /* add dapm control with long name */ 305 /* add dapm control with long name */
310 snprintf(name, 32, "%s %s", w->name, w->kcontrols[i].name); 306 name_len = 2 + strlen(w->name)
311 path->long_name = kstrdup (name, GFP_KERNEL); 307 + strlen(w->kcontrols[i].name);
308 path->long_name = kmalloc(name_len, GFP_KERNEL);
312 if (path->long_name == NULL) 309 if (path->long_name == NULL)
313 return -ENOMEM; 310 return -ENOMEM;
314 311
312 snprintf(path->long_name, name_len, "%s %s",
313 w->name, w->kcontrols[i].name);
314 path->long_name[name_len - 1] = '\0';
315
315 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 316 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
316 path->long_name); 317 path->long_name);
317 ret = snd_ctl_add(codec->card, path->kcontrol); 318 ret = snd_ctl_add(codec->card, path->kcontrol);
@@ -821,23 +822,9 @@ static DEVICE_ATTR(dapm_widget, 0444, dapm_widget_show, NULL);
821 822
822int snd_soc_dapm_sys_add(struct device *dev) 823int snd_soc_dapm_sys_add(struct device *dev)
823{ 824{
824 int ret = 0;
825
826 if (!dapm_status) 825 if (!dapm_status)
827 return 0; 826 return 0;
828 827 return device_create_file(dev, &dev_attr_dapm_widget);
829 ret = device_create_file(dev, &dev_attr_dapm_widget);
830 if (ret != 0)
831 return ret;
832
833 asoc_debugfs = debugfs_create_dir("asoc", NULL);
834 if (!IS_ERR(asoc_debugfs) && asoc_debugfs)
835 debugfs_create_u32("dapm_pop_time", 0744, asoc_debugfs,
836 &pop_time);
837 else
838 asoc_debugfs = NULL;
839
840 return 0;
841} 828}
842 829
843static void snd_soc_dapm_sys_remove(struct device *dev) 830static void snd_soc_dapm_sys_remove(struct device *dev)
@@ -845,9 +832,6 @@ static void snd_soc_dapm_sys_remove(struct device *dev)
845 if (dapm_status) { 832 if (dapm_status) {
846 device_remove_file(dev, &dev_attr_dapm_widget); 833 device_remove_file(dev, &dev_attr_dapm_widget);
847 } 834 }
848
849 if (asoc_debugfs)
850 debugfs_remove_recursive(asoc_debugfs);
851} 835}
852 836
853/* free all dapm widgets and resources */ 837/* free all dapm widgets and resources */
@@ -1007,28 +991,6 @@ err:
1007} 991}
1008 992
1009/** 993/**
1010 * snd_soc_dapm_connect_input - connect dapm widgets
1011 * @codec: audio codec
1012 * @sink: name of target widget
1013 * @control: mixer control name
1014 * @source: name of source name
1015 *
1016 * Connects 2 dapm widgets together via a named audio path. The sink is
1017 * the widget receiving the audio signal, whilst the source is the sender
1018 * of the audio signal.
1019 *
1020 * This function has been deprecated in favour of snd_soc_dapm_add_routes().
1021 *
1022 * Returns 0 for success else error.
1023 */
1024int snd_soc_dapm_connect_input(struct snd_soc_codec *codec, const char *sink,
1025 const char *control, const char *source)
1026{
1027 return snd_soc_dapm_add_route(codec, sink, control, source);
1028}
1029EXPORT_SYMBOL_GPL(snd_soc_dapm_connect_input);
1030
1031/**
1032 * snd_soc_dapm_add_routes - Add routes between DAPM widgets 994 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
1033 * @codec: codec 995 * @codec: codec
1034 * @route: audio routes 996 * @route: audio routes
@@ -1358,8 +1320,12 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
1358 1320
1359 for (i = 0; i < num; i++) { 1321 for (i = 0; i < num; i++) {
1360 ret = snd_soc_dapm_new_control(codec, widget); 1322 ret = snd_soc_dapm_new_control(codec, widget);
1361 if (ret < 0) 1323 if (ret < 0) {
1324 printk(KERN_ERR
1325 "ASoC: Failed to create DAPM control %s: %d\n",
1326 widget->name, ret);
1362 return ret; 1327 return ret;
1328 }
1363 widget++; 1329 widget++;
1364 } 1330 }
1365 return 0; 1331 return 0;
@@ -1440,11 +1406,11 @@ int snd_soc_dapm_set_bias_level(struct snd_soc_device *socdev,
1440 enum snd_soc_bias_level level) 1406 enum snd_soc_bias_level level)
1441{ 1407{
1442 struct snd_soc_codec *codec = socdev->codec; 1408 struct snd_soc_codec *codec = socdev->codec;
1443 struct snd_soc_machine *machine = socdev->machine; 1409 struct snd_soc_card *card = socdev->card;
1444 int ret = 0; 1410 int ret = 0;
1445 1411
1446 if (machine->set_bias_level) 1412 if (card->set_bias_level)
1447 ret = machine->set_bias_level(machine, level); 1413 ret = card->set_bias_level(card, level);
1448 if (ret == 0 && codec->set_bias_level) 1414 if (ret == 0 && codec->set_bias_level)
1449 ret = codec->set_bias_level(codec, level); 1415 ret = codec->set_bias_level(codec, level);
1450 1416
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 10ba4218161b..2b302bbffe73 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -10,6 +10,7 @@
10#include <linux/module.h> 10#include <linux/module.h>
11#include <linux/device.h> 11#include <linux/device.h>
12#include <linux/err.h> 12#include <linux/err.h>
13#include <sound/core.h>
13 14
14#ifdef CONFIG_SOUND_OSS_CORE 15#ifdef CONFIG_SOUND_OSS_CORE
15static int __init init_oss_soundcore(void); 16static int __init init_oss_soundcore(void);
diff --git a/sound/usb/caiaq/caiaq-control.c b/sound/usb/caiaq/caiaq-control.c
index 798ca124da58..ccd763dd7167 100644
--- a/sound/usb/caiaq/caiaq-control.c
+++ b/sound/usb/caiaq/caiaq-control.c
@@ -247,69 +247,56 @@ static struct caiaq_controller a8dj_controller[] = {
247 { "Software lock", 40 } 247 { "Software lock", 40 }
248}; 248};
249 249
250int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev) 250static int __devinit add_controls(struct caiaq_controller *c, int num,
251 struct snd_usb_caiaqdev *dev)
251{ 252{
252 int i; 253 int i, ret;
253 struct snd_kcontrol *kc; 254 struct snd_kcontrol *kc;
254 255
256 for (i = 0; i < num; i++, c++) {
257 kcontrol_template.name = c->name;
258 kcontrol_template.private_value = c->index;
259 kc = snd_ctl_new1(&kcontrol_template, dev);
260 ret = snd_ctl_add(dev->chip.card, kc);
261 if (ret < 0)
262 return ret;
263 }
264
265 return 0;
266}
267
268int __devinit snd_usb_caiaq_control_init(struct snd_usb_caiaqdev *dev)
269{
270 int ret = 0;
271
255 switch (dev->chip.usb_id) { 272 switch (dev->chip.usb_id) {
256 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1): 273 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
257 for (i = 0; i < ARRAY_SIZE(ak1_controller); i++) { 274 ret = add_controls(ak1_controller,
258 struct caiaq_controller *c = ak1_controller + i; 275 ARRAY_SIZE(ak1_controller), dev);
259 kcontrol_template.name = c->name;
260 kcontrol_template.private_value = c->index;
261 kc = snd_ctl_new1(&kcontrol_template, dev);
262 snd_ctl_add(dev->chip.card, kc);
263 }
264
265 break; 276 break;
266 277
267 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2): 278 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL2):
268 for (i = 0; i < ARRAY_SIZE(rk2_controller); i++) { 279 ret = add_controls(rk2_controller,
269 struct caiaq_controller *c = rk2_controller + i; 280 ARRAY_SIZE(rk2_controller), dev);
270 kcontrol_template.name = c->name;
271 kcontrol_template.private_value = c->index;
272 kc = snd_ctl_new1(&kcontrol_template, dev);
273 snd_ctl_add(dev->chip.card, kc);
274 }
275
276 break; 281 break;
277 282
278 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3): 283 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
279 for (i = 0; i < ARRAY_SIZE(rk3_controller); i++) { 284 ret = add_controls(rk3_controller,
280 struct caiaq_controller *c = rk3_controller + i; 285 ARRAY_SIZE(rk3_controller), dev);
281 kcontrol_template.name = c->name;
282 kcontrol_template.private_value = c->index;
283 kc = snd_ctl_new1(&kcontrol_template, dev);
284 snd_ctl_add(dev->chip.card, kc);
285 }
286
287 break; 286 break;
288 287
289 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER): 288 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
290 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2): 289 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
291 for (i = 0; i < ARRAY_SIZE(kore_controller); i++) { 290 ret = add_controls(kore_controller,
292 struct caiaq_controller *c = kore_controller + i; 291 ARRAY_SIZE(kore_controller), dev);
293 kcontrol_template.name = c->name;
294 kcontrol_template.private_value = c->index;
295 kc = snd_ctl_new1(&kcontrol_template, dev);
296 snd_ctl_add(dev->chip.card, kc);
297 }
298
299 break; 292 break;
300 293
301 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ): 294 case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AUDIO8DJ):
302 for (i = 0; i < ARRAY_SIZE(a8dj_controller); i++) { 295 ret = add_controls(a8dj_controller,
303 struct caiaq_controller *c = a8dj_controller + i; 296 ARRAY_SIZE(a8dj_controller), dev);
304 kcontrol_template.name = c->name;
305 kcontrol_template.private_value = c->index;
306 kc = snd_ctl_new1(&kcontrol_template, dev);
307 snd_ctl_add(dev->chip.card, kc);
308 }
309
310 break; 297 break;
311 } 298 }
312 299
313 return 0; 300 return ret;
314} 301}
315 302
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
index 83175083e50f..b143ef7152f7 100644
--- a/sound/usb/caiaq/caiaq-device.c
+++ b/sound/usb/caiaq/caiaq-device.c
@@ -42,7 +42,7 @@
42#endif 42#endif
43 43
44MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 44MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
45MODULE_DESCRIPTION("caiaq USB audio, version 1.3.8"); 45MODULE_DESCRIPTION("caiaq USB audio, version 1.3.9");
46MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
47MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2}," 47MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
48 "{Native Instruments, RigKontrol3}," 48 "{Native Instruments, RigKontrol3},"
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c
index 5962e4b84423..6d9f9b135c62 100644
--- a/sound/usb/usbmidi.c
+++ b/sound/usb/usbmidi.c
@@ -880,7 +880,7 @@ static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream,
880 snd_rawmidi_transmit_ack(substream, 1); 880 snd_rawmidi_transmit_ack(substream, 1);
881 return; 881 return;
882 } 882 }
883 tasklet_hi_schedule(&port->ep->tasklet); 883 tasklet_schedule(&port->ep->tasklet);
884 } 884 }
885} 885}
886 886
diff --git a/sound/usb/usx2y/usb_stream.c b/sound/usb/usx2y/usb_stream.c
index ff23cc1ce3b9..70b96355ca4c 100644
--- a/sound/usb/usx2y/usb_stream.c
+++ b/sound/usb/usx2y/usb_stream.c
@@ -276,7 +276,8 @@ static void subs_set_complete(struct urb **urbs, void (*complete)(struct urb *))
276 } 276 }
277} 277}
278 278
279int usb_stream_prepare_playback(struct usb_stream_kernel *sk, struct urb *inurb) 279static int usb_stream_prepare_playback(struct usb_stream_kernel *sk,
280 struct urb *inurb)
280{ 281{
281 struct usb_stream *s = sk->s; 282 struct usb_stream *s = sk->s;
282 struct urb *io; 283 struct urb *io;