aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 13:32:54 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-13 13:32:54 -0500
commit66dc918d42eaaa9afe42a47d07526765162017a9 (patch)
tree947411841773dfb076f1aa78bc5be868bc4281a6 /sound
parentb2034d474b7e1e8578bd5c2977024b51693269d9 (diff)
parent6db9a0f326d3144d790d9479309df480a8f562e4 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (348 commits) ALSA: hda - Fix NULL-derefence with a single mic in STAC auto-mic detection ALSA: hda - Add missing NID 0x19 fixup for Sony VAIO ALSA: hda - Fix ALC275 enable hardware EQ for SONY VAIO ALSA: oxygen: fix Xonar DG input ALSA: hda - Fix EAPD on Lenovo NB ALC269 to low ALSA: hda - Fix missing EAPD for Acer 4930G ALSA: hda: Disable 4/6 channels on some NVIDIA GPUs. ALSA: hda - Add static_hdmi_pcm option to HDMI codec parser ALSA: hda - Don't refer ELD when unplugged ASoC: tpa6130a2: Fix compiler warning ASoC: tlv320dac33: Add DAPM selection for LOM invert ASoC: DMIC codec: Adding a generic DMIC codec ALSA: snd-usb-us122l: Fix missing NULL checks ALSA: snd-usb-us122l: Fix MIDI output ASoC: soc-cache: Fix invalid memory access during snd_soc_lzo_cache_sync() ASoC: Fix section mismatch in wm8995.c ALSA: oxygen: add S/PDIF source selection for Claro cards ALSA: oxygen: fix CD/MIDI for X-Meridian (2G) ASoC: fix migor audio build ALSA: include delay.h for msleep in Xonar DG support ...
Diffstat (limited to 'sound')
-rw-r--r--sound/ac97_bus.c4
-rw-r--r--sound/aoa/codecs/onyx.c1
-rw-r--r--sound/aoa/core/gpio-feature.c7
-rw-r--r--sound/aoa/core/gpio-pmf.c7
-rw-r--r--sound/core/control.c28
-rw-r--r--sound/core/oss/pcm_oss.c4
-rw-r--r--sound/core/pcm_lib.c22
-rw-r--r--sound/core/pcm_native.c3
-rw-r--r--sound/core/seq/seq.c4
-rw-r--r--sound/core/sound.c18
-rw-r--r--sound/core/timer.c7
-rw-r--r--sound/drivers/ml403-ac97cr.c4
-rw-r--r--sound/i2c/other/ak4113.c5
-rw-r--r--sound/i2c/other/ak4114.c5
-rw-r--r--sound/pci/Kconfig23
-rw-r--r--sound/pci/ac97/ac97_codec.c6
-rw-r--r--sound/pci/azt3328.c406
-rw-r--r--sound/pci/bt87x.c10
-rw-r--r--sound/pci/cmipci.c25
-rw-r--r--sound/pci/hda/hda_codec.c3
-rw-r--r--sound/pci/hda/hda_intel.c9
-rw-r--r--sound/pci/hda/patch_analog.c72
-rw-r--r--sound/pci/hda/patch_conexant.c108
-rw-r--r--sound/pci/hda/patch_hdmi.c92
-rw-r--r--sound/pci/hda/patch_realtek.c703
-rw-r--r--sound/pci/hda/patch_sigmatel.c17
-rw-r--r--sound/pci/hda/patch_via.c3
-rw-r--r--sound/pci/ice1712/delta.c49
-rw-r--r--sound/pci/ice1712/delta.h11
-rw-r--r--sound/pci/oxygen/Makefile4
-rw-r--r--sound/pci/oxygen/cs4245.h107
-rw-r--r--sound/pci/oxygen/hifier.c239
-rw-r--r--sound/pci/oxygen/oxygen.c356
-rw-r--r--sound/pci/oxygen/oxygen.h19
-rw-r--r--sound/pci/oxygen/oxygen_io.c4
-rw-r--r--sound/pci/oxygen/oxygen_lib.c71
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c110
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c55
-rw-r--r--sound/pci/oxygen/oxygen_regs.h16
-rw-r--r--sound/pci/oxygen/xonar.h2
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c84
-rw-r--r--sound/pci/oxygen/xonar_dg.c572
-rw-r--r--sound/pci/oxygen/xonar_dg.h8
-rw-r--r--sound/pci/oxygen/xonar_hdmi.c2
-rw-r--r--sound/pci/oxygen/xonar_lib.c6
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c473
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c317
-rw-r--r--sound/pci/rme9652/hdsp.c538
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c12
-rw-r--r--sound/soc/Kconfig17
-rw-r--r--sound/soc/Makefile2
-rw-r--r--sound/soc/atmel/playpaq_wm8510.c12
-rw-r--r--sound/soc/atmel/sam9g20_wm8731.c18
-rw-r--r--sound/soc/atmel/snd-soc-afeb9260.c14
-rw-r--r--sound/soc/au1x/db1200.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad1836.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad193x.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ad73311.c1
-rw-r--r--sound/soc/blackfin/bf5xx-ssm2602.c1
-rw-r--r--sound/soc/codecs/88pm860x-codec.c30
-rw-r--r--sound/soc/codecs/Kconfig20
-rw-r--r--sound/soc/codecs/Makefile12
-rw-r--r--sound/soc/codecs/ad1836.c7
-rw-r--r--sound/soc/codecs/ad193x.c8
-rw-r--r--sound/soc/codecs/ad1980.c1
-rw-r--r--sound/soc/codecs/ak4535.c20
-rw-r--r--sound/soc/codecs/ak4642.c2
-rw-r--r--sound/soc/codecs/ak4671.c11
-rw-r--r--sound/soc/codecs/alc5623.c1117
-rw-r--r--sound/soc/codecs/alc5623.h161
-rw-r--r--sound/soc/codecs/cq93vc.c4
-rw-r--r--sound/soc/codecs/cs4270.c162
-rw-r--r--sound/soc/codecs/cs42l51.c7
-rw-r--r--sound/soc/codecs/cx20442.c16
-rw-r--r--sound/soc/codecs/da7210.c2
-rw-r--r--sound/soc/codecs/dmic.c81
-rw-r--r--sound/soc/codecs/jz4740.c11
-rw-r--r--sound/soc/codecs/max98088.c13
-rw-r--r--sound/soc/codecs/ssm2602.c10
-rw-r--r--sound/soc/codecs/stac9766.c2
-rw-r--r--sound/soc/codecs/tlv320aic23.c10
-rw-r--r--sound/soc/codecs/tlv320aic26.c5
-rw-r--r--sound/soc/codecs/tlv320aic3x.c71
-rw-r--r--sound/soc/codecs/tlv320dac33.c334
-rw-r--r--sound/soc/codecs/tpa6130a2.c99
-rw-r--r--sound/soc/codecs/tpa6130a2.h1
-rw-r--r--sound/soc/codecs/twl4030.c56
-rw-r--r--sound/soc/codecs/twl6040.c859
-rw-r--r--sound/soc/codecs/twl6040.h8
-rw-r--r--sound/soc/codecs/uda134x.c3
-rw-r--r--sound/soc/codecs/uda1380.c15
-rw-r--r--sound/soc/codecs/wl1273.c3
-rw-r--r--sound/soc/codecs/wm2000.c6
-rw-r--r--sound/soc/codecs/wm8350.c105
-rw-r--r--sound/soc/codecs/wm8400.c12
-rw-r--r--sound/soc/codecs/wm8510.c12
-rw-r--r--sound/soc/codecs/wm8523.c12
-rw-r--r--sound/soc/codecs/wm8580.c23
-rw-r--r--sound/soc/codecs/wm8711.c11
-rw-r--r--sound/soc/codecs/wm8728.c12
-rw-r--r--sound/soc/codecs/wm8731.c102
-rw-r--r--sound/soc/codecs/wm8737.c754
-rw-r--r--sound/soc/codecs/wm8737.h322
-rw-r--r--sound/soc/codecs/wm8741.c10
-rw-r--r--sound/soc/codecs/wm8750.c13
-rw-r--r--sound/soc/codecs/wm8753.c49
-rw-r--r--sound/soc/codecs/wm8770.c749
-rw-r--r--sound/soc/codecs/wm8770.h51
-rw-r--r--sound/soc/codecs/wm8776.c10
-rw-r--r--sound/soc/codecs/wm8804.c7
-rw-r--r--sound/soc/codecs/wm8900.c13
-rw-r--r--sound/soc/codecs/wm8903.c222
-rw-r--r--sound/soc/codecs/wm8903.h25
-rw-r--r--sound/soc/codecs/wm8904.c36
-rw-r--r--sound/soc/codecs/wm8940.c8
-rw-r--r--sound/soc/codecs/wm8955.c12
-rw-r--r--sound/soc/codecs/wm8960.c29
-rw-r--r--sound/soc/codecs/wm8961.c13
-rw-r--r--sound/soc/codecs/wm8962.c41
-rw-r--r--sound/soc/codecs/wm8971.c30
-rw-r--r--sound/soc/codecs/wm8974.c13
-rw-r--r--sound/soc/codecs/wm8978.c13
-rw-r--r--sound/soc/codecs/wm8985.c12
-rw-r--r--sound/soc/codecs/wm8988.c11
-rw-r--r--sound/soc/codecs/wm8990.c12
-rw-r--r--sound/soc/codecs/wm8993.c21
-rw-r--r--sound/soc/codecs/wm8994-tables.c3147
-rw-r--r--sound/soc/codecs/wm8994.c2544
-rw-r--r--sound/soc/codecs/wm8994.h14
-rw-r--r--sound/soc/codecs/wm8995.c1818
-rw-r--r--sound/soc/codecs/wm8995.h4269
-rw-r--r--sound/soc/codecs/wm9081.c15
-rw-r--r--sound/soc/codecs/wm9090.c18
-rw-r--r--sound/soc/codecs/wm9705.c7
-rw-r--r--sound/soc/codecs/wm9712.c10
-rw-r--r--sound/soc/codecs/wm9713.c9
-rw-r--r--sound/soc/codecs/wm_hubs.c108
-rw-r--r--sound/soc/codecs/wm_hubs.h3
-rw-r--r--sound/soc/davinci/davinci-evm.c23
-rw-r--r--sound/soc/davinci/davinci-sffsdr.c1
-rw-r--r--sound/soc/ep93xx/ep93xx-i2s.c4
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c4
-rw-r--r--sound/soc/ep93xx/snappercl15.c6
-rw-r--r--sound/soc/imx/eukrea-tlv320.c1
-rw-r--r--sound/soc/imx/imx-ssi.c4
-rw-r--r--sound/soc/imx/phycore-ac97.c1
-rw-r--r--sound/soc/imx/wm1133-ev1.c8
-rw-r--r--sound/soc/jz4740/jz4740-i2s.c1
-rw-r--r--sound/soc/jz4740/qi_lb60.c14
-rw-r--r--sound/soc/kirkwood/Kconfig11
-rw-r--r--sound/soc/kirkwood/Makefile2
-rw-r--r--sound/soc/kirkwood/kirkwood-openrd.c2
-rw-r--r--sound/soc/kirkwood/kirkwood-t5325.c141
-rw-r--r--sound/soc/nuc900/nuc900-audio.c1
-rw-r--r--sound/soc/omap/am3517evm.c14
-rw-r--r--sound/soc/omap/ams-delta.c82
-rw-r--r--sound/soc/omap/igep0020.c1
-rw-r--r--sound/soc/omap/n810.c44
-rw-r--r--sound/soc/omap/omap-mcbsp.c35
-rw-r--r--sound/soc/omap/omap-mcbsp.h4
-rw-r--r--sound/soc/omap/omap2evm.c1
-rw-r--r--sound/soc/omap/omap3beagle.c1
-rw-r--r--sound/soc/omap/omap3evm.c1
-rw-r--r--sound/soc/omap/omap3pandora.c45
-rw-r--r--sound/soc/omap/osk5912.c14
-rw-r--r--sound/soc/omap/overo.c1
-rw-r--r--sound/soc/omap/rx51.c27
-rw-r--r--sound/soc/omap/sdp3430.c44
-rw-r--r--sound/soc/omap/sdp4430.c57
-rw-r--r--sound/soc/omap/zoom2.c36
-rw-r--r--sound/soc/pxa/corgi.c52
-rw-r--r--sound/soc/pxa/e740_wm9705.c30
-rw-r--r--sound/soc/pxa/e750_wm9705.c30
-rw-r--r--sound/soc/pxa/e800_wm9712.c8
-rw-r--r--sound/soc/pxa/em-x270.c1
-rw-r--r--sound/soc/pxa/magician.c36
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c18
-rw-r--r--sound/soc/pxa/palm27x.c34
-rw-r--r--sound/soc/pxa/poodle.c26
-rw-r--r--sound/soc/pxa/raumfeld.c1
-rw-r--r--sound/soc/pxa/saarb.c18
-rw-r--r--sound/soc/pxa/spitz.c70
-rw-r--r--sound/soc/pxa/tavorevb3.c18
-rw-r--r--sound/soc/pxa/tosa.c38
-rw-r--r--sound/soc/pxa/z2.c16
-rw-r--r--sound/soc/pxa/zylonite.c12
-rw-r--r--sound/soc/s3c24xx/Kconfig171
-rw-r--r--sound/soc/s3c24xx/Makefile55
-rw-r--r--sound/soc/s3c24xx/aquila_wm8994.c295
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s-v4.c230
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.c242
-rw-r--r--sound/soc/s3c24xx/s3c64xx-i2s.h41
-rw-r--r--sound/soc/s6000/s6105-ipcam.c42
-rw-r--r--sound/soc/samsung/Kconfig171
-rw-r--r--sound/soc/samsung/Makefile55
-rw-r--r--sound/soc/samsung/ac97.c (renamed from sound/soc/s3c24xx/s3c-ac97.c)22
-rw-r--r--sound/soc/samsung/ac97.h (renamed from sound/soc/s3c24xx/s3c-ac97.h)8
-rw-r--r--sound/soc/samsung/dma.c (renamed from sound/soc/s3c24xx/s3c-dma.c)134
-rw-r--r--sound/soc/samsung/dma.h (renamed from sound/soc/s3c24xx/s3c-dma.h)2
-rw-r--r--sound/soc/samsung/goni_wm8994.c (renamed from sound/soc/s3c24xx/goni_wm8994.c)66
-rw-r--r--sound/soc/samsung/h1940_uda1380.c296
-rw-r--r--sound/soc/samsung/i2s.c1258
-rw-r--r--sound/soc/samsung/i2s.h29
-rw-r--r--sound/soc/samsung/jive_wm8750.c (renamed from sound/soc/s3c24xx/jive_wm8750.c)26
-rw-r--r--sound/soc/samsung/lm4857.h (renamed from sound/soc/s3c24xx/lm4857.h)0
-rw-r--r--sound/soc/samsung/ln2440sbc_alc650.c (renamed from sound/soc/s3c24xx/ln2440sbc_alc650.c)9
-rw-r--r--sound/soc/samsung/neo1973_gta02_wm8753.c (renamed from sound/soc/s3c24xx/neo1973_gta02_wm8753.c)72
-rw-r--r--sound/soc/samsung/neo1973_wm8753.c (renamed from sound/soc/s3c24xx/neo1973_wm8753.c)130
-rw-r--r--sound/soc/samsung/pcm.c (renamed from sound/soc/s3c24xx/s3c-pcm.c)6
-rw-r--r--sound/soc/samsung/pcm.h (renamed from sound/soc/s3c24xx/s3c-pcm.h)2
-rw-r--r--sound/soc/samsung/regs-i2s-v2.h (renamed from sound/soc/s3c24xx/regs-i2s-v2.h)0
-rw-r--r--sound/soc/samsung/rx1950_uda1380.c (renamed from sound/soc/s3c24xx/rx1950_uda1380.c)17
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.c (renamed from sound/soc/s3c24xx/s3c-i2s-v2.c)4
-rw-r--r--sound/soc/samsung/s3c-i2s-v2.h (renamed from sound/soc/s3c24xx/s3c-i2s-v2.h)2
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c (renamed from sound/soc/s3c24xx/s3c2412-i2s.c)4
-rw-r--r--sound/soc/samsung/s3c2412-i2s.h (renamed from sound/soc/s3c24xx/s3c2412-i2s.h)2
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c (renamed from sound/soc/s3c24xx/s3c24xx-i2s.c)2
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.h (renamed from sound/soc/s3c24xx/s3c24xx-i2s.h)0
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.c (renamed from sound/soc/s3c24xx/s3c24xx_simtec.c)5
-rw-r--r--sound/soc/samsung/s3c24xx_simtec.h (renamed from sound/soc/s3c24xx/s3c24xx_simtec.h)2
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_hermes.c (renamed from sound/soc/s3c24xx/s3c24xx_simtec_hermes.c)24
-rw-r--r--sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c (renamed from sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c)22
-rw-r--r--sound/soc/samsung/s3c24xx_uda134x.c (renamed from sound/soc/s3c24xx/s3c24xx_uda134x.c)5
-rw-r--r--sound/soc/samsung/smartq_wm8987.c (renamed from sound/soc/s3c24xx/smartq_wm8987.c)64
-rw-r--r--sound/soc/samsung/smdk2443_wm9710.c (renamed from sound/soc/s3c24xx/smdk2443_wm9710.c)9
-rw-r--r--sound/soc/samsung/smdk_spdif.c (renamed from sound/soc/s3c24xx/smdk_spdif.c)21
-rw-r--r--sound/soc/samsung/smdk_wm8580.c (renamed from sound/soc/s3c24xx/smdk64xx_wm8580.c)174
-rw-r--r--sound/soc/samsung/smdk_wm8994.c176
-rw-r--r--sound/soc/samsung/smdk_wm9713.c (renamed from sound/soc/s3c24xx/smdk_wm9713.c)26
-rw-r--r--sound/soc/samsung/spdif.c (renamed from sound/soc/s3c24xx/spdif.c)4
-rw-r--r--sound/soc/samsung/spdif.h (renamed from sound/soc/s3c24xx/spdif.h)2
-rw-r--r--sound/soc/sh/Kconfig4
-rw-r--r--sound/soc/sh/fsi-ak4642.c140
-rw-r--r--sound/soc/sh/fsi-da7210.c2
-rw-r--r--sound/soc/sh/fsi.c273
-rw-r--r--sound/soc/sh/migor.c8
-rw-r--r--sound/soc/sh/sh7760-ac97.c3
-rw-r--r--sound/soc/sh/siu.h2
-rw-r--r--sound/soc/sh/siu_dai.c2
-rw-r--r--sound/soc/sh/siu_pcm.c2
-rw-r--r--sound/soc/soc-cache.c1065
-rw-r--r--sound/soc/soc-core.c575
-rw-r--r--sound/soc/soc-dapm.c860
-rw-r--r--sound/soc/soc-jack.c31
-rw-r--r--sound/usb/format.c5
-rw-r--r--sound/usb/midi.c19
-rw-r--r--sound/usb/mixer.c11
-rw-r--r--sound/usb/quirks-table.h4
-rw-r--r--sound/usb/usx2y/us122l.c41
249 files changed, 23678 insertions, 6948 deletions
diff --git a/sound/ac97_bus.c b/sound/ac97_bus.c
index a351dd0a09c7..2b50cbe6aca9 100644
--- a/sound/ac97_bus.c
+++ b/sound/ac97_bus.c
@@ -19,8 +19,8 @@
19 19
20/* 20/*
21 * 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
22 * probe method. Drivers have direct access to the struct snd_ac97 structure and may 22 * probe method. Drivers have direct access to the struct snd_ac97
23 * decide based on the id field amongst other things. 23 * structure and may decide based on the id field amongst other things.
24 */ 24 */
25static int ac97_bus_match(struct device *dev, struct device_driver *drv) 25static int ac97_bus_match(struct device *dev, struct device_driver *drv)
26{ 26{
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 91852e49910e..3687a6cc9881 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -1114,7 +1114,6 @@ static int onyx_i2c_remove(struct i2c_client *client)
1114 of_node_put(onyx->codec.node); 1114 of_node_put(onyx->codec.node);
1115 if (onyx->codec_info) 1115 if (onyx->codec_info)
1116 kfree(onyx->codec_info); 1116 kfree(onyx->codec_info);
1117 i2c_set_clientdata(client, onyx);
1118 kfree(onyx); 1117 kfree(onyx);
1119 return 0; 1118 return 0;
1120} 1119}
diff --git a/sound/aoa/core/gpio-feature.c b/sound/aoa/core/gpio-feature.c
index de8e03afa97b..faa317490545 100644
--- a/sound/aoa/core/gpio-feature.c
+++ b/sound/aoa/core/gpio-feature.c
@@ -287,10 +287,9 @@ static void ftr_gpio_exit(struct gpio_runtime *rt)
287 free_irq(linein_detect_irq, &rt->line_in_notify); 287 free_irq(linein_detect_irq, &rt->line_in_notify);
288 if (rt->line_out_notify.gpio_private) 288 if (rt->line_out_notify.gpio_private)
289 free_irq(lineout_detect_irq, &rt->line_out_notify); 289 free_irq(lineout_detect_irq, &rt->line_out_notify);
290 cancel_delayed_work(&rt->headphone_notify.work); 290 cancel_delayed_work_sync(&rt->headphone_notify.work);
291 cancel_delayed_work(&rt->line_in_notify.work); 291 cancel_delayed_work_sync(&rt->line_in_notify.work);
292 cancel_delayed_work(&rt->line_out_notify.work); 292 cancel_delayed_work_sync(&rt->line_out_notify.work);
293 flush_scheduled_work();
294 mutex_destroy(&rt->headphone_notify.mutex); 293 mutex_destroy(&rt->headphone_notify.mutex);
295 mutex_destroy(&rt->line_in_notify.mutex); 294 mutex_destroy(&rt->line_in_notify.mutex);
296 mutex_destroy(&rt->line_out_notify.mutex); 295 mutex_destroy(&rt->line_out_notify.mutex);
diff --git a/sound/aoa/core/gpio-pmf.c b/sound/aoa/core/gpio-pmf.c
index 7e267c9379bc..c8d8a1a6f964 100644
--- a/sound/aoa/core/gpio-pmf.c
+++ b/sound/aoa/core/gpio-pmf.c
@@ -107,10 +107,9 @@ static void pmf_gpio_exit(struct gpio_runtime *rt)
107 107
108 /* make sure no work is pending before freeing 108 /* make sure no work is pending before freeing
109 * all things */ 109 * all things */
110 cancel_delayed_work(&rt->headphone_notify.work); 110 cancel_delayed_work_sync(&rt->headphone_notify.work);
111 cancel_delayed_work(&rt->line_in_notify.work); 111 cancel_delayed_work_sync(&rt->line_in_notify.work);
112 cancel_delayed_work(&rt->line_out_notify.work); 112 cancel_delayed_work_sync(&rt->line_out_notify.work);
113 flush_scheduled_work();
114 113
115 mutex_destroy(&rt->headphone_notify.mutex); 114 mutex_destroy(&rt->headphone_notify.mutex);
116 mutex_destroy(&rt->line_in_notify.mutex); 115 mutex_destroy(&rt->line_in_notify.mutex);
diff --git a/sound/core/control.c b/sound/core/control.c
index 45a818002d99..9ce00ed20fba 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1488,7 +1488,7 @@ int snd_ctl_create(struct snd_card *card)
1488} 1488}
1489 1489
1490/* 1490/*
1491 * Frequently used control callbacks 1491 * Frequently used control callbacks/helpers
1492 */ 1492 */
1493int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, 1493int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
1494 struct snd_ctl_elem_info *uinfo) 1494 struct snd_ctl_elem_info *uinfo)
@@ -1513,3 +1513,29 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
1513} 1513}
1514 1514
1515EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); 1515EXPORT_SYMBOL(snd_ctl_boolean_stereo_info);
1516
1517/**
1518 * snd_ctl_enum_info - fills the info structure for an enumerated control
1519 * @info: the structure to be filled
1520 * @channels: the number of the control's channels; often one
1521 * @items: the number of control values; also the size of @names
1522 * @names: an array containing the names of all control values
1523 *
1524 * Sets all required fields in @info to their appropriate values.
1525 * If the control's accessibility is not the default (readable and writable),
1526 * the caller has to fill @info->access.
1527 */
1528int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels,
1529 unsigned int items, const char *const names[])
1530{
1531 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1532 info->count = channels;
1533 info->value.enumerated.items = items;
1534 if (info->value.enumerated.item >= items)
1535 info->value.enumerated.item = items - 1;
1536 strlcpy(info->value.enumerated.name,
1537 names[info->value.enumerated.item],
1538 sizeof(info->value.enumerated.name));
1539 return 0;
1540}
1541EXPORT_SYMBOL(snd_ctl_enum_info);
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index b753ec661fcf..a2e4eb324699 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -453,8 +453,10 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
453 } else { 453 } else {
454 *params = *save; 454 *params = *save;
455 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir); 455 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
456 if (max < 0) 456 if (max < 0) {
457 kfree(save);
457 return max; 458 return max;
459 }
458 last = 1; 460 last = 1;
459 } 461 }
460 _end: 462 _end:
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 11446a1506da..a82e3756a72d 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -373,6 +373,27 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
373 (unsigned long)new_hw_ptr, 373 (unsigned long)new_hw_ptr,
374 (unsigned long)runtime->hw_ptr_base); 374 (unsigned long)runtime->hw_ptr_base);
375 } 375 }
376
377 if (runtime->no_period_wakeup) {
378 /*
379 * Without regular period interrupts, we have to check
380 * the elapsed time to detect xruns.
381 */
382 jdelta = jiffies - runtime->hw_ptr_jiffies;
383 if (jdelta < runtime->hw_ptr_buffer_jiffies / 2)
384 goto no_delta_check;
385 hdelta = jdelta - delta * HZ / runtime->rate;
386 while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) {
387 delta += runtime->buffer_size;
388 hw_base += runtime->buffer_size;
389 if (hw_base >= runtime->boundary)
390 hw_base = 0;
391 new_hw_ptr = hw_base + pos;
392 hdelta -= runtime->hw_ptr_buffer_jiffies;
393 }
394 goto no_delta_check;
395 }
396
376 /* something must be really wrong */ 397 /* something must be really wrong */
377 if (delta >= runtime->buffer_size + runtime->period_size) { 398 if (delta >= runtime->buffer_size + runtime->period_size) {
378 hw_ptr_error(substream, 399 hw_ptr_error(substream,
@@ -442,6 +463,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
442 (long)old_hw_ptr); 463 (long)old_hw_ptr);
443 } 464 }
444 465
466 no_delta_check:
445 if (runtime->status->hw_ptr == new_hw_ptr) 467 if (runtime->status->hw_ptr == new_hw_ptr)
446 return 0; 468 return 0;
447 469
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index c0ebb5162e95..4be45e7be8ad 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -422,6 +422,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
422 runtime->info = params->info; 422 runtime->info = params->info;
423 runtime->rate_num = params->rate_num; 423 runtime->rate_num = params->rate_num;
424 runtime->rate_den = params->rate_den; 424 runtime->rate_den = params->rate_den;
425 runtime->no_period_wakeup =
426 (params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
427 (params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
425 428
426 bits = snd_pcm_format_physical_width(runtime->format); 429 bits = snd_pcm_format_physical_width(runtime->format);
427 runtime->sample_bits = bits; 430 runtime->sample_bits = bits;
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index bf09a5ad1865..119fddb6fc99 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -32,6 +32,7 @@
32#include "seq_timer.h" 32#include "seq_timer.h"
33#include "seq_system.h" 33#include "seq_system.h"
34#include "seq_info.h" 34#include "seq_info.h"
35#include <sound/minors.h>
35#include <sound/seq_device.h> 36#include <sound/seq_device.h>
36 37
37#if defined(CONFIG_SND_SEQ_DUMMY_MODULE) 38#if defined(CONFIG_SND_SEQ_DUMMY_MODULE)
@@ -73,6 +74,9 @@ MODULE_PARM_DESC(seq_default_timer_subdevice, "The default timer subdevice numbe
73module_param(seq_default_timer_resolution, int, 0644); 74module_param(seq_default_timer_resolution, int, 0644);
74MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz."); 75MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz.");
75 76
77MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER);
78MODULE_ALIAS("devname:snd/seq");
79
76/* 80/*
77 * INIT PART 81 * INIT PART
78 */ 82 */
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 66691fe437e6..1c7a3efe1778 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -188,14 +188,22 @@ static const struct file_operations snd_fops =
188}; 188};
189 189
190#ifdef CONFIG_SND_DYNAMIC_MINORS 190#ifdef CONFIG_SND_DYNAMIC_MINORS
191static int snd_find_free_minor(void) 191static int snd_find_free_minor(int type)
192{ 192{
193 int minor; 193 int minor;
194 194
195 /* static minors for module auto loading */
196 if (type == SNDRV_DEVICE_TYPE_SEQUENCER)
197 return SNDRV_MINOR_SEQUENCER;
198 if (type == SNDRV_DEVICE_TYPE_TIMER)
199 return SNDRV_MINOR_TIMER;
200
195 for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) { 201 for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) {
196 /* skip minors still used statically for autoloading devices */ 202 /* skip static minors still used for module auto loading */
197 if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL || 203 if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL)
198 minor == SNDRV_MINOR_SEQUENCER) 204 continue;
205 if (minor == SNDRV_MINOR_SEQUENCER ||
206 minor == SNDRV_MINOR_TIMER)
199 continue; 207 continue;
200 if (!snd_minors[minor]) 208 if (!snd_minors[minor])
201 return minor; 209 return minor;
@@ -269,7 +277,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
269 preg->private_data = private_data; 277 preg->private_data = private_data;
270 mutex_lock(&sound_mutex); 278 mutex_lock(&sound_mutex);
271#ifdef CONFIG_SND_DYNAMIC_MINORS 279#ifdef CONFIG_SND_DYNAMIC_MINORS
272 minor = snd_find_free_minor(); 280 minor = snd_find_free_minor(type);
273#else 281#else
274 minor = snd_kernel_minor(type, card, dev); 282 minor = snd_kernel_minor(type, card, dev);
275 if (minor >= 0 && snd_minors[minor]) 283 if (minor >= 0 && snd_minors[minor])
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 13afb60999b9..ed016329e911 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -34,8 +34,8 @@
34#include <sound/initval.h> 34#include <sound/initval.h>
35#include <linux/kmod.h> 35#include <linux/kmod.h>
36 36
37#if defined(CONFIG_SND_HPET) || defined(CONFIG_SND_HPET_MODULE) 37#if defined(CONFIG_SND_HRTIMER) || defined(CONFIG_SND_HRTIMER_MODULE)
38#define DEFAULT_TIMER_LIMIT 3 38#define DEFAULT_TIMER_LIMIT 4
39#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE) 39#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
40#define DEFAULT_TIMER_LIMIT 2 40#define DEFAULT_TIMER_LIMIT 2
41#else 41#else
@@ -52,6 +52,9 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
52module_param(timer_tstamp_monotonic, int, 0444); 52module_param(timer_tstamp_monotonic, int, 0444);
53MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default)."); 53MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
54 54
55MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER);
56MODULE_ALIAS("devname:snd/timer");
57
55struct snd_timer_user { 58struct snd_timer_user {
56 struct snd_timer_instance *timeri; 59 struct snd_timer_instance *timeri;
57 int tread; /* enhanced read with timestamps and events */ 60 int tread; /* enhanced read with timestamps and events */
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index a1282c1c0591..5cfcb908c430 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -1143,8 +1143,8 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
1143 (resource->start) + 1); 1143 (resource->start) + 1);
1144 if (ml403_ac97cr->port == NULL) { 1144 if (ml403_ac97cr->port == NULL) {
1145 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " 1145 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
1146 "unable to remap memory region (%x to %x)\n", 1146 "unable to remap memory region (%pR)\n",
1147 resource->start, resource->end); 1147 resource);
1148 snd_ml403_ac97cr_free(ml403_ac97cr); 1148 snd_ml403_ac97cr_free(ml403_ac97cr);
1149 return -EBUSY; 1149 return -EBUSY;
1150 } 1150 }
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c
index 971a84a4fa77..c424d329f806 100644
--- a/sound/i2c/other/ak4113.c
+++ b/sound/i2c/other/ak4113.c
@@ -57,8 +57,7 @@ static void snd_ak4113_free(struct ak4113 *chip)
57{ 57{
58 chip->init = 1; /* don't schedule new work */ 58 chip->init = 1; /* don't schedule new work */
59 mb(); 59 mb();
60 cancel_delayed_work(&chip->work); 60 cancel_delayed_work_sync(&chip->work);
61 flush_scheduled_work();
62 kfree(chip); 61 kfree(chip);
63} 62}
64 63
@@ -141,7 +140,7 @@ void snd_ak4113_reinit(struct ak4113 *chip)
141{ 140{
142 chip->init = 1; 141 chip->init = 1;
143 mb(); 142 mb();
144 flush_scheduled_work(); 143 flush_delayed_work_sync(&chip->work);
145 ak4113_init_regs(chip); 144 ak4113_init_regs(chip);
146 /* bring up statistics / event queing */ 145 /* bring up statistics / event queing */
147 chip->init = 0; 146 chip->init = 0;
diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c
index 0341451f814c..d9fb537b0b94 100644
--- a/sound/i2c/other/ak4114.c
+++ b/sound/i2c/other/ak4114.c
@@ -67,8 +67,7 @@ static void snd_ak4114_free(struct ak4114 *chip)
67{ 67{
68 chip->init = 1; /* don't schedule new work */ 68 chip->init = 1; /* don't schedule new work */
69 mb(); 69 mb();
70 cancel_delayed_work(&chip->work); 70 cancel_delayed_work_sync(&chip->work);
71 flush_scheduled_work();
72 kfree(chip); 71 kfree(chip);
73} 72}
74 73
@@ -154,7 +153,7 @@ void snd_ak4114_reinit(struct ak4114 *chip)
154{ 153{
155 chip->init = 1; 154 chip->init = 1;
156 mb(); 155 mb();
157 flush_scheduled_work(); 156 flush_delayed_work_sync(&chip->work);
158 ak4114_init_regs(chip); 157 ak4114_init_regs(chip);
159 /* bring up statistics / event queing */ 158 /* bring up statistics / event queing */
160 chip->init = 0; 159 chip->init = 0;
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 12e34653b8a8..9823d59d7ad7 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -209,7 +209,7 @@ config SND_OXYGEN_LIB
209 tristate 209 tristate
210 210
211config SND_OXYGEN 211config SND_OXYGEN
212 tristate "C-Media 8788 (Oxygen)" 212 tristate "C-Media 8786, 8787, 8788 (Oxygen)"
213 select SND_OXYGEN_LIB 213 select SND_OXYGEN_LIB
214 select SND_PCM 214 select SND_PCM
215 select SND_MPU401_UART 215 select SND_MPU401_UART
@@ -217,13 +217,18 @@ config SND_OXYGEN
217 Say Y here to include support for sound cards based on the 217 Say Y here to include support for sound cards based on the
218 C-Media CMI8788 (Oxygen HD Audio) chip: 218 C-Media CMI8788 (Oxygen HD Audio) chip:
219 * Asound A-8788 219 * Asound A-8788
220 * Asus Xonar DG
220 * AuzenTech X-Meridian 221 * AuzenTech X-Meridian
222 * AuzenTech X-Meridian 2G
221 * Bgears b-Enspirer 223 * Bgears b-Enspirer
222 * Club3D Theatron DTS 224 * Club3D Theatron DTS
223 * HT-Omega Claro (plus) 225 * HT-Omega Claro (plus)
224 * HT-Omega Claro halo (XT) 226 * HT-Omega Claro halo (XT)
227 * Kuroutoshikou CMI8787-HG2PCI
225 * Razer Barracuda AC-1 228 * Razer Barracuda AC-1
226 * Sondigo Inferno 229 * Sondigo Inferno
230 * TempoTec/MediaTek HiFier Fantasia
231 * TempoTec/MediaTek HiFier Serenade
227 232
228 To compile this driver as a module, choose M here: the module 233 To compile this driver as a module, choose M here: the module
229 will be called snd-oxygen. 234 will be called snd-oxygen.
@@ -578,18 +583,6 @@ config SND_HDSPM
578 To compile this driver as a module, choose M here: the module 583 To compile this driver as a module, choose M here: the module
579 will be called snd-hdspm. 584 will be called snd-hdspm.
580 585
581config SND_HIFIER
582 tristate "TempoTec HiFier Fantasia"
583 select SND_OXYGEN_LIB
584 select SND_PCM
585 select SND_MPU401_UART
586 help
587 Say Y here to include support for the MediaTek/TempoTec HiFier
588 Fantasia sound card.
589
590 To compile this driver as a module, choose M here: the module
591 will be called snd-hifier.
592
593config SND_ICE1712 586config SND_ICE1712
594 tristate "ICEnsemble ICE1712 (Envy24)" 587 tristate "ICEnsemble ICE1712 (Envy24)"
595 select SND_MPU401_UART 588 select SND_MPU401_UART
@@ -826,8 +819,8 @@ config SND_VIRTUOSO
826 Say Y here to include support for sound cards based on the 819 Say Y here to include support for sound cards based on the
827 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, 820 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS,
828 Essence ST (Deluxe), and Essence STX. 821 Essence ST (Deluxe), and Essence STX.
829 Support for the HDAV1.3 (Deluxe) is incomplete; for the 822 Support for the HDAV1.3 (Deluxe) and HDAV1.3 Slim is experimental;
830 HDAV1.3 Slim and Xense, missing. 823 for the Xense, missing.
831 824
832 To compile this driver as a module, choose M here: the module 825 To compile this driver as a module, choose M here: the module
833 will be called snd-virtuoso. 826 will be called snd-virtuoso.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index a7630e9edf8a..0fc614ce16c1 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -1014,8 +1014,7 @@ static int snd_ac97_free(struct snd_ac97 *ac97)
1014{ 1014{
1015 if (ac97) { 1015 if (ac97) {
1016#ifdef CONFIG_SND_AC97_POWER_SAVE 1016#ifdef CONFIG_SND_AC97_POWER_SAVE
1017 cancel_delayed_work(&ac97->power_work); 1017 cancel_delayed_work_sync(&ac97->power_work);
1018 flush_scheduled_work();
1019#endif 1018#endif
1020 snd_ac97_proc_done(ac97); 1019 snd_ac97_proc_done(ac97);
1021 if (ac97->bus) 1020 if (ac97->bus)
@@ -2456,8 +2455,7 @@ void snd_ac97_suspend(struct snd_ac97 *ac97)
2456 if (ac97->build_ops->suspend) 2455 if (ac97->build_ops->suspend)
2457 ac97->build_ops->suspend(ac97); 2456 ac97->build_ops->suspend(ac97);
2458#ifdef CONFIG_SND_AC97_POWER_SAVE 2457#ifdef CONFIG_SND_AC97_POWER_SAVE
2459 cancel_delayed_work(&ac97->power_work); 2458 cancel_delayed_work_sync(&ac97->power_work);
2460 flush_scheduled_work();
2461#endif 2459#endif
2462 snd_ac97_powerdown(ac97); 2460 snd_ac97_powerdown(ac97);
2463} 2461}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 2f3cacbd5528..6117595fc075 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). 2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
3 * Copyright (C) 2002, 2005 - 2009 by Andreas Mohr <andi AT lisas.de> 3 * Copyright (C) 2002, 2005 - 2010 by Andreas Mohr <andi AT lisas.de>
4 * 4 *
5 * Framework borrowed from Bart Hartgers's als4000.c. 5 * Framework borrowed from Bart Hartgers's als4000.c.
6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), 6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -175,6 +175,7 @@
175 175
176#include <asm/io.h> 176#include <asm/io.h>
177#include <linux/init.h> 177#include <linux/init.h>
178#include <linux/bug.h> /* WARN_ONCE */
178#include <linux/pci.h> 179#include <linux/pci.h>
179#include <linux/delay.h> 180#include <linux/delay.h>
180#include <linux/slab.h> 181#include <linux/slab.h>
@@ -201,14 +202,15 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
201 202
202/* === Debug settings === 203/* === Debug settings ===
203 Further diagnostic functionality than the settings below 204 Further diagnostic functionality than the settings below
204 does not need to be provided, since one can easily write a bash script 205 does not need to be provided, since one can easily write a POSIX shell script
205 to dump the card's I/O ports (those listed in lspci -v -v): 206 to dump the card's I/O ports (those listed in lspci -v -v):
206 function dump() 207 dump()
207 { 208 {
208 local descr=$1; local addr=$2; local count=$3 209 local descr=$1; local addr=$2; local count=$3
209 210
210 echo "${descr}: ${count} @ ${addr}:" 211 echo "${descr}: ${count} @ ${addr}:"
211 dd if=/dev/port skip=$[${addr}] count=${count} bs=1 2>/dev/null| hexdump -C 212 dd if=/dev/port skip=`printf %d ${addr}` count=${count} bs=1 \
213 2>/dev/null| hexdump -C
212 } 214 }
213 and then use something like 215 and then use something like
214 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8", 216 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8",
@@ -216,14 +218,14 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
216 possibly within a "while true; do ... sleep 1; done" loop. 218 possibly within a "while true; do ... sleep 1; done" loop.
217 Tweaking ports could be done using 219 Tweaking ports could be done using
218 VALSTRING="`printf "%02x" $value`" 220 VALSTRING="`printf "%02x" $value`"
219 printf "\x""$VALSTRING"|dd of=/dev/port seek=$[${addr}] bs=1 2>/dev/null 221 printf "\x""$VALSTRING"|dd of=/dev/port seek=`printf %d ${addr}` bs=1 \
222 2>/dev/null
220*/ 223*/
221 224
222#define DEBUG_MISC 0 225#define DEBUG_MISC 0
223#define DEBUG_CALLS 0 226#define DEBUG_CALLS 0
224#define DEBUG_MIXER 0 227#define DEBUG_MIXER 0
225#define DEBUG_CODEC 0 228#define DEBUG_CODEC 0
226#define DEBUG_IO 0
227#define DEBUG_TIMER 0 229#define DEBUG_TIMER 0
228#define DEBUG_GAME 0 230#define DEBUG_GAME 0
229#define DEBUG_PM 0 231#define DEBUG_PM 0
@@ -291,19 +293,23 @@ static int seqtimer_scaling = 128;
291module_param(seqtimer_scaling, int, 0444); 293module_param(seqtimer_scaling, int, 0444);
292MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); 294MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
293 295
294struct snd_azf3328_codec_data {
295 unsigned long io_base;
296 struct snd_pcm_substream *substream;
297 bool running;
298 const char *name;
299};
300
301enum snd_azf3328_codec_type { 296enum snd_azf3328_codec_type {
297 /* warning: fixed indices (also used for bitmask checks!) */
302 AZF_CODEC_PLAYBACK = 0, 298 AZF_CODEC_PLAYBACK = 0,
303 AZF_CODEC_CAPTURE = 1, 299 AZF_CODEC_CAPTURE = 1,
304 AZF_CODEC_I2S_OUT = 2, 300 AZF_CODEC_I2S_OUT = 2,
305}; 301};
306 302
303struct snd_azf3328_codec_data {
304 unsigned long io_base; /* keep first! (avoid offset calc) */
305 unsigned int dma_base; /* helper to avoid an indirection in hotpath */
306 spinlock_t *lock; /* TODO: convert to our own per-codec lock member */
307 struct snd_pcm_substream *substream;
308 bool running;
309 enum snd_azf3328_codec_type type;
310 const char *name;
311};
312
307struct snd_azf3328 { 313struct snd_azf3328 {
308 /* often-used fields towards beginning, then grouped */ 314 /* often-used fields towards beginning, then grouped */
309 315
@@ -362,6 +368,9 @@ MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
362static int 368static int
363snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set) 369snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set)
364{ 370{
371 /* Well, strictly spoken, the inb/outb sequence isn't atomic
372 and would need locking. However we currently don't care
373 since it potentially complicates matters. */
365 u8 prev = inb(reg), new; 374 u8 prev = inb(reg), new;
366 375
367 new = (do_set) ? (prev|mask) : (prev & ~mask); 376 new = (do_set) ? (prev|mask) : (prev & ~mask);
@@ -413,6 +422,21 @@ snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec,
413 outl(value, codec->io_base + reg); 422 outl(value, codec->io_base + reg);
414} 423}
415 424
425static inline void
426snd_azf3328_codec_outl_multi(const struct snd_azf3328_codec_data *codec,
427 unsigned reg, const void *buffer, int count
428)
429{
430 unsigned long addr = codec->io_base + reg;
431 if (count) {
432 const u32 *buf = buffer;
433 do {
434 outl(*buf++, addr);
435 addr += 4;
436 } while (--count);
437 }
438}
439
416static inline u32 440static inline u32
417snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg) 441snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg)
418{ 442{
@@ -943,38 +967,43 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream)
943} 967}
944 968
945static void 969static void
946snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, 970snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
947 enum snd_azf3328_codec_type codec_type,
948 enum azf_freq_t bitrate, 971 enum azf_freq_t bitrate,
949 unsigned int format_width, 972 unsigned int format_width,
950 unsigned int channels 973 unsigned int channels
951) 974)
952{ 975{
953 unsigned long flags; 976 unsigned long flags;
954 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
955 u16 val = 0xff00; 977 u16 val = 0xff00;
978 u8 freq = 0;
956 979
957 snd_azf3328_dbgcallenter(); 980 snd_azf3328_dbgcallenter();
958 switch (bitrate) { 981 switch (bitrate) {
959 case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break; 982#define AZF_FMT_XLATE(in_freq, out_bits) \
960 case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break; 983 do { \
961 case AZF_FREQ_5512: 984 case AZF_FREQ_ ## in_freq: \
962 /* the AZF3328 names it "5510" for some strange reason */ 985 freq = SOUNDFORMAT_FREQ_ ## out_bits; \
963 val |= SOUNDFORMAT_FREQ_5510; break; 986 break; \
964 case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break; 987 } while (0);
965 case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break; 988 AZF_FMT_XLATE(4000, SUSPECTED_4000)
966 case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break; 989 AZF_FMT_XLATE(4800, SUSPECTED_4800)
967 case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break; 990 /* the AZF3328 names it "5510" for some strange reason: */
968 case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break; 991 AZF_FMT_XLATE(5512, 5510)
969 case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break; 992 AZF_FMT_XLATE(6620, 6620)
970 case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break; 993 AZF_FMT_XLATE(8000, 8000)
971 case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break; 994 AZF_FMT_XLATE(9600, 9600)
995 AZF_FMT_XLATE(11025, 11025)
996 AZF_FMT_XLATE(13240, SUSPECTED_13240)
997 AZF_FMT_XLATE(16000, 16000)
998 AZF_FMT_XLATE(22050, 22050)
999 AZF_FMT_XLATE(32000, 32000)
972 default: 1000 default:
973 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate); 1001 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
974 /* fall-through */ 1002 /* fall-through */
975 case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break; 1003 AZF_FMT_XLATE(44100, 44100)
976 case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break; 1004 AZF_FMT_XLATE(48000, 48000)
977 case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break; 1005 AZF_FMT_XLATE(66200, SUSPECTED_66200)
1006#undef AZF_FMT_XLATE
978 } 1007 }
979 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ 1008 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
980 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ 1009 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
@@ -986,13 +1015,15 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
986 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */ 1015 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
987 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */ 1016 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
988 1017
1018 val |= freq;
1019
989 if (channels == 2) 1020 if (channels == 2)
990 val |= SOUNDFORMAT_FLAG_2CHANNELS; 1021 val |= SOUNDFORMAT_FLAG_2CHANNELS;
991 1022
992 if (format_width == 16) 1023 if (format_width == 16)
993 val |= SOUNDFORMAT_FLAG_16BIT; 1024 val |= SOUNDFORMAT_FLAG_16BIT;
994 1025
995 spin_lock_irqsave(&chip->reg_lock, flags); 1026 spin_lock_irqsave(codec->lock, flags);
996 1027
997 /* set bitrate/format */ 1028 /* set bitrate/format */
998 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val); 1029 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
@@ -1004,7 +1035,8 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
1004 * (FIXME: yes, it works, but what exactly am I doing here?? :) 1035 * (FIXME: yes, it works, but what exactly am I doing here?? :)
1005 * FIXME: does this have some side effects for full-duplex 1036 * FIXME: does this have some side effects for full-duplex
1006 * or other dramatic side effects? */ 1037 * or other dramatic side effects? */
1007 if (codec_type == AZF_CODEC_PLAYBACK) /* only do it for playback */ 1038 /* do it for non-capture codecs only */
1039 if (codec->type != AZF_CODEC_CAPTURE)
1008 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, 1040 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1009 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) | 1041 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) |
1010 DMA_RUN_SOMETHING1 | 1042 DMA_RUN_SOMETHING1 |
@@ -1014,20 +1046,19 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
1014 DMA_SOMETHING_ELSE 1046 DMA_SOMETHING_ELSE
1015 ); 1047 );
1016 1048
1017 spin_unlock_irqrestore(&chip->reg_lock, flags); 1049 spin_unlock_irqrestore(codec->lock, flags);
1018 snd_azf3328_dbgcallleave(); 1050 snd_azf3328_dbgcallleave();
1019} 1051}
1020 1052
1021static inline void 1053static inline void
1022snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip, 1054snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328_codec_data *codec
1023 enum snd_azf3328_codec_type codec_type
1024) 1055)
1025{ 1056{
1026 /* choose lowest frequency for low power consumption. 1057 /* choose lowest frequency for low power consumption.
1027 * While this will cause louder noise due to rather coarse frequency, 1058 * While this will cause louder noise due to rather coarse frequency,
1028 * it should never matter since output should always 1059 * it should never matter since output should always
1029 * get disabled properly when idle anyway. */ 1060 * get disabled properly when idle anyway. */
1030 snd_azf3328_codec_setfmt(chip, codec_type, AZF_FREQ_4000, 8, 1); 1061 snd_azf3328_codec_setfmt(codec, AZF_FREQ_4000, 8, 1);
1031} 1062}
1032 1063
1033static void 1064static void
@@ -1101,69 +1132,87 @@ snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip,
1101 /* ...and adjust clock, too 1132 /* ...and adjust clock, too
1102 * (reduce noise and power consumption) */ 1133 * (reduce noise and power consumption) */
1103 if (!enable) 1134 if (!enable)
1104 snd_azf3328_codec_setfmt_lowpower( 1135 snd_azf3328_codec_setfmt_lowpower(codec);
1105 chip,
1106 codec_type
1107 );
1108 codec->running = enable; 1136 codec->running = enable;
1109 } 1137 }
1110} 1138}
1111 1139
1112static void 1140static void
1113snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, 1141snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data *codec,
1114 enum snd_azf3328_codec_type codec_type,
1115 unsigned long addr, 1142 unsigned long addr,
1116 unsigned int count, 1143 unsigned int period_bytes,
1117 unsigned int size 1144 unsigned int buffer_bytes
1118) 1145)
1119{ 1146{
1120 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1121 snd_azf3328_dbgcallenter(); 1147 snd_azf3328_dbgcallenter();
1148 WARN_ONCE(period_bytes & 1, "odd period length!?\n");
1149 WARN_ONCE(buffer_bytes != 2 * period_bytes,
1150 "missed our input expectations! %u vs. %u\n",
1151 buffer_bytes, period_bytes);
1122 if (!codec->running) { 1152 if (!codec->running) {
1123 /* AZF3328 uses a two buffer pointer DMA transfer approach */ 1153 /* AZF3328 uses a two buffer pointer DMA transfer approach */
1124 1154
1125 unsigned long flags, addr_area2; 1155 unsigned long flags;
1126 1156
1127 /* width 32bit (prevent overflow): */ 1157 /* width 32bit (prevent overflow): */
1128 u32 count_areas, lengths; 1158 u32 area_length;
1159 struct codec_setup_io {
1160 u32 dma_start_1;
1161 u32 dma_start_2;
1162 u32 dma_lengths;
1163 } __attribute__((packed)) setup_io;
1164
1165 area_length = buffer_bytes/2;
1166
1167 setup_io.dma_start_1 = addr;
1168 setup_io.dma_start_2 = addr+area_length;
1129 1169
1130 count_areas = size/2; 1170 snd_azf3328_dbgcodec(
1131 addr_area2 = addr+count_areas; 1171 "setdma: buffers %08x[%u] / %08x[%u], %u, %u\n",
1132 snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n", 1172 setup_io.dma_start_1, area_length,
1133 addr, count_areas, addr_area2, count_areas); 1173 setup_io.dma_start_2, area_length,
1174 period_bytes, buffer_bytes);
1134 1175
1135 count_areas--; /* max. index */ 1176 /* Hmm, are we really supposed to decrement this by 1??
1177 Most definitely certainly not: configuring full length does
1178 work properly (i.e. likely better), and BTW we
1179 violated possibly differing frame sizes with this...
1180
1181 area_length--; |* max. index *|
1182 */
1136 1183
1137 /* build combined I/O buffer length word */ 1184 /* build combined I/O buffer length word */
1138 lengths = (count_areas << 16) | (count_areas); 1185 setup_io.dma_lengths = (area_length << 16) | (area_length);
1139 spin_lock_irqsave(&chip->reg_lock, flags); 1186
1140 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_1, addr); 1187 spin_lock_irqsave(codec->lock, flags);
1141 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_2, 1188 snd_azf3328_codec_outl_multi(
1142 addr_area2); 1189 codec, IDX_IO_CODEC_DMA_START_1, &setup_io, 3
1143 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_LENGTHS, 1190 );
1144 lengths); 1191 spin_unlock_irqrestore(codec->lock, flags);
1145 spin_unlock_irqrestore(&chip->reg_lock, flags);
1146 } 1192 }
1147 snd_azf3328_dbgcallleave(); 1193 snd_azf3328_dbgcallleave();
1148} 1194}
1149 1195
1150static int 1196static int
1151snd_azf3328_codec_prepare(struct snd_pcm_substream *substream) 1197snd_azf3328_pcm_prepare(struct snd_pcm_substream *substream)
1152{ 1198{
1153#if 0
1154 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1155 struct snd_pcm_runtime *runtime = substream->runtime; 1199 struct snd_pcm_runtime *runtime = substream->runtime;
1200 struct snd_azf3328_codec_data *codec = runtime->private_data;
1201#if 0
1156 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 1202 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1157 unsigned int count = snd_pcm_lib_period_bytes(substream); 1203 unsigned int count = snd_pcm_lib_period_bytes(substream);
1158#endif 1204#endif
1159 1205
1160 snd_azf3328_dbgcallenter(); 1206 snd_azf3328_dbgcallenter();
1207
1208 codec->dma_base = runtime->dma_addr;
1209
1161#if 0 1210#if 0
1162 snd_azf3328_codec_setfmt(chip, AZF_CODEC_..., 1211 snd_azf3328_codec_setfmt(codec,
1163 runtime->rate, 1212 runtime->rate,
1164 snd_pcm_format_width(runtime->format), 1213 snd_pcm_format_width(runtime->format),
1165 runtime->channels); 1214 runtime->channels);
1166 snd_azf3328_codec_setdmaa(chip, AZF_CODEC_..., 1215 snd_azf3328_codec_setdmaa(codec,
1167 runtime->dma_addr, count, size); 1216 runtime->dma_addr, count, size);
1168#endif 1217#endif
1169 snd_azf3328_dbgcallleave(); 1218 snd_azf3328_dbgcallleave();
@@ -1171,24 +1220,23 @@ snd_azf3328_codec_prepare(struct snd_pcm_substream *substream)
1171} 1220}
1172 1221
1173static int 1222static int
1174snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, 1223snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1175 struct snd_pcm_substream *substream, int cmd)
1176{ 1224{
1177 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1225 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1178 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1179 struct snd_pcm_runtime *runtime = substream->runtime; 1226 struct snd_pcm_runtime *runtime = substream->runtime;
1227 struct snd_azf3328_codec_data *codec = runtime->private_data;
1180 int result = 0; 1228 int result = 0;
1181 u16 flags1; 1229 u16 flags1;
1182 bool previously_muted = 0; 1230 bool previously_muted = 0;
1183 bool is_playback_codec = (AZF_CODEC_PLAYBACK == codec_type); 1231 bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type);
1184 1232
1185 snd_azf3328_dbgcalls("snd_azf3328_codec_trigger cmd %d\n", cmd); 1233 snd_azf3328_dbgcalls("snd_azf3328_pcm_trigger cmd %d\n", cmd);
1186 1234
1187 switch (cmd) { 1235 switch (cmd) {
1188 case SNDRV_PCM_TRIGGER_START: 1236 case SNDRV_PCM_TRIGGER_START:
1189 snd_azf3328_dbgcodec("START %s\n", codec->name); 1237 snd_azf3328_dbgcodec("START %s\n", codec->name);
1190 1238
1191 if (is_playback_codec) { 1239 if (is_main_mixer_playback_codec) {
1192 /* mute WaveOut (avoid clicking during setup) */ 1240 /* mute WaveOut (avoid clicking during setup) */
1193 previously_muted = 1241 previously_muted =
1194 snd_azf3328_mixer_set_mute( 1242 snd_azf3328_mixer_set_mute(
@@ -1196,12 +1244,12 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1196 ); 1244 );
1197 } 1245 }
1198 1246
1199 snd_azf3328_codec_setfmt(chip, codec_type, 1247 snd_azf3328_codec_setfmt(codec,
1200 runtime->rate, 1248 runtime->rate,
1201 snd_pcm_format_width(runtime->format), 1249 snd_pcm_format_width(runtime->format),
1202 runtime->channels); 1250 runtime->channels);
1203 1251
1204 spin_lock(&chip->reg_lock); 1252 spin_lock(codec->lock);
1205 /* first, remember current value: */ 1253 /* first, remember current value: */
1206 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS); 1254 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1207 1255
@@ -1211,14 +1259,14 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1211 1259
1212 /* FIXME: clear interrupts or what??? */ 1260 /* FIXME: clear interrupts or what??? */
1213 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff); 1261 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
1214 spin_unlock(&chip->reg_lock); 1262 spin_unlock(codec->lock);
1215 1263
1216 snd_azf3328_codec_setdmaa(chip, codec_type, runtime->dma_addr, 1264 snd_azf3328_codec_setdmaa(codec, runtime->dma_addr,
1217 snd_pcm_lib_period_bytes(substream), 1265 snd_pcm_lib_period_bytes(substream),
1218 snd_pcm_lib_buffer_bytes(substream) 1266 snd_pcm_lib_buffer_bytes(substream)
1219 ); 1267 );
1220 1268
1221 spin_lock(&chip->reg_lock); 1269 spin_lock(codec->lock);
1222#ifdef WIN9X 1270#ifdef WIN9X
1223 /* FIXME: enable playback/recording??? */ 1271 /* FIXME: enable playback/recording??? */
1224 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2; 1272 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
@@ -1242,10 +1290,10 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1242 DMA_EPILOGUE_SOMETHING | 1290 DMA_EPILOGUE_SOMETHING |
1243 DMA_SOMETHING_ELSE); 1291 DMA_SOMETHING_ELSE);
1244#endif 1292#endif
1245 spin_unlock(&chip->reg_lock); 1293 spin_unlock(codec->lock);
1246 snd_azf3328_ctrl_codec_activity(chip, codec_type, 1); 1294 snd_azf3328_ctrl_codec_activity(chip, codec->type, 1);
1247 1295
1248 if (is_playback_codec) { 1296 if (is_main_mixer_playback_codec) {
1249 /* now unmute WaveOut */ 1297 /* now unmute WaveOut */
1250 if (!previously_muted) 1298 if (!previously_muted)
1251 snd_azf3328_mixer_set_mute( 1299 snd_azf3328_mixer_set_mute(
@@ -1258,19 +1306,19 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1258 case SNDRV_PCM_TRIGGER_RESUME: 1306 case SNDRV_PCM_TRIGGER_RESUME:
1259 snd_azf3328_dbgcodec("RESUME %s\n", codec->name); 1307 snd_azf3328_dbgcodec("RESUME %s\n", codec->name);
1260 /* resume codec if we were active */ 1308 /* resume codec if we were active */
1261 spin_lock(&chip->reg_lock); 1309 spin_lock(codec->lock);
1262 if (codec->running) 1310 if (codec->running)
1263 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, 1311 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1264 snd_azf3328_codec_inw( 1312 snd_azf3328_codec_inw(
1265 codec, IDX_IO_CODEC_DMA_FLAGS 1313 codec, IDX_IO_CODEC_DMA_FLAGS
1266 ) | DMA_RESUME 1314 ) | DMA_RESUME
1267 ); 1315 );
1268 spin_unlock(&chip->reg_lock); 1316 spin_unlock(codec->lock);
1269 break; 1317 break;
1270 case SNDRV_PCM_TRIGGER_STOP: 1318 case SNDRV_PCM_TRIGGER_STOP:
1271 snd_azf3328_dbgcodec("STOP %s\n", codec->name); 1319 snd_azf3328_dbgcodec("STOP %s\n", codec->name);
1272 1320
1273 if (is_playback_codec) { 1321 if (is_main_mixer_playback_codec) {
1274 /* mute WaveOut (avoid clicking during setup) */ 1322 /* mute WaveOut (avoid clicking during setup) */
1275 previously_muted = 1323 previously_muted =
1276 snd_azf3328_mixer_set_mute( 1324 snd_azf3328_mixer_set_mute(
@@ -1278,7 +1326,7 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1278 ); 1326 );
1279 } 1327 }
1280 1328
1281 spin_lock(&chip->reg_lock); 1329 spin_lock(codec->lock);
1282 /* first, remember current value: */ 1330 /* first, remember current value: */
1283 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS); 1331 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1284 1332
@@ -1293,10 +1341,10 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1293 1341
1294 flags1 &= ~DMA_RUN_SOMETHING1; 1342 flags1 &= ~DMA_RUN_SOMETHING1;
1295 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1); 1343 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1296 spin_unlock(&chip->reg_lock); 1344 spin_unlock(codec->lock);
1297 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); 1345 snd_azf3328_ctrl_codec_activity(chip, codec->type, 0);
1298 1346
1299 if (is_playback_codec) { 1347 if (is_main_mixer_playback_codec) {
1300 /* now unmute WaveOut */ 1348 /* now unmute WaveOut */
1301 if (!previously_muted) 1349 if (!previously_muted)
1302 snd_azf3328_mixer_set_mute( 1350 snd_azf3328_mixer_set_mute(
@@ -1330,67 +1378,29 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1330 return result; 1378 return result;
1331} 1379}
1332 1380
1333static int
1334snd_azf3328_codec_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1335{
1336 return snd_azf3328_codec_trigger(AZF_CODEC_PLAYBACK, substream, cmd);
1337}
1338
1339static int
1340snd_azf3328_codec_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1341{
1342 return snd_azf3328_codec_trigger(AZF_CODEC_CAPTURE, substream, cmd);
1343}
1344
1345static int
1346snd_azf3328_codec_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd)
1347{
1348 return snd_azf3328_codec_trigger(AZF_CODEC_I2S_OUT, substream, cmd);
1349}
1350
1351static snd_pcm_uframes_t 1381static snd_pcm_uframes_t
1352snd_azf3328_codec_pointer(struct snd_pcm_substream *substream, 1382snd_azf3328_pcm_pointer(struct snd_pcm_substream *substream
1353 enum snd_azf3328_codec_type codec_type
1354) 1383)
1355{ 1384{
1356 const struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1385 const struct snd_azf3328_codec_data *codec =
1357 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; 1386 substream->runtime->private_data;
1358 unsigned long bufptr, result; 1387 unsigned long result;
1359 snd_pcm_uframes_t frmres; 1388 snd_pcm_uframes_t frmres;
1360 1389
1361#ifdef QUERY_HARDWARE
1362 bufptr = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1363#else
1364 bufptr = substream->runtime->dma_addr;
1365#endif
1366 result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS); 1390 result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS);
1367 1391
1368 /* calculate offset */ 1392 /* calculate offset */
1369 result -= bufptr; 1393#ifdef QUERY_HARDWARE
1394 result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1395#else
1396 result -= codec->dma_base;
1397#endif
1370 frmres = bytes_to_frames( substream->runtime, result); 1398 frmres = bytes_to_frames( substream->runtime, result);
1371 snd_azf3328_dbgcodec("%s @ 0x%8lx, frames %8ld\n", 1399 snd_azf3328_dbgcodec("%08li %s @ 0x%8lx, frames %8ld\n",
1372 codec->name, result, frmres); 1400 jiffies, codec->name, result, frmres);
1373 return frmres; 1401 return frmres;
1374} 1402}
1375 1403
1376static snd_pcm_uframes_t
1377snd_azf3328_codec_playback_pointer(struct snd_pcm_substream *substream)
1378{
1379 return snd_azf3328_codec_pointer(substream, AZF_CODEC_PLAYBACK);
1380}
1381
1382static snd_pcm_uframes_t
1383snd_azf3328_codec_capture_pointer(struct snd_pcm_substream *substream)
1384{
1385 return snd_azf3328_codec_pointer(substream, AZF_CODEC_CAPTURE);
1386}
1387
1388static snd_pcm_uframes_t
1389snd_azf3328_codec_i2s_out_pointer(struct snd_pcm_substream *substream)
1390{
1391 return snd_azf3328_codec_pointer(substream, AZF_CODEC_I2S_OUT);
1392}
1393
1394/******************************************************************/ 1404/******************************************************************/
1395 1405
1396#ifdef SUPPORT_GAMEPORT 1406#ifdef SUPPORT_GAMEPORT
@@ -1532,7 +1542,7 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1532 } 1542 }
1533 } 1543 }
1534 1544
1535 /* trigger next axes sampling, to be evaluated the next time we 1545 /* trigger next sampling of axes, to be evaluated the next time we
1536 * enter this function */ 1546 * enter this function */
1537 1547
1538 /* for some very, very strange reason we cannot enable 1548 /* for some very, very strange reason we cannot enable
@@ -1624,29 +1634,29 @@ snd_azf3328_irq_log_unknown_type(u8 which)
1624} 1634}
1625 1635
1626static inline void 1636static inline void
1627snd_azf3328_codec_interrupt(struct snd_azf3328 *chip, u8 status) 1637snd_azf3328_pcm_interrupt(const struct snd_azf3328_codec_data *first_codec,
1638 u8 status
1639)
1628{ 1640{
1629 u8 which; 1641 u8 which;
1630 enum snd_azf3328_codec_type codec_type; 1642 enum snd_azf3328_codec_type codec_type;
1631 const struct snd_azf3328_codec_data *codec; 1643 const struct snd_azf3328_codec_data *codec = first_codec;
1632 1644
1633 for (codec_type = AZF_CODEC_PLAYBACK; 1645 for (codec_type = AZF_CODEC_PLAYBACK;
1634 codec_type <= AZF_CODEC_I2S_OUT; 1646 codec_type <= AZF_CODEC_I2S_OUT;
1635 ++codec_type) { 1647 ++codec_type, ++codec) {
1636 1648
1637 /* skip codec if there's no interrupt for it */ 1649 /* skip codec if there's no interrupt for it */
1638 if (!(status & (1 << codec_type))) 1650 if (!(status & (1 << codec_type)))
1639 continue; 1651 continue;
1640 1652
1641 codec = &chip->codecs[codec_type]; 1653 spin_lock(codec->lock);
1642
1643 spin_lock(&chip->reg_lock);
1644 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE); 1654 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
1645 /* ack all IRQ types immediately */ 1655 /* ack all IRQ types immediately */
1646 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which); 1656 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
1647 spin_unlock(&chip->reg_lock); 1657 spin_unlock(codec->lock);
1648 1658
1649 if ((chip->pcm[codec_type]) && (codec->substream)) { 1659 if (codec->substream) {
1650 snd_pcm_period_elapsed(codec->substream); 1660 snd_pcm_period_elapsed(codec->substream);
1651 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n", 1661 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n",
1652 codec->name, 1662 codec->name,
@@ -1701,7 +1711,7 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1701 } 1711 }
1702 1712
1703 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT)) 1713 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT))
1704 snd_azf3328_codec_interrupt(chip, status); 1714 snd_azf3328_pcm_interrupt(chip->codecs, status);
1705 1715
1706 if (status & IRQ_GAMEPORT) 1716 if (status & IRQ_GAMEPORT)
1707 snd_azf3328_gameport_interrupt(chip); 1717 snd_azf3328_gameport_interrupt(chip);
@@ -1789,101 +1799,85 @@ snd_azf3328_pcm_open(struct snd_pcm_substream *substream,
1789{ 1799{
1790 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1800 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1791 struct snd_pcm_runtime *runtime = substream->runtime; 1801 struct snd_pcm_runtime *runtime = substream->runtime;
1802 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1792 1803
1793 snd_azf3328_dbgcallenter(); 1804 snd_azf3328_dbgcallenter();
1794 chip->codecs[codec_type].substream = substream; 1805 codec->substream = substream;
1795 1806
1796 /* same parameters for all our codecs - at least we think so... */ 1807 /* same parameters for all our codecs - at least we think so... */
1797 runtime->hw = snd_azf3328_hardware; 1808 runtime->hw = snd_azf3328_hardware;
1798 1809
1799 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1810 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1800 &snd_azf3328_hw_constraints_rates); 1811 &snd_azf3328_hw_constraints_rates);
1812 runtime->private_data = codec;
1801 snd_azf3328_dbgcallleave(); 1813 snd_azf3328_dbgcallleave();
1802 return 0; 1814 return 0;
1803} 1815}
1804 1816
1805static int 1817static int
1806snd_azf3328_playback_open(struct snd_pcm_substream *substream) 1818snd_azf3328_pcm_playback_open(struct snd_pcm_substream *substream)
1807{ 1819{
1808 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK); 1820 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK);
1809} 1821}
1810 1822
1811static int 1823static int
1812snd_azf3328_capture_open(struct snd_pcm_substream *substream) 1824snd_azf3328_pcm_capture_open(struct snd_pcm_substream *substream)
1813{ 1825{
1814 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE); 1826 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE);
1815} 1827}
1816 1828
1817static int 1829static int
1818snd_azf3328_i2s_out_open(struct snd_pcm_substream *substream) 1830snd_azf3328_pcm_i2s_out_open(struct snd_pcm_substream *substream)
1819{ 1831{
1820 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT); 1832 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT);
1821} 1833}
1822 1834
1823static int 1835static int
1824snd_azf3328_pcm_close(struct snd_pcm_substream *substream, 1836snd_azf3328_pcm_close(struct snd_pcm_substream *substream
1825 enum snd_azf3328_codec_type codec_type
1826) 1837)
1827{ 1838{
1828 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1839 struct snd_azf3328_codec_data *codec =
1840 substream->runtime->private_data;
1829 1841
1830 snd_azf3328_dbgcallenter(); 1842 snd_azf3328_dbgcallenter();
1831 chip->codecs[codec_type].substream = NULL; 1843 codec->substream = NULL;
1832 snd_azf3328_dbgcallleave(); 1844 snd_azf3328_dbgcallleave();
1833 return 0; 1845 return 0;
1834} 1846}
1835 1847
1836static int
1837snd_azf3328_playback_close(struct snd_pcm_substream *substream)
1838{
1839 return snd_azf3328_pcm_close(substream, AZF_CODEC_PLAYBACK);
1840}
1841
1842static int
1843snd_azf3328_capture_close(struct snd_pcm_substream *substream)
1844{
1845 return snd_azf3328_pcm_close(substream, AZF_CODEC_CAPTURE);
1846}
1847
1848static int
1849snd_azf3328_i2s_out_close(struct snd_pcm_substream *substream)
1850{
1851 return snd_azf3328_pcm_close(substream, AZF_CODEC_I2S_OUT);
1852}
1853
1854/******************************************************************/ 1848/******************************************************************/
1855 1849
1856static struct snd_pcm_ops snd_azf3328_playback_ops = { 1850static struct snd_pcm_ops snd_azf3328_playback_ops = {
1857 .open = snd_azf3328_playback_open, 1851 .open = snd_azf3328_pcm_playback_open,
1858 .close = snd_azf3328_playback_close, 1852 .close = snd_azf3328_pcm_close,
1859 .ioctl = snd_pcm_lib_ioctl, 1853 .ioctl = snd_pcm_lib_ioctl,
1860 .hw_params = snd_azf3328_hw_params, 1854 .hw_params = snd_azf3328_hw_params,
1861 .hw_free = snd_azf3328_hw_free, 1855 .hw_free = snd_azf3328_hw_free,
1862 .prepare = snd_azf3328_codec_prepare, 1856 .prepare = snd_azf3328_pcm_prepare,
1863 .trigger = snd_azf3328_codec_playback_trigger, 1857 .trigger = snd_azf3328_pcm_trigger,
1864 .pointer = snd_azf3328_codec_playback_pointer 1858 .pointer = snd_azf3328_pcm_pointer
1865}; 1859};
1866 1860
1867static struct snd_pcm_ops snd_azf3328_capture_ops = { 1861static struct snd_pcm_ops snd_azf3328_capture_ops = {
1868 .open = snd_azf3328_capture_open, 1862 .open = snd_azf3328_pcm_capture_open,
1869 .close = snd_azf3328_capture_close, 1863 .close = snd_azf3328_pcm_close,
1870 .ioctl = snd_pcm_lib_ioctl, 1864 .ioctl = snd_pcm_lib_ioctl,
1871 .hw_params = snd_azf3328_hw_params, 1865 .hw_params = snd_azf3328_hw_params,
1872 .hw_free = snd_azf3328_hw_free, 1866 .hw_free = snd_azf3328_hw_free,
1873 .prepare = snd_azf3328_codec_prepare, 1867 .prepare = snd_azf3328_pcm_prepare,
1874 .trigger = snd_azf3328_codec_capture_trigger, 1868 .trigger = snd_azf3328_pcm_trigger,
1875 .pointer = snd_azf3328_codec_capture_pointer 1869 .pointer = snd_azf3328_pcm_pointer
1876}; 1870};
1877 1871
1878static struct snd_pcm_ops snd_azf3328_i2s_out_ops = { 1872static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
1879 .open = snd_azf3328_i2s_out_open, 1873 .open = snd_azf3328_pcm_i2s_out_open,
1880 .close = snd_azf3328_i2s_out_close, 1874 .close = snd_azf3328_pcm_close,
1881 .ioctl = snd_pcm_lib_ioctl, 1875 .ioctl = snd_pcm_lib_ioctl,
1882 .hw_params = snd_azf3328_hw_params, 1876 .hw_params = snd_azf3328_hw_params,
1883 .hw_free = snd_azf3328_hw_free, 1877 .hw_free = snd_azf3328_hw_free,
1884 .prepare = snd_azf3328_codec_prepare, 1878 .prepare = snd_azf3328_pcm_prepare,
1885 .trigger = snd_azf3328_codec_i2s_out_trigger, 1879 .trigger = snd_azf3328_pcm_trigger,
1886 .pointer = snd_azf3328_codec_i2s_out_pointer 1880 .pointer = snd_azf3328_pcm_pointer
1887}; 1881};
1888 1882
1889static int __devinit 1883static int __devinit
@@ -1966,7 +1960,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
1966 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay); 1960 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
1967 delay = 49; /* minimum time is 49 ticks */ 1961 delay = 49; /* minimum time is 49 ticks */
1968 } 1962 }
1969 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay); 1963 snd_azf3328_dbgtimer("setting timer countdown value %d\n", delay);
1970 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE; 1964 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1971 spin_lock_irqsave(&chip->reg_lock, flags); 1965 spin_lock_irqsave(&chip->reg_lock, flags);
1972 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay); 1966 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
@@ -2180,6 +2174,7 @@ snd_azf3328_create(struct snd_card *card,
2180 }; 2174 };
2181 u8 dma_init; 2175 u8 dma_init;
2182 enum snd_azf3328_codec_type codec_type; 2176 enum snd_azf3328_codec_type codec_type;
2177 struct snd_azf3328_codec_data *codec_setup;
2183 2178
2184 *rchip = NULL; 2179 *rchip = NULL;
2185 2180
@@ -2217,15 +2212,23 @@ snd_azf3328_create(struct snd_card *card,
2217 chip->opl3_io = pci_resource_start(pci, 3); 2212 chip->opl3_io = pci_resource_start(pci, 3);
2218 chip->mixer_io = pci_resource_start(pci, 4); 2213 chip->mixer_io = pci_resource_start(pci, 4);
2219 2214
2220 chip->codecs[AZF_CODEC_PLAYBACK].io_base = 2215 codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK];
2221 chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK; 2216 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
2222 chip->codecs[AZF_CODEC_PLAYBACK].name = "PLAYBACK"; 2217 codec_setup->lock = &chip->reg_lock;
2223 chip->codecs[AZF_CODEC_CAPTURE].io_base = 2218 codec_setup->type = AZF_CODEC_PLAYBACK;
2224 chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE; 2219 codec_setup->name = "PLAYBACK";
2225 chip->codecs[AZF_CODEC_CAPTURE].name = "CAPTURE"; 2220
2226 chip->codecs[AZF_CODEC_I2S_OUT].io_base = 2221 codec_setup = &chip->codecs[AZF_CODEC_CAPTURE];
2227 chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT; 2222 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
2228 chip->codecs[AZF_CODEC_I2S_OUT].name = "I2S_OUT"; 2223 codec_setup->lock = &chip->reg_lock;
2224 codec_setup->type = AZF_CODEC_CAPTURE;
2225 codec_setup->name = "CAPTURE";
2226
2227 codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT];
2228 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
2229 codec_setup->lock = &chip->reg_lock;
2230 codec_setup->type = AZF_CODEC_I2S_OUT;
2231 codec_setup->name = "I2S_OUT";
2229 2232
2230 if (request_irq(pci->irq, snd_azf3328_interrupt, 2233 if (request_irq(pci->irq, snd_azf3328_interrupt,
2231 IRQF_SHARED, card->shortname, chip)) { 2234 IRQF_SHARED, card->shortname, chip)) {
@@ -2257,15 +2260,15 @@ snd_azf3328_create(struct snd_card *card,
2257 struct snd_azf3328_codec_data *codec = 2260 struct snd_azf3328_codec_data *codec =
2258 &chip->codecs[codec_type]; 2261 &chip->codecs[codec_type];
2259 2262
2260 /* shutdown codecs to save power */ 2263 /* shutdown codecs to reduce power / noise */
2261 /* have ...ctrl_codec_activity() act properly */ 2264 /* have ...ctrl_codec_activity() act properly */
2262 codec->running = 1; 2265 codec->running = 1;
2263 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); 2266 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
2264 2267
2265 spin_lock_irq(&chip->reg_lock); 2268 spin_lock_irq(codec->lock);
2266 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS, 2269 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
2267 dma_init); 2270 dma_init);
2268 spin_unlock_irq(&chip->reg_lock); 2271 spin_unlock_irq(codec->lock);
2269 } 2272 }
2270 2273
2271 snd_card_set_dev(card, &pci->dev); 2274 snd_card_set_dev(card, &pci->dev);
@@ -2419,6 +2422,7 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2419 2422
2420 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2423 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2421 2424
2425 /* same pcm object for playback/capture */
2422 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]); 2426 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
2423 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]); 2427 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
2424 2428
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 37e1b5df5ab8..2958a05b5293 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -637,15 +637,9 @@ static struct snd_kcontrol_new snd_bt87x_capture_boost = {
637static int snd_bt87x_capture_source_info(struct snd_kcontrol *kcontrol, 637static int snd_bt87x_capture_source_info(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_info *info) 638 struct snd_ctl_elem_info *info)
639{ 639{
640 static char *texts[3] = {"TV Tuner", "FM", "Mic/Line"}; 640 static const char *const texts[3] = {"TV Tuner", "FM", "Mic/Line"};
641 641
642 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 642 return snd_ctl_enum_info(info, 1, 3, texts);
643 info->count = 1;
644 info->value.enumerated.items = 3;
645 if (info->value.enumerated.item > 2)
646 info->value.enumerated.item = 2;
647 strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
648 return 0;
649} 643}
650 644
651static int snd_bt87x_capture_source_get(struct snd_kcontrol *kcontrol, 645static int snd_bt87x_capture_source_get(struct snd_kcontrol *kcontrol,
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 329968edca9b..b5bb036ef73c 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -2507,14 +2507,12 @@ static int snd_cmipci_line_in_mode_info(struct snd_kcontrol *kcontrol,
2507 struct snd_ctl_elem_info *uinfo) 2507 struct snd_ctl_elem_info *uinfo)
2508{ 2508{
2509 struct cmipci *cm = snd_kcontrol_chip(kcontrol); 2509 struct cmipci *cm = snd_kcontrol_chip(kcontrol);
2510 static char *texts[3] = { "Line-In", "Rear Output", "Bass Output" }; 2510 static const char *const texts[3] = {
2511 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2511 "Line-In", "Rear Output", "Bass Output"
2512 uinfo->count = 1; 2512 };
2513 uinfo->value.enumerated.items = cm->chip_version >= 39 ? 3 : 2; 2513
2514 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 2514 return snd_ctl_enum_info(uinfo, 1,
2515 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 2515 cm->chip_version >= 39 ? 3 : 2, texts);
2516 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2517 return 0;
2518} 2516}
2519 2517
2520static inline unsigned int get_line_in_mode(struct cmipci *cm) 2518static inline unsigned int get_line_in_mode(struct cmipci *cm)
@@ -2564,14 +2562,9 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol,
2564static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol, 2562static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol,
2565 struct snd_ctl_elem_info *uinfo) 2563 struct snd_ctl_elem_info *uinfo)
2566{ 2564{
2567 static char *texts[2] = { "Mic-In", "Center/LFE Output" }; 2565 static const char *const texts[2] = { "Mic-In", "Center/LFE Output" };
2568 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2566
2569 uinfo->count = 1; 2567 return snd_ctl_enum_info(uinfo, 1, 2, texts);
2570 uinfo->value.enumerated.items = 2;
2571 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2572 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2573 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2574 return 0;
2575} 2568}
2576 2569
2577static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol, 2570static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol,
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 98b6d02a36c9..05e5ec88c2d9 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -4571,6 +4571,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4571 } 4571 }
4572 memset(cfg->hp_pins + cfg->hp_outs, 0, 4572 memset(cfg->hp_pins + cfg->hp_outs, 0,
4573 sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs)); 4573 sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs));
4574 if (!cfg->hp_outs)
4575 cfg->line_out_type = AUTO_PIN_HP_OUT;
4576
4574 } 4577 }
4575 4578
4576 /* sort by sequence */ 4579 /* sort by sequence */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index a1c4008af891..d3d18be483e1 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1235,7 +1235,8 @@ static int azx_setup_periods(struct azx *chip,
1235 pos_adj = 0; 1235 pos_adj = 0;
1236 } else { 1236 } else {
1237 ofs = setup_bdle(substream, azx_dev, 1237 ofs = setup_bdle(substream, azx_dev,
1238 &bdl, ofs, pos_adj, 1); 1238 &bdl, ofs, pos_adj,
1239 !substream->runtime->no_period_wakeup);
1239 if (ofs < 0) 1240 if (ofs < 0)
1240 goto error; 1241 goto error;
1241 } 1242 }
@@ -1247,7 +1248,8 @@ static int azx_setup_periods(struct azx *chip,
1247 period_bytes - pos_adj, 0); 1248 period_bytes - pos_adj, 0);
1248 else 1249 else
1249 ofs = setup_bdle(substream, azx_dev, &bdl, ofs, 1250 ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
1250 period_bytes, 1); 1251 period_bytes,
1252 !substream->runtime->no_period_wakeup);
1251 if (ofs < 0) 1253 if (ofs < 0)
1252 goto error; 1254 goto error;
1253 } 1255 }
@@ -1515,7 +1517,8 @@ static struct snd_pcm_hardware azx_pcm_hw = {
1515 /* No full-resume yet implemented */ 1517 /* No full-resume yet implemented */
1516 /* SNDRV_PCM_INFO_RESUME |*/ 1518 /* SNDRV_PCM_INFO_RESUME |*/
1517 SNDRV_PCM_INFO_PAUSE | 1519 SNDRV_PCM_INFO_PAUSE |
1518 SNDRV_PCM_INFO_SYNC_START), 1520 SNDRV_PCM_INFO_SYNC_START |
1521 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
1519 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1522 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1520 .rates = SNDRV_PCM_RATE_48000, 1523 .rates = SNDRV_PCM_RATE_48000,
1521 .rate_min = 48000, 1524 .rate_min = 48000,
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index f7ff3f7ccb8e..46780670162b 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -666,7 +666,7 @@ static struct snd_kcontrol_new ad1986a_mixers[] = {
666 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 666 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
668 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 668 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
669 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 669 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
670 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 670 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
671 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), 671 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
672 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 672 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
@@ -729,7 +729,7 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
729 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 729 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
731 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 731 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
732 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 732 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
733 /* 733 /*
734 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 734 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
735 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */ 735 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
@@ -775,7 +775,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
775 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 775 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
776 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 776 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
777 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 777 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
778 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 778 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
779 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 779 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
780 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 780 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
781 { 781 {
@@ -1358,7 +1358,7 @@ static struct snd_kcontrol_new ad1983_mixers[] = {
1358 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1358 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1359 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), 1359 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1360 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), 1360 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1361 HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT), 1361 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT),
1362 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1362 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1363 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1363 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1364 { 1364 {
@@ -1515,8 +1515,8 @@ static struct snd_kcontrol_new ad1981_mixers[] = {
1515 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 1515 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1516 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1516 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1517 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1517 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1518 HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT), 1518 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1519 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT), 1519 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1520 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1520 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1521 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1521 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1522 { 1522 {
@@ -1726,8 +1726,8 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1726 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1726 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1727 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1727 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1728#endif 1728#endif
1729 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), 1729 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1730 HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT), 1730 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1731 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1731 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1732 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1732 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1733 { 1733 {
@@ -1774,7 +1774,7 @@ static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1774 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1774 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1775 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1775 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1776 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1776 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1777 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), 1777 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1778 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1778 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1779 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1779 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1780 { 1780 {
@@ -2160,8 +2160,8 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2160 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2160 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2161 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2161 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2162 2162
2163 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 2163 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2164 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 2164 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2165 2165
2166 { } /* end */ 2166 { } /* end */
2167}; 2167};
@@ -2203,8 +2203,8 @@ static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2203 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2203 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2204 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2204 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2205 2205
2206 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 2206 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2207 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 2207 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2208 { 2208 {
2209 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2209 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2210 .name = "Channel Mode", 2210 .name = "Channel Mode",
@@ -2232,7 +2232,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2232 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2232 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2233 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2233 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2234 2234
2235 HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT), 2235 HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2236 2236
2237 { 2237 {
2238 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2238 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2902,7 +2902,7 @@ static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2902 idx = ad1988_pin_idx(pin); 2902 idx = ad1988_pin_idx(pin);
2903 bnid = ad1988_boost_nids[idx]; 2903 bnid = ad1988_boost_nids[idx];
2904 if (bnid) { 2904 if (bnid) {
2905 sprintf(name, "%s Boost", ctlname); 2905 sprintf(name, "%s Boost Volume", ctlname);
2906 return add_control(spec, AD_CTL_WIDGET_VOL, name, 2906 return add_control(spec, AD_CTL_WIDGET_VOL, name,
2907 HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT)); 2907 HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2908 2908
@@ -3300,8 +3300,8 @@ static struct snd_kcontrol_new ad1884_base_mixers[] = {
3300 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 3300 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3301 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), 3301 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3302 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), 3302 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3303 HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT), 3303 HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3304 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), 3304 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3305 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3305 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3306 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3306 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3307 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3307 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3499,9 +3499,9 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3499 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), 3499 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3500 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 3500 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3501 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3501 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3502 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 3502 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3503 HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), 3503 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3504 HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT), 3504 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3505 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3505 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3506 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3506 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3507 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3507 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3560,8 +3560,8 @@ static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3560 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 3560 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3561 HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT), 3561 HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3562 HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT), 3562 HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3563 HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT), 3563 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
3564 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), 3564 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3565 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3565 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3566 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3566 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3567 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3567 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3745,9 +3745,9 @@ static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3745 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3745 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3746 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), 3746 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3747 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), 3747 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3748 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), 3748 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3749 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT), 3749 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
3750 HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT), 3750 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3751 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3751 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3752 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3752 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3753 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3753 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3888,9 +3888,9 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3888 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 3888 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3889 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 3889 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3890 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3890 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3891 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 3891 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3892 HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), 3892 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3893 HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT), 3893 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3894 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3894 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3895 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3895 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3896 { } /* end */ 3896 { } /* end */
@@ -4126,8 +4126,8 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4126 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4126 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4128 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4128 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4129 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 4129 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4130 HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT), 4130 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4131 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4131 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4132 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4132 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4133 { 4133 {
@@ -4255,8 +4255,8 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4255 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4255 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4256 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4256 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4257 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4257 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4258 HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT), 4258 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4259 HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT), 4259 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4260 { } /* end */ 4260 { } /* end */
4261}; 4261};
4262 4262
@@ -4494,9 +4494,9 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = {
4494 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 4494 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4495 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 4495 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4496 4496
4497 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 4497 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
4498 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 4498 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
4499 HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), 4499 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT),
4500 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4500 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4501 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4501 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4502 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 4502 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -4547,7 +4547,7 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4547 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT), 4547 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4548 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), 4548 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4549 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), 4549 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4550 HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT), 4550 HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT),
4551 { } /* end */ 4551 { } /* end */
4552}; 4552};
4553 4553
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 76bd58a0e2b6..e96581fcdbdb 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -869,16 +869,16 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
869} 869}
870 870
871static struct snd_kcontrol_new cxt5045_mixers[] = { 871static struct snd_kcontrol_new cxt5045_mixers[] = {
872 HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 872 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
873 HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), 873 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
874 HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 874 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
875 HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), 875 HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
876 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), 876 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
877 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), 877 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
878 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT), 878 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
879 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT), 879 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
880 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT), 880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
881 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT), 881 HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
882 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), 882 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
883 { 883 {
884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -910,16 +910,16 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
910}; 910};
911 911
912static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { 912static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
913 HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 913 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
914 HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), 914 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
915 HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 915 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
916 HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), 916 HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
917 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), 917 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
918 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), 918 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
919 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x2, HDA_INPUT), 919 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
920 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x2, HDA_INPUT), 920 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
921 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT), 921 HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
922 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT), 922 HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
923 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), 923 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
924 { 924 {
925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -947,7 +947,7 @@ static struct hda_verb cxt5045_init_verbs[] = {
947 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 947 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
948 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 948 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
949 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 949 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
950 /* Record selector: Int mic */ 950 /* Record selector: Internal mic */
951 {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, 951 {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
952 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 952 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
953 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, 953 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
@@ -960,7 +960,7 @@ static struct hda_verb cxt5045_init_verbs[] = {
960}; 960};
961 961
962static struct hda_verb cxt5045_benq_init_verbs[] = { 962static struct hda_verb cxt5045_benq_init_verbs[] = {
963 /* Int Mic, Mic */ 963 /* Internal Mic, Mic */
964 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 964 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
966 /* Line In,HP, Amp */ 966 /* Line In,HP, Amp */
@@ -973,7 +973,7 @@ static struct hda_verb cxt5045_benq_init_verbs[] = {
973 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 973 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
974 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 974 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
975 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 975 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
976 /* Record selector: Int mic */ 976 /* Record selector: Internal mic */
977 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1}, 977 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
978 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 978 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
979 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, 979 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
@@ -1376,7 +1376,7 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1376static struct snd_kcontrol_new cxt5047_base_mixers[] = { 1376static struct snd_kcontrol_new cxt5047_base_mixers[] = {
1377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT), 1377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1378 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT), 1378 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1379 HDA_CODEC_VOLUME("Mic Boost", 0x1a, 0x0, HDA_OUTPUT), 1379 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1380 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), 1380 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1381 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), 1381 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1382 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), 1382 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
@@ -1796,8 +1796,8 @@ static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1796static struct snd_kcontrol_new cxt5051_capture_mixers[] = { 1796static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1797 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1797 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1798 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1798 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1799 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT), 1799 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1800 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT), 1800 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1801 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT), 1801 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1802 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT), 1802 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1803 {} 1803 {}
@@ -1806,8 +1806,8 @@ static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1806static struct snd_kcontrol_new cxt5051_hp_mixers[] = { 1806static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1807 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1807 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1808 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1808 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1809 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT), 1809 HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
1810 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT), 1810 HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT),
1811 {} 1811 {}
1812}; 1812};
1813 1813
@@ -1826,8 +1826,8 @@ static struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1826static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { 1826static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1827 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1827 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1828 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1828 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1829 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT), 1829 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1830 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT), 1830 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1831 {} 1831 {}
1832}; 1832};
1833 1833
@@ -1847,7 +1847,7 @@ static struct hda_verb cxt5051_init_verbs[] = {
1847 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1847 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1848 /* DAC1 */ 1848 /* DAC1 */
1849 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1849 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1850 /* Record selector: Int mic */ 1850 /* Record selector: Internal mic */
1851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1853 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1853 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
@@ -1874,7 +1874,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1874 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1874 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1875 /* DAC1 */ 1875 /* DAC1 */
1876 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1876 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1877 /* Record selector: Int mic */ 1877 /* Record selector: Internal mic */
1878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1879 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, 1879 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1880 /* SPDIF route: PCM */ 1880 /* SPDIF route: PCM */
@@ -1904,7 +1904,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1904 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, 1904 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
1905 /* DAC1 */ 1905 /* DAC1 */
1906 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1906 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1907 /* Record selector: Int mic */ 1907 /* Record selector: Internal mic */
1908 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1908 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1909 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1909 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1910 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1910 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
@@ -1932,7 +1932,7 @@ static struct hda_verb cxt5051_f700_init_verbs[] = {
1932 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1932 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1933 /* DAC1 */ 1933 /* DAC1 */
1934 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1934 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1935 /* Record selector: Int mic */ 1935 /* Record selector: Internal mic */
1936 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1936 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1937 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, 1937 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1938 /* SPDIF route: PCM */ 1938 /* SPDIF route: PCM */
@@ -2111,6 +2111,11 @@ static struct hda_channel_mode cxt5066_modes[1] = {
2111 { 2, NULL }, 2111 { 2, NULL },
2112}; 2112};
2113 2113
2114#define HP_PRESENT_PORT_A (1 << 0)
2115#define HP_PRESENT_PORT_D (1 << 1)
2116#define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A)
2117#define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D)
2118
2114static void cxt5066_update_speaker(struct hda_codec *codec) 2119static void cxt5066_update_speaker(struct hda_codec *codec)
2115{ 2120{
2116 struct conexant_spec *spec = codec->spec; 2121 struct conexant_spec *spec = codec->spec;
@@ -2120,24 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
2120 spec->hp_present, spec->cur_eapd); 2125 spec->hp_present, spec->cur_eapd);
2121 2126
2122 /* Port A (HP) */ 2127 /* Port A (HP) */
2123 pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; 2128 pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
2124 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2129 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2125 pinctl); 2130 pinctl);
2126 2131
2127 /* Port D (HP/LO) */ 2132 /* Port D (HP/LO) */
2128 if (spec->dell_automute) { 2133 pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
2129 /* DELL AIO Port Rule: PortA> PortD> IntSpk */ 2134 if (spec->dell_automute || spec->thinkpad) {
2130 pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) 2135 /* Mute if Port A is connected */
2131 ? PIN_OUT : 0; 2136 if (hp_port_a_present(spec))
2132 } else if (spec->thinkpad) {
2133 if (spec->cur_eapd)
2134 pinctl = spec->port_d_mode;
2135 /* Mute dock line-out if Port A (laptop HP) is present */
2136 if (spec->hp_present& 1)
2137 pinctl = 0; 2137 pinctl = 0;
2138 } else { 2138 } else {
2139 pinctl = ((spec->hp_present & 2) && spec->cur_eapd) 2139 /* Thinkpad/Dell doesn't give pin-D status */
2140 ? spec->port_d_mode : 0; 2140 if (!hp_port_d_present(spec))
2141 pinctl = 0;
2141 } 2142 }
2142 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2143 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2143 pinctl); 2144 pinctl);
@@ -2379,8 +2380,8 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
2379 /* Port D */ 2380 /* Port D */
2380 portD = snd_hda_jack_detect(codec, 0x1c); 2381 portD = snd_hda_jack_detect(codec, 0x1c);
2381 2382
2382 spec->hp_present = !!(portA); 2383 spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
2383 spec->hp_present |= portD ? 2 : 0; 2384 spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
2384 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", 2385 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2385 portA, portD, spec->hp_present); 2386 portA, portD, spec->hp_present);
2386 cxt5066_update_speaker(codec); 2387 cxt5066_update_speaker(codec);
@@ -2728,7 +2729,7 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
2728static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { 2729static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2729 { 2730 {
2730 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2731 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2731 .name = "Int Mic Boost Capture Enum", 2732 .name = "Internal Mic Boost Capture Enum",
2732 .info = cxt5066_mic_boost_mux_enum_info, 2733 .info = cxt5066_mic_boost_mux_enum_info,
2733 .get = cxt5066_mic_boost_mux_enum_get, 2734 .get = cxt5066_mic_boost_mux_enum_get,
2734 .put = cxt5066_mic_boost_mux_enum_put, 2735 .put = cxt5066_mic_boost_mux_enum_put,
@@ -2954,7 +2955,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2954 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2955 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2955 2956
2956 /* internal microphone */ 2957 /* internal microphone */
2957 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ 2958 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2958 2959
2959 /* EAPD */ 2960 /* EAPD */
2960 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2961 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -3009,7 +3010,7 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = {
3009 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3010 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3010 3011
3011 /* internal microphone */ 3012 /* internal microphone */
3012 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ 3013 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
3013 3014
3014 /* EAPD */ 3015 /* EAPD */
3015 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 3016 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -3097,6 +3098,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3097 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), 3098 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
3098 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), 3099 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
3099 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), 3100 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
3101 SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
3100 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), 3102 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
3101 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), 3103 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
3102 SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), 3104 SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
@@ -3108,16 +3110,9 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3108 CXT5066_LAPTOP), 3110 CXT5066_LAPTOP),
3109 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 3111 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
3110 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), 3112 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
3111 SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD),
3112 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), 3113 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
3113 SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
3114 SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
3115 SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD),
3116 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), 3114 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
3117 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), 3115 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
3118 SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD),
3119 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD),
3120 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
3121 {} 3116 {}
3122}; 3117};
3123 3118
@@ -3422,6 +3417,9 @@ static void cx_auto_hp_automute(struct hda_codec *codec)
3422 AC_VERB_SET_PIN_WIDGET_CONTROL, 3417 AC_VERB_SET_PIN_WIDGET_CONTROL,
3423 present ? 0 : PIN_OUT); 3418 present ? 0 : PIN_OUT);
3424 } 3419 }
3420 for (i = 0; !present && i < cfg->line_outs; i++)
3421 if (snd_hda_jack_detect(codec, cfg->line_out_pins[i]))
3422 present = 1;
3425 for (i = 0; i < cfg->speaker_outs; i++) { 3423 for (i = 0; i < cfg->speaker_outs; i++) {
3426 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, 3424 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
3427 AC_VERB_SET_PIN_WIDGET_CONTROL, 3425 AC_VERB_SET_PIN_WIDGET_CONTROL,
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 31df7747990d..f29b97b5de8f 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -31,10 +31,15 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/moduleparam.h>
34#include <sound/core.h> 35#include <sound/core.h>
35#include "hda_codec.h" 36#include "hda_codec.h"
36#include "hda_local.h" 37#include "hda_local.h"
37 38
39static bool static_hdmi_pcm;
40module_param(static_hdmi_pcm, bool, 0644);
41MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
42
38/* 43/*
39 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device 44 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
40 * could support two independent pipes, each of them can be connected to one or 45 * could support two independent pipes, each of them can be connected to one or
@@ -827,7 +832,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
827 *codec_pars = *hinfo; 832 *codec_pars = *hinfo;
828 833
829 eld = &spec->sink_eld[idx]; 834 eld = &spec->sink_eld[idx];
830 if (eld->sad_count > 0) { 835 if (!static_hdmi_pcm && eld->eld_valid && eld->sad_count > 0) {
831 hdmi_eld_update_pcm_info(eld, hinfo, codec_pars); 836 hdmi_eld_update_pcm_info(eld, hinfo, codec_pars);
832 if (hinfo->channels_min > hinfo->channels_max || 837 if (hinfo->channels_min > hinfo->channels_max ||
833 !hinfo->rates || !hinfo->formats) 838 !hinfo->rates || !hinfo->formats)
@@ -904,23 +909,28 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
904 spec->pin[spec->num_pins] = pin_nid; 909 spec->pin[spec->num_pins] = pin_nid;
905 spec->num_pins++; 910 spec->num_pins++;
906 911
907 /*
908 * It is assumed that converter nodes come first in the node list and
909 * hence have been registered and usable now.
910 */
911 return hdmi_read_pin_conn(codec, pin_nid); 912 return hdmi_read_pin_conn(codec, pin_nid);
912} 913}
913 914
914static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid) 915static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
915{ 916{
917 int i, found_pin = 0;
916 struct hdmi_spec *spec = codec->spec; 918 struct hdmi_spec *spec = codec->spec;
917 919
918 if (spec->num_cvts >= MAX_HDMI_CVTS) { 920 for (i = 0; i < spec->num_pins; i++)
919 snd_printk(KERN_WARNING 921 if (nid == spec->pin_cvt[i]) {
920 "HDMI: no space for converter %d\n", nid); 922 found_pin = 1;
921 return -E2BIG; 923 break;
924 }
925
926 if (!found_pin) {
927 snd_printdd("HDMI: Skipping node %d (no connection)\n", nid);
928 return -EINVAL;
922 } 929 }
923 930
931 if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
932 return -E2BIG;
933
924 spec->cvt[spec->num_cvts] = nid; 934 spec->cvt[spec->num_cvts] = nid;
925 spec->num_cvts++; 935 spec->num_cvts++;
926 936
@@ -931,6 +941,8 @@ static int hdmi_parse_codec(struct hda_codec *codec)
931{ 941{
932 hda_nid_t nid; 942 hda_nid_t nid;
933 int i, nodes; 943 int i, nodes;
944 int num_tmp_cvts = 0;
945 hda_nid_t tmp_cvt[MAX_HDMI_CVTS];
934 946
935 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); 947 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
936 if (!nid || nodes < 0) { 948 if (!nid || nodes < 0) {
@@ -941,6 +953,7 @@ static int hdmi_parse_codec(struct hda_codec *codec)
941 for (i = 0; i < nodes; i++, nid++) { 953 for (i = 0; i < nodes; i++, nid++) {
942 unsigned int caps; 954 unsigned int caps;
943 unsigned int type; 955 unsigned int type;
956 unsigned int config;
944 957
945 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); 958 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
946 type = get_wcaps_type(caps); 959 type = get_wcaps_type(caps);
@@ -950,17 +963,32 @@ static int hdmi_parse_codec(struct hda_codec *codec)
950 963
951 switch (type) { 964 switch (type) {
952 case AC_WID_AUD_OUT: 965 case AC_WID_AUD_OUT:
953 hdmi_add_cvt(codec, nid); 966 if (num_tmp_cvts >= MAX_HDMI_CVTS) {
967 snd_printk(KERN_WARNING
968 "HDMI: no space for converter %d\n", nid);
969 continue;
970 }
971 tmp_cvt[num_tmp_cvts] = nid;
972 num_tmp_cvts++;
954 break; 973 break;
955 case AC_WID_PIN: 974 case AC_WID_PIN:
956 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 975 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
957 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) 976 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
958 continue; 977 continue;
978
979 config = snd_hda_codec_read(codec, nid, 0,
980 AC_VERB_GET_CONFIG_DEFAULT, 0);
981 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
982 continue;
983
959 hdmi_add_pin(codec, nid); 984 hdmi_add_pin(codec, nid);
960 break; 985 break;
961 } 986 }
962 } 987 }
963 988
989 for (i = 0; i < num_tmp_cvts; i++)
990 hdmi_add_cvt(codec, tmp_cvt[i]);
991
964 /* 992 /*
965 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event 993 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
966 * can be lost and presence sense verb will become inaccurate if the 994 * can be lost and presence sense verb will become inaccurate if the
@@ -1165,11 +1193,53 @@ static int nvhdmi_7x_init(struct hda_codec *codec)
1165 return 0; 1193 return 0;
1166} 1194}
1167 1195
1196static unsigned int channels_2_6_8[] = {
1197 2, 6, 8
1198};
1199
1200static unsigned int channels_2_8[] = {
1201 2, 8
1202};
1203
1204static struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = {
1205 .count = ARRAY_SIZE(channels_2_6_8),
1206 .list = channels_2_6_8,
1207 .mask = 0,
1208};
1209
1210static struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = {
1211 .count = ARRAY_SIZE(channels_2_8),
1212 .list = channels_2_8,
1213 .mask = 0,
1214};
1215
1168static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo, 1216static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo,
1169 struct hda_codec *codec, 1217 struct hda_codec *codec,
1170 struct snd_pcm_substream *substream) 1218 struct snd_pcm_substream *substream)
1171{ 1219{
1172 struct hdmi_spec *spec = codec->spec; 1220 struct hdmi_spec *spec = codec->spec;
1221 struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL;
1222
1223 switch (codec->preset->id) {
1224 case 0x10de0002:
1225 case 0x10de0003:
1226 case 0x10de0005:
1227 case 0x10de0006:
1228 hw_constraints_channels = &hw_constraints_2_8_channels;
1229 break;
1230 case 0x10de0007:
1231 hw_constraints_channels = &hw_constraints_2_6_8_channels;
1232 break;
1233 default:
1234 break;
1235 }
1236
1237 if (hw_constraints_channels != NULL) {
1238 snd_pcm_hw_constraint_list(substream->runtime, 0,
1239 SNDRV_PCM_HW_PARAM_CHANNELS,
1240 hw_constraints_channels);
1241 }
1242
1173 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 1243 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1174} 1244}
1175 1245
@@ -1532,7 +1602,7 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = {
1532{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi }, 1602{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
1533{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi }, 1603{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
1534{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi }, 1604{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
1535{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi }, 1605{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_generic_hdmi },
1536{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi }, 1606{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi },
1537{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi }, 1607{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi },
1538{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi }, 1608{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi },
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 552a09e9211f..51c08edd7563 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -231,7 +231,6 @@ enum {
231 ALC888_ACER_ASPIRE_8930G, 231 ALC888_ACER_ASPIRE_8930G,
232 ALC888_ACER_ASPIRE_7730G, 232 ALC888_ACER_ASPIRE_7730G,
233 ALC883_MEDION, 233 ALC883_MEDION,
234 ALC883_MEDION_MD2,
235 ALC883_MEDION_WIM2160, 234 ALC883_MEDION_WIM2160,
236 ALC883_LAPTOP_EAPD, 235 ALC883_LAPTOP_EAPD,
237 ALC883_LENOVO_101E_2ch, 236 ALC883_LENOVO_101E_2ch,
@@ -1678,29 +1677,32 @@ struct alc_pincfg {
1678 u32 val; 1677 u32 val;
1679}; 1678};
1680 1679
1680struct alc_model_fixup {
1681 const int id;
1682 const char *name;
1683};
1684
1681struct alc_fixup { 1685struct alc_fixup {
1682 unsigned int sku; 1686 unsigned int sku;
1683 const struct alc_pincfg *pins; 1687 const struct alc_pincfg *pins;
1684 const struct hda_verb *verbs; 1688 const struct hda_verb *verbs;
1689 void (*func)(struct hda_codec *codec, const struct alc_fixup *fix,
1690 int pre_init);
1685}; 1691};
1686 1692
1687static void alc_pick_fixup(struct hda_codec *codec, 1693static void __alc_pick_fixup(struct hda_codec *codec,
1688 const struct snd_pci_quirk *quirk, 1694 const struct alc_fixup *fix,
1689 const struct alc_fixup *fix, 1695 const char *modelname,
1690 int pre_init) 1696 int pre_init)
1691{ 1697{
1692 const struct alc_pincfg *cfg; 1698 const struct alc_pincfg *cfg;
1693 struct alc_spec *spec; 1699 struct alc_spec *spec;
1694 1700
1695 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1696 if (!quirk)
1697 return;
1698 fix += quirk->value;
1699 cfg = fix->pins; 1701 cfg = fix->pins;
1700 if (pre_init && fix->sku) { 1702 if (pre_init && fix->sku) {
1701#ifdef CONFIG_SND_DEBUG_VERBOSE 1703#ifdef CONFIG_SND_DEBUG_VERBOSE
1702 snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n", 1704 snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n",
1703 codec->chip_name, quirk->name); 1705 codec->chip_name, modelname);
1704#endif 1706#endif
1705 spec = codec->spec; 1707 spec = codec->spec;
1706 spec->cdefine.sku_cfg = fix->sku; 1708 spec->cdefine.sku_cfg = fix->sku;
@@ -1709,7 +1711,7 @@ static void alc_pick_fixup(struct hda_codec *codec,
1709 if (pre_init && cfg) { 1711 if (pre_init && cfg) {
1710#ifdef CONFIG_SND_DEBUG_VERBOSE 1712#ifdef CONFIG_SND_DEBUG_VERBOSE
1711 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", 1713 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n",
1712 codec->chip_name, quirk->name); 1714 codec->chip_name, modelname);
1713#endif 1715#endif
1714 for (; cfg->nid; cfg++) 1716 for (; cfg->nid; cfg++)
1715 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1717 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val);
@@ -1717,10 +1719,53 @@ static void alc_pick_fixup(struct hda_codec *codec,
1717 if (!pre_init && fix->verbs) { 1719 if (!pre_init && fix->verbs) {
1718#ifdef CONFIG_SND_DEBUG_VERBOSE 1720#ifdef CONFIG_SND_DEBUG_VERBOSE
1719 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", 1721 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n",
1720 codec->chip_name, quirk->name); 1722 codec->chip_name, modelname);
1721#endif 1723#endif
1722 add_verb(codec->spec, fix->verbs); 1724 add_verb(codec->spec, fix->verbs);
1723 } 1725 }
1726 if (fix->func) {
1727#ifdef CONFIG_SND_DEBUG_VERBOSE
1728 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n",
1729 codec->chip_name, modelname);
1730#endif
1731 fix->func(codec, fix, pre_init);
1732 }
1733}
1734
1735static void alc_pick_fixup(struct hda_codec *codec,
1736 const struct snd_pci_quirk *quirk,
1737 const struct alc_fixup *fix,
1738 int pre_init)
1739{
1740 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1741 if (quirk) {
1742 fix += quirk->value;
1743#ifdef CONFIG_SND_DEBUG_VERBOSE
1744 __alc_pick_fixup(codec, fix, quirk->name, pre_init);
1745#else
1746 __alc_pick_fixup(codec, fix, NULL, pre_init);
1747#endif
1748 }
1749}
1750
1751static void alc_pick_fixup_model(struct hda_codec *codec,
1752 const struct alc_model_fixup *models,
1753 const struct snd_pci_quirk *quirk,
1754 const struct alc_fixup *fix,
1755 int pre_init)
1756{
1757 if (codec->modelname && models) {
1758 while (models->name) {
1759 if (!strcmp(codec->modelname, models->name)) {
1760 fix += models->id;
1761 break;
1762 }
1763 models++;
1764 }
1765 __alc_pick_fixup(codec, fix, codec->modelname, pre_init);
1766 } else {
1767 alc_pick_fixup(codec, quirk, fix, pre_init);
1768 }
1724} 1769}
1725 1770
1726static int alc_read_coef_idx(struct hda_codec *codec, 1771static int alc_read_coef_idx(struct hda_codec *codec,
@@ -1981,6 +2026,7 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1981 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2026 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1982 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2027 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1983 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2028 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2029 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1984 { } 2030 { }
1985}; 2031};
1986 2032
@@ -2120,17 +2166,17 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2120 { 2166 {
2121 .num_items = 5, 2167 .num_items = 5,
2122 .items = { 2168 .items = {
2123 { "Ext Mic", 0x0 }, 2169 { "Mic", 0x0 },
2124 { "Line In", 0x2 }, 2170 { "Line In", 0x2 },
2125 { "CD", 0x4 }, 2171 { "CD", 0x4 },
2126 { "Input Mix", 0xa }, 2172 { "Input Mix", 0xa },
2127 { "Int Mic", 0xb }, 2173 { "Internal Mic", 0xb },
2128 }, 2174 },
2129 }, 2175 },
2130 { 2176 {
2131 .num_items = 4, 2177 .num_items = 4,
2132 .items = { 2178 .items = {
2133 { "Ext Mic", 0x0 }, 2179 { "Mic", 0x0 },
2134 { "Line In", 0x2 }, 2180 { "Line In", 0x2 },
2135 { "CD", 0x4 }, 2181 { "CD", 0x4 },
2136 { "Input Mix", 0xa }, 2182 { "Input Mix", 0xa },
@@ -2187,7 +2233,7 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
2187 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2233 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2188 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2234 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2189 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2190 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 2236 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2237 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2192 { } /* end */ 2238 { } /* end */
2193}; 2239};
@@ -2205,7 +2251,7 @@ static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2205 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2206 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2207 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2208 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 2254 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2209 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2210 { } /* end */ 2256 { } /* end */
2211}; 2257};
@@ -2796,10 +2842,10 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2796 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2842 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2797 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2843 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2798 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2844 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2799 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2845 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2800 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2846 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2801 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2847 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2802 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2848 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2803 { } /* end */ 2849 { } /* end */
2804}; 2850};
2805 2851
@@ -3307,7 +3353,7 @@ static struct hda_verb alc880_beep_init_verbs[] = {
3307}; 3353};
3308 3354
3309/* auto-toggle front mic */ 3355/* auto-toggle front mic */
3310static void alc880_uniwill_mic_automute(struct hda_codec *codec) 3356static void alc88x_simple_mic_automute(struct hda_codec *codec)
3311{ 3357{
3312 unsigned int present; 3358 unsigned int present;
3313 unsigned char bits; 3359 unsigned char bits;
@@ -3329,7 +3375,7 @@ static void alc880_uniwill_setup(struct hda_codec *codec)
3329static void alc880_uniwill_init_hook(struct hda_codec *codec) 3375static void alc880_uniwill_init_hook(struct hda_codec *codec)
3330{ 3376{
3331 alc_automute_amp(codec); 3377 alc_automute_amp(codec);
3332 alc880_uniwill_mic_automute(codec); 3378 alc88x_simple_mic_automute(codec);
3333} 3379}
3334 3380
3335static void alc880_uniwill_unsol_event(struct hda_codec *codec, 3381static void alc880_uniwill_unsol_event(struct hda_codec *codec,
@@ -3340,7 +3386,7 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3340 */ 3386 */
3341 switch (res >> 28) { 3387 switch (res >> 28) {
3342 case ALC880_MIC_EVENT: 3388 case ALC880_MIC_EVENT:
3343 alc880_uniwill_mic_automute(codec); 3389 alc88x_simple_mic_automute(codec);
3344 break; 3390 break;
3345 default: 3391 default:
3346 alc_automute_amp_unsol_event(codec, res); 3392 alc_automute_amp_unsol_event(codec, res);
@@ -5023,6 +5069,25 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5023 return 0; 5069 return 0;
5024} 5070}
5025 5071
5072static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5073 bool can_be_master)
5074{
5075 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5076 return "Master";
5077
5078 switch (cfg->line_out_type) {
5079 case AUTO_PIN_SPEAKER_OUT:
5080 return "Speaker";
5081 case AUTO_PIN_HP_OUT:
5082 return "Headphone";
5083 default:
5084 if (cfg->line_outs == 1)
5085 return "PCM";
5086 break;
5087 }
5088 return NULL;
5089}
5090
5026/* add playback controls from the parsed DAC table */ 5091/* add playback controls from the parsed DAC table */
5027static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 5092static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5028 const struct auto_pin_cfg *cfg) 5093 const struct auto_pin_cfg *cfg)
@@ -5030,6 +5095,7 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5030 static const char *chname[4] = { 5095 static const char *chname[4] = {
5031 "Front", "Surround", NULL /*CLFE*/, "Side" 5096 "Front", "Surround", NULL /*CLFE*/, "Side"
5032 }; 5097 };
5098 const char *pfx = alc_get_line_out_pfx(cfg, false);
5033 hda_nid_t nid; 5099 hda_nid_t nid;
5034 int i, err; 5100 int i, err;
5035 5101
@@ -5037,7 +5103,7 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5037 if (!spec->multiout.dac_nids[i]) 5103 if (!spec->multiout.dac_nids[i])
5038 continue; 5104 continue;
5039 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 5105 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5040 if (i == 2) { 5106 if (!pfx && i == 2) {
5041 /* Center/LFE */ 5107 /* Center/LFE */
5042 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5108 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5043 "Center", 5109 "Center",
@@ -5064,18 +5130,17 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5064 if (err < 0) 5130 if (err < 0)
5065 return err; 5131 return err;
5066 } else { 5132 } else {
5067 const char *pfx; 5133 const char *name = pfx;
5068 if (cfg->line_outs == 1 && 5134 if (!name)
5069 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 5135 name = chname[i];
5070 pfx = "Speaker"; 5136 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5071 else 5137 name, i,
5072 pfx = chname[i];
5073 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5074 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 5138 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5075 HDA_OUTPUT)); 5139 HDA_OUTPUT));
5076 if (err < 0) 5140 if (err < 0)
5077 return err; 5141 return err;
5078 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 5142 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5143 name, i,
5079 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 5144 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5080 HDA_INPUT)); 5145 HDA_INPUT));
5081 if (err < 0) 5146 if (err < 0)
@@ -5155,7 +5220,8 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec,
5155{ 5220{
5156 struct alc_spec *spec = codec->spec; 5221 struct alc_spec *spec = codec->spec;
5157 struct hda_input_mux *imux = &spec->private_imux[0]; 5222 struct hda_input_mux *imux = &spec->private_imux[0];
5158 int i, err, idx, type, type_idx = 0; 5223 int i, err, idx, type_idx = 0;
5224 const char *prev_label = NULL;
5159 5225
5160 for (i = 0; i < cfg->num_inputs; i++) { 5226 for (i = 0; i < cfg->num_inputs; i++) {
5161 hda_nid_t pin; 5227 hda_nid_t pin;
@@ -5165,12 +5231,13 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec,
5165 if (!alc_is_input_pin(codec, pin)) 5231 if (!alc_is_input_pin(codec, pin))
5166 continue; 5232 continue;
5167 5233
5168 type = cfg->inputs[i].type; 5234 label = hda_get_autocfg_input_label(codec, cfg, i);
5169 if (i > 0 && type == cfg->inputs[i - 1].type) 5235 if (prev_label && !strcmp(label, prev_label))
5170 type_idx++; 5236 type_idx++;
5171 else 5237 else
5172 type_idx = 0; 5238 type_idx = 0;
5173 label = hda_get_autocfg_input_label(codec, cfg, i); 5239 prev_label = label;
5240
5174 if (mixer) { 5241 if (mixer) {
5175 idx = get_connection_index(codec, mixer, pin); 5242 idx = get_connection_index(codec, mixer, pin);
5176 if (idx >= 0) { 5243 if (idx >= 0) {
@@ -7406,7 +7473,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7406 .num_items = 4, 7473 .num_items = 4,
7407 .items = { 7474 .items = {
7408 { "Mic", 0x0 }, 7475 { "Mic", 0x0 },
7409 { "Int Mic", 0x1 }, 7476 { "Internal Mic", 0x1 },
7410 { "Line", 0x2 }, 7477 { "Line", 0x2 },
7411 { "CD", 0x4 }, 7478 { "CD", 0x4 },
7412 }, 7479 },
@@ -7416,7 +7483,7 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7416 .num_items = 2, 7483 .num_items = 2,
7417 .items = { 7484 .items = {
7418 { "Mic", 0x0 }, 7485 { "Mic", 0x0 },
7419 { "Int Mic", 0x1 }, 7486 { "Internal Mic", 0x1 },
7420 }, 7487 },
7421}; 7488};
7422 7489
@@ -7851,10 +7918,10 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
7851 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7918 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7852 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7919 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7853 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7920 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7854 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7921 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7855 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7922 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7856 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7923 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7857 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7924 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
7858 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7925 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7859 { } /* end */ 7926 { } /* end */
7860}; 7927};
@@ -7878,8 +7945,8 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7878 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7945 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7879 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 7946 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7880 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 7947 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7881 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 7948 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7882 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 7949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
7883 { } /* end */ 7950 { } /* end */
7884}; 7951};
7885 7952
@@ -7896,8 +7963,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7896 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7963 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 7964 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7898 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 7965 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7899 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7966 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7900 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT), 7967 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
7901 { } /* end */ 7968 { } /* end */
7902}; 7969};
7903 7970
@@ -7912,7 +7979,7 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7912 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 7979 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7913 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 7980 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7914 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 7981 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7915 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 7982 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7916 { } /* end */ 7983 { } /* end */
7917}; 7984};
7918 7985
@@ -7931,7 +7998,7 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7931 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7998 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7932 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7999 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8000 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7934 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8001 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8002 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7936 { } /* end */ 8003 { } /* end */
7937}; 8004};
@@ -7946,10 +8013,10 @@ static struct snd_kcontrol_new alc882_targa_mixer[] = {
7946 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8013 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7947 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8014 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7948 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8015 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7949 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8016 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7950 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8017 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7951 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8018 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7952 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8019 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
7953 { } /* end */ 8020 { } /* end */
7954}; 8021};
7955 8022
@@ -7969,7 +8036,7 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7969 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 8036 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7970 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8037 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7971 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8038 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7972 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8039 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7973 { } /* end */ 8040 { } /* end */
7974}; 8041};
7975 8042
@@ -7982,7 +8049,7 @@ static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7982 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8049 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7983 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8050 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7984 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7985 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8052 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7986 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7987 { } /* end */ 8054 { } /* end */
7988}; 8055};
@@ -8763,10 +8830,10 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8763 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8830 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8764 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8831 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8765 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8766 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8833 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8767 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8768 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8835 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8769 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8836 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8770 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8837 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8771 { } /* end */ 8838 { } /* end */
8772}; 8839};
@@ -8777,11 +8844,11 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8777 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8844 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8778 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8845 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8779 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8846 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8780 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8847 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8781 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8848 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8782 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8849 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8783 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8850 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8784 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8851 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8785 { } /* end */ 8852 { } /* end */
8786}; 8853};
8787 8854
@@ -8791,11 +8858,11 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8791 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8858 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8792 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8859 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8793 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8794 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8861 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8795 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8862 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8796 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8863 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8797 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8864 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8798 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8865 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8799 { } /* end */ 8866 { } /* end */
8800}; 8867};
8801 8868
@@ -8808,10 +8875,10 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8808 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8875 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8809 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8876 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8810 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8877 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8811 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8878 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8812 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8879 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8813 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8880 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8814 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8881 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8815 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8882 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8816 { } /* end */ 8883 { } /* end */
8817}; 8884};
@@ -8831,10 +8898,10 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8831 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8898 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8832 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8899 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8833 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8900 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8834 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8901 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8835 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8836 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8903 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8837 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8904 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8838 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8905 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8839 { } /* end */ 8906 { } /* end */
8840}; 8907};
@@ -8855,10 +8922,10 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8855 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8922 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8856 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8923 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8857 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8924 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8858 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 8925 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
8859 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8926 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8860 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8927 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8861 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8928 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
8862 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8929 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8863 { } /* end */ 8930 { } /* end */
8864}; 8931};
@@ -8879,10 +8946,10 @@ static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8879 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8946 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8880 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8947 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8881 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 8948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8882 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT), 8949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
8883 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 8950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8884 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8885 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8952 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
8886 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8887 { } /* end */ 8954 { } /* end */
8888}; 8955};
@@ -8902,10 +8969,10 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8902 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8903 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8904 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8905 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8972 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8906 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8973 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8907 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8974 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8908 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8975 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8909 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8976 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8910 { } /* end */ 8977 { } /* end */
8911}; 8978};
@@ -8926,7 +8993,7 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = {
8926 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8993 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8927 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8994 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8928 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8929 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8996 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8930 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8997 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8931 { } /* end */ 8998 { } /* end */
8932}; 8999};
@@ -8939,20 +9006,20 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
8939 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9006 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8940 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9007 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8941 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9008 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8942 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9009 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8943 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9010 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8944 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9011 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8945 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 9012 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8946 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9013 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8947 { } /* end */ 9014 { } /* end */
8948}; 9015};
8949 9016
8950static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 9017static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8951 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9018 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8952 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 9019 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8953 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9020 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8954 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 9021 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8955 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9022 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8956 { } /* end */ 9023 { } /* end */
8957}; 9024};
8958 9025
@@ -8963,7 +9030,7 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8963 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 9030 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8964 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8965 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9032 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8966 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9033 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8967 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9034 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8968 { } /* end */ 9035 { } /* end */
8969}; 9036};
@@ -8976,21 +9043,8 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8976 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9043 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8977 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9044 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9045 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9046 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8980 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9047 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8981 { } /* end */
8982};
8983
8984static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8985 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8986 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8987 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8988 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8989 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8990 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8992 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8993 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8994 { } /* end */ 9048 { } /* end */
8995}; 9049};
8996 9050
@@ -9037,7 +9091,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9037 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9091 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9038 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9092 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9039 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9040 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9094 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9041 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9095 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9042 { } /* end */ 9096 { } /* end */
9043}; 9097};
@@ -9050,7 +9104,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9050 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9104 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9051 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9105 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9106 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9053 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9107 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9054 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9108 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9055 { } /* end */ 9109 { } /* end */
9056}; 9110};
@@ -9072,10 +9126,10 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9072 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9126 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9073 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9127 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9074 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9075 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9129 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9076 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9130 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9077 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9131 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9078 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9132 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9079 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9133 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9080 { } /* end */ 9134 { } /* end */
9081}; 9135};
@@ -9096,8 +9150,8 @@ static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9096 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), 9150 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9097 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), 9151 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9098 /* Boost mixers */ 9152 /* Boost mixers */
9099 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 9153 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9100 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 9154 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9101 /* Input mixers */ 9155 /* Input mixers */
9102 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 9156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9103 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 9157 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
@@ -9111,7 +9165,7 @@ static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9111 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9165 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9112 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9166 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9114 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 9168 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9115 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9169 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9116 { } /* end */ 9170 { } /* end */
9117}; 9171};
@@ -9141,7 +9195,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9141 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9195 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9142 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9196 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9197 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9144 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9198 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9146 { } /* end */ 9200 { } /* end */
9147}; 9201};
@@ -9182,16 +9236,6 @@ static void alc883_mitac_setup(struct hda_codec *codec)
9182 spec->autocfg.speaker_pins[1] = 0x17; 9236 spec->autocfg.speaker_pins[1] = 0x17;
9183} 9237}
9184 9238
9185/* auto-toggle front mic */
9186/*
9187static void alc883_mitac_mic_automute(struct hda_codec *codec)
9188{
9189 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
9190
9191 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
9192}
9193*/
9194
9195static struct hda_verb alc883_mitac_verbs[] = { 9239static struct hda_verb alc883_mitac_verbs[] = {
9196 /* HP */ 9240 /* HP */
9197 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9241 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -9435,18 +9479,8 @@ static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9435 alc888_lenovo_ms7195_rca_automute(codec); 9479 alc888_lenovo_ms7195_rca_automute(codec);
9436} 9480}
9437 9481
9438static struct hda_verb alc883_medion_md2_verbs[] = {
9439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9440 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9441
9442 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9443
9444 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9445 { } /* end */
9446};
9447
9448/* toggle speaker-output according to the hp-jack state */ 9482/* toggle speaker-output according to the hp-jack state */
9449static void alc883_medion_md2_setup(struct hda_codec *codec) 9483static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9450{ 9484{
9451 struct alc_spec *spec = codec->spec; 9485 struct alc_spec *spec = codec->spec;
9452 9486
@@ -9458,15 +9492,6 @@ static void alc883_medion_md2_setup(struct hda_codec *codec)
9458#define alc883_targa_init_hook alc882_targa_init_hook 9492#define alc883_targa_init_hook alc882_targa_init_hook
9459#define alc883_targa_unsol_event alc882_targa_unsol_event 9493#define alc883_targa_unsol_event alc882_targa_unsol_event
9460 9494
9461static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9462{
9463 unsigned int present;
9464
9465 present = snd_hda_jack_detect(codec, 0x18);
9466 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9467 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9468}
9469
9470static void alc883_clevo_m720_setup(struct hda_codec *codec) 9495static void alc883_clevo_m720_setup(struct hda_codec *codec)
9471{ 9496{
9472 struct alc_spec *spec = codec->spec; 9497 struct alc_spec *spec = codec->spec;
@@ -9478,7 +9503,7 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec)
9478static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9503static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9479{ 9504{
9480 alc_automute_amp(codec); 9505 alc_automute_amp(codec);
9481 alc883_clevo_m720_mic_automute(codec); 9506 alc88x_simple_mic_automute(codec);
9482} 9507}
9483 9508
9484static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 9509static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
@@ -9486,7 +9511,7 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9486{ 9511{
9487 switch (res >> 26) { 9512 switch (res >> 26) {
9488 case ALC880_MIC_EVENT: 9513 case ALC880_MIC_EVENT:
9489 alc883_clevo_m720_mic_automute(codec); 9514 alc88x_simple_mic_automute(codec);
9490 break; 9515 break;
9491 default: 9516 default:
9492 alc_automute_amp_unsol_event(codec, res); 9517 alc_automute_amp_unsol_event(codec, res);
@@ -9731,7 +9756,6 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
9731 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 9756 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9732 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 9757 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9733 [ALC883_MEDION] = "medion", 9758 [ALC883_MEDION] = "medion",
9734 [ALC883_MEDION_MD2] = "medion-md2",
9735 [ALC883_MEDION_WIM2160] = "medion-wim2160", 9759 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9736 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 9760 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9737 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 9761 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
@@ -10379,19 +10403,6 @@ static struct alc_config_preset alc882_presets[] = {
10379 .channel_mode = alc883_sixstack_modes, 10403 .channel_mode = alc883_sixstack_modes,
10380 .input_mux = &alc883_capture_source, 10404 .input_mux = &alc883_capture_source,
10381 }, 10405 },
10382 [ALC883_MEDION_MD2] = {
10383 .mixers = { alc883_medion_md2_mixer},
10384 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10385 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10386 .dac_nids = alc883_dac_nids,
10387 .dig_out_nid = ALC883_DIGOUT_NID,
10388 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10389 .channel_mode = alc883_3ST_2ch_modes,
10390 .input_mux = &alc883_capture_source,
10391 .unsol_event = alc_automute_amp_unsol_event,
10392 .setup = alc883_medion_md2_setup,
10393 .init_hook = alc_automute_amp,
10394 },
10395 [ALC883_MEDION_WIM2160] = { 10406 [ALC883_MEDION_WIM2160] = {
10396 .mixers = { alc883_medion_wim2160_mixer }, 10407 .mixers = { alc883_medion_wim2160_mixer },
10397 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, 10408 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
@@ -10468,7 +10479,7 @@ static struct alc_config_preset alc882_presets[] = {
10468 .need_dac_fix = 1, 10479 .need_dac_fix = 1,
10469 .input_mux = &alc883_lenovo_nb0763_capture_source, 10480 .input_mux = &alc883_lenovo_nb0763_capture_source,
10470 .unsol_event = alc_automute_amp_unsol_event, 10481 .unsol_event = alc_automute_amp_unsol_event,
10471 .setup = alc883_medion_md2_setup, 10482 .setup = alc883_lenovo_nb0763_setup,
10472 .init_hook = alc_automute_amp, 10483 .init_hook = alc_automute_amp,
10473 }, 10484 },
10474 [ALC888_LENOVO_MS7195_DIG] = { 10485 [ALC888_LENOVO_MS7195_DIG] = {
@@ -10830,25 +10841,30 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
10830{ 10841{
10831 struct alc_spec *spec = codec->spec; 10842 struct alc_spec *spec = codec->spec;
10832 struct auto_pin_cfg *cfg = &spec->autocfg; 10843 struct auto_pin_cfg *cfg = &spec->autocfg;
10833 int i, err, type; 10844 int i, err;
10834 int type_idx = 0; 10845 int type_idx = 0;
10835 hda_nid_t nid; 10846 hda_nid_t nid;
10847 const char *prev_label = NULL;
10836 10848
10837 for (i = 0; i < cfg->num_inputs; i++) { 10849 for (i = 0; i < cfg->num_inputs; i++) {
10838 if (cfg->inputs[i].type > AUTO_PIN_MIC) 10850 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10839 break; 10851 break;
10840 nid = cfg->inputs[i].pin; 10852 nid = cfg->inputs[i].pin;
10841 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { 10853 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10842 char label[32]; 10854 const char *label;
10843 type = cfg->inputs[i].type; 10855 char boost_label[32];
10844 if (i > 0 && type == cfg->inputs[i - 1].type) 10856
10857 label = hda_get_autocfg_input_label(codec, cfg, i);
10858 if (prev_label && !strcmp(label, prev_label))
10845 type_idx++; 10859 type_idx++;
10846 else 10860 else
10847 type_idx = 0; 10861 type_idx = 0;
10848 snprintf(label, sizeof(label), "%s Boost", 10862 prev_label = label;
10849 hda_get_autocfg_input_label(codec, cfg, i)); 10863
10850 err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 10864 snprintf(boost_label, sizeof(boost_label),
10851 type_idx, 10865 "%s Boost Volume", label);
10866 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10867 boost_label, type_idx,
10852 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 10868 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10853 if (err < 0) 10869 if (err < 0)
10854 return err; 10870 return err;
@@ -10857,6 +10873,9 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
10857 return 0; 10873 return 0;
10858} 10874}
10859 10875
10876static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
10877 const struct auto_pin_cfg *cfg);
10878
10860/* almost identical with ALC880 parser... */ 10879/* almost identical with ALC880 parser... */
10861static int alc882_parse_auto_config(struct hda_codec *codec) 10880static int alc882_parse_auto_config(struct hda_codec *codec)
10862{ 10881{
@@ -10874,7 +10893,10 @@ static int alc882_parse_auto_config(struct hda_codec *codec)
10874 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); 10893 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
10875 if (err < 0) 10894 if (err < 0)
10876 return err; 10895 return err;
10877 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); 10896 if (codec->vendor_id == 0x10ec0887)
10897 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
10898 else
10899 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
10878 if (err < 0) 10900 if (err < 0)
10879 return err; 10901 return err;
10880 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], 10902 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
@@ -11090,10 +11112,10 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
11090 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11112 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11113 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11114 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11093 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11094 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11116 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11095 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11117 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11096 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11118 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 11119 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11120 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11099 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 11121 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
@@ -11194,10 +11216,10 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11194 HDA_OUTPUT), 11216 HDA_OUTPUT),
11195 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11217 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11196 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11218 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11197 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11219 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11198 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11220 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11199 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11221 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11200 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11222 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11201 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11223 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11202 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11224 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11203 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11225 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -11219,7 +11241,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11219 HDA_OUTPUT), 11241 HDA_OUTPUT),
11220 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 11242 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11221 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 11243 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11222 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 11244 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11223 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11245 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11224 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11246 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11225 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11247 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -11230,7 +11252,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11230static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 11252static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11231 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11253 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11232 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11254 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11233 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 11255 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11234 { } /* end */ 11256 { } /* end */
11235}; 11257};
11236 11258
@@ -11250,7 +11272,7 @@ static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11250 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11272 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11251 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11273 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11252 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11274 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11253 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11275 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11254 { } /* end */ 11276 { } /* end */
11255}; 11277};
11256 11278
@@ -11357,10 +11379,10 @@ static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11357 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11379 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11358 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11380 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11359 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11381 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11360 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11382 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11361 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11383 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11362 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11384 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11363 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11385 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11364 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11386 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11365 { } /* end */ 11387 { } /* end */
11366}; 11388};
@@ -11374,10 +11396,10 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11374 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11396 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11375 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11397 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11376 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11398 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11377 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11399 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11378 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11400 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11379 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11401 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11380 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11402 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11381 { } /* end */ 11403 { } /* end */
11382}; 11404};
11383 11405
@@ -11445,10 +11467,10 @@ static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11445 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11467 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11446 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11447 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11448 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11470 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11449 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11471 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11450 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11472 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11451 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11473 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11452 { } /* end */ 11474 { } /* end */
11453}; 11475};
11454 11476
@@ -11632,7 +11654,7 @@ static struct snd_kcontrol_new alc262_nec_mixer[] = {
11632 11654
11633 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11634 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11635 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11657 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11636 11658
11637 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11659 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11638 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11660 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -11687,7 +11709,7 @@ static struct hda_input_mux alc262_fujitsu_capture_source = {
11687 .num_items = 3, 11709 .num_items = 3,
11688 .items = { 11710 .items = {
11689 { "Mic", 0x0 }, 11711 { "Mic", 0x0 },
11690 { "Int Mic", 0x1 }, 11712 { "Internal Mic", 0x1 },
11691 { "CD", 0x4 }, 11713 { "CD", 0x4 },
11692 }, 11714 },
11693}; 11715};
@@ -11839,12 +11861,12 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11839 }, 11861 },
11840 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11862 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11841 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11863 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11842 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11864 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11843 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11865 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11844 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11866 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11845 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11867 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11846 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11868 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11847 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11869 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11848 { } /* end */ 11870 { } /* end */
11849}; 11871};
11850 11872
@@ -11875,12 +11897,12 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11875 }, 11897 },
11876 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11898 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11877 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11899 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11878 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11900 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11879 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11901 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11880 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11902 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11881 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11903 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11882 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11904 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11883 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11905 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11884 { } /* end */ 11906 { } /* end */
11885}; 11907};
11886 11908
@@ -11889,10 +11911,10 @@ static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11889 ALC262_HIPPO_MASTER_SWITCH, 11911 ALC262_HIPPO_MASTER_SWITCH,
11890 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11912 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11891 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11913 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11892 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11914 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11893 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11915 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11894 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11916 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11895 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11917 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11896 { } /* end */ 11918 { } /* end */
11897}; 11919};
11898 11920
@@ -11918,8 +11940,8 @@ static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11918 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11940 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11941 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11942 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11921 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 11943 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11922 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT), 11944 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
11923 { } /* end */ 11945 { } /* end */
11924}; 11946};
11925 11947
@@ -12089,13 +12111,8 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12089 spec->multiout.dac_nids = spec->private_dac_nids; 12111 spec->multiout.dac_nids = spec->private_dac_nids;
12090 spec->multiout.dac_nids[0] = 2; 12112 spec->multiout.dac_nids[0] = 2;
12091 12113
12092 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 12114 pfx = alc_get_line_out_pfx(cfg, true);
12093 pfx = "Master"; 12115 if (!pfx)
12094 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12095 pfx = "Speaker";
12096 else if (cfg->line_out_type == AUTO_PIN_HP_OUT)
12097 pfx = "Headphone";
12098 else
12099 pfx = "Front"; 12116 pfx = "Front";
12100 for (i = 0; i < 2; i++) { 12117 for (i = 0; i < 2; i++) {
12101 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i); 12118 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
@@ -12996,9 +13013,9 @@ static struct snd_kcontrol_new alc268_base_mixer[] = {
12996 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13013 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12997 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13014 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12998 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13015 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12999 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13016 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13000 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13017 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13001 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13018 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13002 { } 13019 { }
13003}; 13020};
13004 13021
@@ -13007,9 +13024,9 @@ static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13007 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13024 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13008 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13025 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13009 ALC262_HIPPO_MASTER_SWITCH, 13026 ALC262_HIPPO_MASTER_SWITCH,
13010 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13027 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13011 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13028 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13012 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13029 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13013 { } 13030 { }
13014}; 13031};
13015 13032
@@ -13113,9 +13130,9 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
13113 .put = alc268_acer_master_sw_put, 13130 .put = alc268_acer_master_sw_put,
13114 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13131 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13115 }, 13132 },
13116 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13133 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13117 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13134 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13118 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13135 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13119 { } 13136 { }
13120}; 13137};
13121 13138
@@ -13131,8 +13148,8 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13131 .put = alc268_acer_master_sw_put, 13148 .put = alc268_acer_master_sw_put,
13132 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13149 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13133 }, 13150 },
13134 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13151 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13135 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13152 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13136 { } 13153 { }
13137}; 13154};
13138 13155
@@ -13224,8 +13241,8 @@ static struct snd_kcontrol_new alc268_dell_mixer[] = {
13224 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13241 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13225 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13242 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13226 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13243 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13227 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13244 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13228 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13245 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13229 { } 13246 { }
13230}; 13247};
13231 13248
@@ -13258,8 +13275,8 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13275 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13259 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13276 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13260 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 13277 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13261 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 13278 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13262 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 13279 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13263 { } 13280 { }
13264}; 13281};
13265 13282
@@ -14082,10 +14099,10 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {
14082 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14099 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14084 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14101 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14085 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14102 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14086 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14103 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14087 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14104 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14088 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 14105 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14089 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14106 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14090 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 14107 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14091 { } /* end */ 14108 { } /* end */
@@ -14105,10 +14122,10 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14105 }, 14122 },
14106 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14123 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14107 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14124 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14108 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14125 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14109 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14126 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14110 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14127 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14111 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 14128 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14112 { } 14129 { }
14113}; 14130};
14114 14131
@@ -14126,13 +14143,13 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14126 }, 14143 },
14127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14144 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14128 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14145 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14129 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14146 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14130 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14147 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14131 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14148 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14132 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 14149 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14133 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 14150 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14134 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 14151 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14135 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), 14152 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14136 { } 14153 { }
14137}; 14154};
14138 14155
@@ -14162,30 +14179,30 @@ static struct snd_kcontrol_new alc269_asus_mixer[] = {
14162static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 14179static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14163 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14180 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14164 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14181 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14165 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14182 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14166 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 14183 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14167 { } /* end */ 14184 { } /* end */
14168}; 14185};
14169 14186
14170static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 14187static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14171 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14188 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14172 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14189 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14173 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14190 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14174 { } /* end */ 14191 { } /* end */
14175}; 14192};
14176 14193
14177static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 14194static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14178 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14195 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14179 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14196 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14180 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14197 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14181 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 14198 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14182 { } /* end */ 14199 { } /* end */
14183}; 14200};
14184 14201
14185static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 14202static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14186 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14203 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14187 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14204 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14188 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14205 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14189 { } /* end */ 14206 { } /* end */
14190}; 14207};
14191 14208
@@ -14804,12 +14821,23 @@ static int alc269_resume(struct hda_codec *codec)
14804} 14821}
14805#endif /* SND_HDA_NEEDS_RESUME */ 14822#endif /* SND_HDA_NEEDS_RESUME */
14806 14823
14824static void alc269_fixup_hweq(struct hda_codec *codec,
14825 const struct alc_fixup *fix, int pre_init)
14826{
14827 int coef;
14828
14829 coef = alc_read_coef_idx(codec, 0x1e);
14830 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14831}
14832
14807enum { 14833enum {
14808 ALC269_FIXUP_SONY_VAIO, 14834 ALC269_FIXUP_SONY_VAIO,
14809 ALC275_FIX_SONY_VAIO_GPIO2, 14835 ALC275_FIX_SONY_VAIO_GPIO2,
14810 ALC269_FIXUP_DELL_M101Z, 14836 ALC269_FIXUP_DELL_M101Z,
14811 ALC269_FIXUP_SKU_IGNORE, 14837 ALC269_FIXUP_SKU_IGNORE,
14812 ALC269_FIXUP_ASUS_G73JW, 14838 ALC269_FIXUP_ASUS_G73JW,
14839 ALC269_FIXUP_LENOVO_EAPD,
14840 ALC275_FIXUP_SONY_HWEQ,
14813}; 14841};
14814 14842
14815static const struct alc_fixup alc269_fixups[] = { 14843static const struct alc_fixup alc269_fixups[] = {
@@ -14824,6 +14852,7 @@ static const struct alc_fixup alc269_fixups[] = {
14824 {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, 14852 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14825 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, 14853 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14826 {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, 14854 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14855 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14827 { } 14856 { }
14828 } 14857 }
14829 }, 14858 },
@@ -14844,17 +14873,34 @@ static const struct alc_fixup alc269_fixups[] = {
14844 { } 14873 { }
14845 } 14874 }
14846 }, 14875 },
14876 [ALC269_FIXUP_LENOVO_EAPD] = {
14877 .verbs = (const struct hda_verb[]) {
14878 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14879 {}
14880 }
14881 },
14882 [ALC275_FIXUP_SONY_HWEQ] = {
14883 .func = alc269_fixup_hweq,
14884 .verbs = (const struct hda_verb[]) {
14885 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14886 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14887 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14888 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14889 { }
14890 }
14891 }
14847}; 14892};
14848 14893
14849static struct snd_pci_quirk alc269_fixup_tbl[] = { 14894static struct snd_pci_quirk alc269_fixup_tbl[] = {
14850 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), 14895 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2),
14851 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), 14896 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14852 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), 14897 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14853 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14898 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14854 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 14899 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14855 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 14900 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14856 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 14901 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14857 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 14902 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14903 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14858 {} 14904 {}
14859}; 14905};
14860 14906
@@ -15889,13 +15935,16 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15889 return 0; 15935 return 0;
15890} 15936}
15891 15937
15892static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 15938static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15893 hda_nid_t nid, unsigned int chs) 15939 hda_nid_t nid, int idx, unsigned int chs)
15894{ 15940{
15895 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, 15941 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
15896 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 15942 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15897} 15943}
15898 15944
15945#define alc861_create_out_sw(codec, pfx, nid, chs) \
15946 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
15947
15899/* add playback controls from the parsed DAC table */ 15948/* add playback controls from the parsed DAC table */
15900static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, 15949static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15901 const struct auto_pin_cfg *cfg) 15950 const struct auto_pin_cfg *cfg)
@@ -15904,26 +15953,15 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15904 static const char *chname[4] = { 15953 static const char *chname[4] = {
15905 "Front", "Surround", NULL /*CLFE*/, "Side" 15954 "Front", "Surround", NULL /*CLFE*/, "Side"
15906 }; 15955 };
15956 const char *pfx = alc_get_line_out_pfx(cfg, true);
15907 hda_nid_t nid; 15957 hda_nid_t nid;
15908 int i, err; 15958 int i, err;
15909 15959
15910 if (cfg->line_outs == 1) {
15911 const char *pfx = NULL;
15912 if (!cfg->hp_outs)
15913 pfx = "Master";
15914 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15915 pfx = "Speaker";
15916 if (pfx) {
15917 nid = spec->multiout.dac_nids[0];
15918 return alc861_create_out_sw(codec, pfx, nid, 3);
15919 }
15920 }
15921
15922 for (i = 0; i < cfg->line_outs; i++) { 15960 for (i = 0; i < cfg->line_outs; i++) {
15923 nid = spec->multiout.dac_nids[i]; 15961 nid = spec->multiout.dac_nids[i];
15924 if (!nid) 15962 if (!nid)
15925 continue; 15963 continue;
15926 if (i == 2) { 15964 if (!pfx && i == 2) {
15927 /* Center/LFE */ 15965 /* Center/LFE */
15928 err = alc861_create_out_sw(codec, "Center", nid, 1); 15966 err = alc861_create_out_sw(codec, "Center", nid, 1);
15929 if (err < 0) 15967 if (err < 0)
@@ -15932,7 +15970,10 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15932 if (err < 0) 15970 if (err < 0)
15933 return err; 15971 return err;
15934 } else { 15972 } else {
15935 err = alc861_create_out_sw(codec, chname[i], nid, 3); 15973 const char *name = pfx;
15974 if (!name)
15975 name = chname[i];
15976 err = __alc861_create_out_sw(codec, name, nid, i, 3);
15936 if (err < 0) 15977 if (err < 0)
15937 return err; 15978 return err;
15938 } 15979 }
@@ -16404,8 +16445,8 @@ static struct hda_input_mux alc861vd_capture_source = {
16404static struct hda_input_mux alc861vd_dallas_capture_source = { 16445static struct hda_input_mux alc861vd_dallas_capture_source = {
16405 .num_items = 2, 16446 .num_items = 2,
16406 .items = { 16447 .items = {
16407 { "Ext Mic", 0x0 }, 16448 { "Mic", 0x0 },
16408 { "Int Mic", 0x1 }, 16449 { "Internal Mic", 0x1 },
16409 }, 16450 },
16410}; 16451};
16411 16452
@@ -16484,11 +16525,11 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16484 16525
16485 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16526 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16486 16527
16487 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16528 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16488 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16529 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16489 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16530 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16490 16531
16491 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16532 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16492 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16533 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16493 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16534 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16494 16535
@@ -16507,11 +16548,11 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16507 16548
16508 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16549 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16509 16550
16510 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16551 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16511 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16552 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16512 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16553 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16513 16554
16514 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16555 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16515 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16556 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16516 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16557 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16517 16558
@@ -16531,11 +16572,11 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16531 16572
16532 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16573 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16533 16574
16534 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16575 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16535 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16576 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16536 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16577 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16537 16578
16538 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16579 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16539 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16580 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16540 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16581 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16541 16582
@@ -16546,19 +16587,19 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16546}; 16587};
16547 16588
16548/* Pin assignment: Speaker=0x14, HP = 0x15, 16589/* Pin assignment: Speaker=0x14, HP = 0x15,
16549 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16590 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16550 */ 16591 */
16551static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16592static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16552 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16593 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16553 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16594 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16554 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16595 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16555 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16596 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16556 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 16597 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16557 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16598 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16558 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16599 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16559 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 16600 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16560 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16601 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16561 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16602 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16562 { } /* end */ 16603 { } /* end */
16563}; 16604};
16564 16605
@@ -16723,18 +16764,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16723 {} 16764 {}
16724}; 16765};
16725 16766
16726static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16727{
16728 unsigned int present;
16729 unsigned char bits;
16730
16731 present = snd_hda_jack_detect(codec, 0x18);
16732 bits = present ? HDA_AMP_MUTE : 0;
16733
16734 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16735 HDA_AMP_MUTE, bits);
16736}
16737
16738static void alc861vd_lenovo_setup(struct hda_codec *codec) 16767static void alc861vd_lenovo_setup(struct hda_codec *codec)
16739{ 16768{
16740 struct alc_spec *spec = codec->spec; 16769 struct alc_spec *spec = codec->spec;
@@ -16745,7 +16774,7 @@ static void alc861vd_lenovo_setup(struct hda_codec *codec)
16745static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16774static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16746{ 16775{
16747 alc_automute_amp(codec); 16776 alc_automute_amp(codec);
16748 alc861vd_lenovo_mic_automute(codec); 16777 alc88x_simple_mic_automute(codec);
16749} 16778}
16750 16779
16751static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 16780static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
@@ -16753,7 +16782,7 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16753{ 16782{
16754 switch (res >> 26) { 16783 switch (res >> 26) {
16755 case ALC880_MIC_EVENT: 16784 case ALC880_MIC_EVENT:
16756 alc861vd_lenovo_mic_automute(codec); 16785 alc88x_simple_mic_automute(codec);
16757 break; 16786 break;
16758 default: 16787 default:
16759 alc_automute_amp_unsol_event(codec, res); 16788 alc_automute_amp_unsol_event(codec, res);
@@ -17043,12 +17072,13 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17043#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 17072#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17044 17073
17045/* add playback controls from the parsed DAC table */ 17074/* add playback controls from the parsed DAC table */
17046/* Based on ALC880 version. But ALC861VD has separate, 17075/* Based on ALC880 version. But ALC861VD and ALC887 have separate,
17047 * different NIDs for mute/unmute switch and volume control */ 17076 * different NIDs for mute/unmute switch and volume control */
17048static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 17077static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17049 const struct auto_pin_cfg *cfg) 17078 const struct auto_pin_cfg *cfg)
17050{ 17079{
17051 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 17080 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
17081 const char *pfx = alc_get_line_out_pfx(cfg, true);
17052 hda_nid_t nid_v, nid_s; 17082 hda_nid_t nid_v, nid_s;
17053 int i, err; 17083 int i, err;
17054 17084
@@ -17062,7 +17092,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17062 alc880_dac_to_idx( 17092 alc880_dac_to_idx(
17063 spec->multiout.dac_nids[i])); 17093 spec->multiout.dac_nids[i]));
17064 17094
17065 if (i == 2) { 17095 if (!pfx && i == 2) {
17066 /* Center/LFE */ 17096 /* Center/LFE */
17067 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17097 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17068 "Center", 17098 "Center",
@@ -17089,24 +17119,17 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17089 if (err < 0) 17119 if (err < 0)
17090 return err; 17120 return err;
17091 } else { 17121 } else {
17092 const char *pfx; 17122 const char *name = pfx;
17093 if (cfg->line_outs == 1 && 17123 if (!name)
17094 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 17124 name = chname[i];
17095 if (!cfg->hp_pins) 17125 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17096 pfx = "Speaker"; 17126 name, i,
17097 else
17098 pfx = "PCM";
17099 } else
17100 pfx = chname[i];
17101 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17102 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 17127 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17103 HDA_OUTPUT)); 17128 HDA_OUTPUT));
17104 if (err < 0) 17129 if (err < 0)
17105 return err; 17130 return err;
17106 if (cfg->line_outs == 1 && 17131 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17107 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 17132 name, i,
17108 pfx = "Speaker";
17109 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17110 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 17133 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17111 HDA_INPUT)); 17134 HDA_INPUT));
17112 if (err < 0) 17135 if (err < 0)
@@ -17570,13 +17593,13 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17570 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17593 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17571 ALC262_HIPPO_MASTER_SWITCH, 17594 ALC262_HIPPO_MASTER_SWITCH,
17572 17595
17573 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 17596 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17574 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17597 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17575 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17598 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17576 17599
17577 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 17600 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17578 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17601 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17579 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17602 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17580 { } /* end */ 17603 { } /* end */
17581}; 17604};
17582 17605
@@ -17720,8 +17743,8 @@ static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17720 17743
17721 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17744 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17722 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17745 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17723 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17746 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17724 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17747 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17725 { } /* end */ 17748 { } /* end */
17726}; 17749};
17727 17750
@@ -17732,8 +17755,8 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17732 17755
17733 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17756 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17734 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17757 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17735 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17758 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17736 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17759 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17737 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17760 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17738 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17761 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17739 { } /* end */ 17762 { } /* end */
@@ -18566,13 +18589,13 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18566 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18589 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18567 ALC262_HIPPO_MASTER_SWITCH, 18590 ALC262_HIPPO_MASTER_SWITCH,
18568 18591
18569 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 18592 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18570 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 18593 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18571 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 18594 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18572 18595
18573 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 18596 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18574 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18597 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18575 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18598 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18576 { } /* end */ 18599 { } /* end */
18577}; 18600};
18578 18601
@@ -18583,13 +18606,13 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18583 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 18606 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18584 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 18607 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18585 18608
18586 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 18609 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18587 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 18610 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18588 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 18611 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18589 18612
18590 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18613 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18591 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18614 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18592 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 18615 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18593 { } /* end */ 18616 { } /* end */
18594}; 18617};
18595 18618
@@ -19094,20 +19117,24 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19094 return 0; 19117 return 0;
19095} 19118}
19096 19119
19097static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 19120static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19098 hda_nid_t nid, unsigned int chs) 19121 hda_nid_t nid, int idx, unsigned int chs)
19099{ 19122{
19100 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 19123 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
19101 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 19124 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19102} 19125}
19103 19126
19104static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 19127static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19105 hda_nid_t nid, unsigned int chs) 19128 hda_nid_t nid, int idx, unsigned int chs)
19106{ 19129{
19107 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 19130 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19108 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 19131 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19109} 19132}
19110 19133
19134#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19135 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19136#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19137 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19111#define alc662_add_stereo_vol(spec, pfx, nid) \ 19138#define alc662_add_stereo_vol(spec, pfx, nid) \
19112 alc662_add_vol_ctl(spec, pfx, nid, 3) 19139 alc662_add_vol_ctl(spec, pfx, nid, 3)
19113#define alc662_add_stereo_sw(spec, pfx, nid) \ 19140#define alc662_add_stereo_sw(spec, pfx, nid) \
@@ -19121,6 +19148,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19121 static const char *chname[4] = { 19148 static const char *chname[4] = {
19122 "Front", "Surround", NULL /*CLFE*/, "Side" 19149 "Front", "Surround", NULL /*CLFE*/, "Side"
19123 }; 19150 };
19151 const char *pfx = alc_get_line_out_pfx(cfg, true);
19124 hda_nid_t nid, mix; 19152 hda_nid_t nid, mix;
19125 int i, err; 19153 int i, err;
19126 19154
@@ -19131,7 +19159,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19131 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); 19159 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19132 if (!mix) 19160 if (!mix)
19133 continue; 19161 continue;
19134 if (i == 2) { 19162 if (!pfx && i == 2) {
19135 /* Center/LFE */ 19163 /* Center/LFE */
19136 err = alc662_add_vol_ctl(spec, "Center", nid, 1); 19164 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19137 if (err < 0) 19165 if (err < 0)
@@ -19146,22 +19174,13 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19146 if (err < 0) 19174 if (err < 0)
19147 return err; 19175 return err;
19148 } else { 19176 } else {
19149 const char *pfx; 19177 const char *name = pfx;
19150 if (cfg->line_outs == 1 && 19178 if (!name)
19151 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 19179 name = chname[i];
19152 if (cfg->hp_outs) 19180 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
19153 pfx = "Speaker";
19154 else
19155 pfx = "PCM";
19156 } else
19157 pfx = chname[i];
19158 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19159 if (err < 0) 19181 if (err < 0)
19160 return err; 19182 return err;
19161 if (cfg->line_outs == 1 && 19183 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
19162 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19163 pfx = "Speaker";
19164 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19165 if (err < 0) 19184 if (err < 0)
19166 return err; 19185 return err;
19167 } 19186 }
@@ -19358,9 +19377,21 @@ static void alc662_auto_init(struct hda_codec *codec)
19358 alc_inithook(codec); 19377 alc_inithook(codec);
19359} 19378}
19360 19379
19380static void alc272_fixup_mario(struct hda_codec *codec,
19381 const struct alc_fixup *fix, int pre_init) {
19382 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19383 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19384 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19385 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19386 (0 << AC_AMPCAP_MUTE_SHIFT)))
19387 printk(KERN_WARNING
19388 "hda_codec: failed to override amp caps for NID 0x2\n");
19389}
19390
19361enum { 19391enum {
19362 ALC662_FIXUP_ASPIRE, 19392 ALC662_FIXUP_ASPIRE,
19363 ALC662_FIXUP_IDEAPAD, 19393 ALC662_FIXUP_IDEAPAD,
19394 ALC272_FIXUP_MARIO,
19364}; 19395};
19365 19396
19366static const struct alc_fixup alc662_fixups[] = { 19397static const struct alc_fixup alc662_fixups[] = {
@@ -19376,6 +19407,9 @@ static const struct alc_fixup alc662_fixups[] = {
19376 { } 19407 { }
19377 } 19408 }
19378 }, 19409 },
19410 [ALC272_FIXUP_MARIO] = {
19411 .func = alc272_fixup_mario,
19412 }
19379}; 19413};
19380 19414
19381static struct snd_pci_quirk alc662_fixup_tbl[] = { 19415static struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -19386,6 +19420,10 @@ static struct snd_pci_quirk alc662_fixup_tbl[] = {
19386 {} 19420 {}
19387}; 19421};
19388 19422
19423static const struct alc_model_fixup alc662_fixup_models[] = {
19424 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19425 {}
19426};
19389 19427
19390 19428
19391static int patch_alc662(struct hda_codec *codec) 19429static int patch_alc662(struct hda_codec *codec)
@@ -19485,7 +19523,8 @@ static int patch_alc662(struct hda_codec *codec)
19485 codec->patch_ops = alc_patch_ops; 19523 codec->patch_ops = alc_patch_ops;
19486 if (board_config == ALC662_AUTO) { 19524 if (board_config == ALC662_AUTO) {
19487 spec->init_hook = alc662_auto_init; 19525 spec->init_hook = alc662_auto_init;
19488 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0); 19526 alc_pick_fixup_model(codec, alc662_fixup_models,
19527 alc662_fixup_tbl, alc662_fixups, 0);
19489 } 19528 }
19490 19529
19491 alc_init_jacks(codec); 19530 alc_init_jacks(codec);
@@ -19612,9 +19651,9 @@ static struct snd_kcontrol_new alc680_base_mixer[] = {
19612 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 19651 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19613 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), 19652 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19614 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), 19653 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19615 HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT), 19654 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19616 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 19655 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19617 HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT), 19656 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19618 { } 19657 { }
19619}; 19658};
19620 19659
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index f03b2ff90496..4ab019d0924e 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -389,6 +389,9 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
389 0x11, 0x20, 0 389 0x11, 0x20, 0
390}; 390};
391 391
392#define STAC92HD88XXX_NUM_DMICS STAC92HD83XXX_NUM_DMICS
393#define stac92hd88xxx_dmic_nids stac92hd83xxx_dmic_nids
394
392#define STAC92HD87B_NUM_DMICS 1 395#define STAC92HD87B_NUM_DMICS 1
393static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = { 396static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = {
394 0x11, 0 397 0x11, 0
@@ -3591,7 +3594,7 @@ static int stac_check_auto_mic(struct hda_codec *codec)
3591 if (check_mic_pin(codec, spec->dmic_nids[i], 3594 if (check_mic_pin(codec, spec->dmic_nids[i],
3592 &fixed, &ext, &dock)) 3595 &fixed, &ext, &dock))
3593 return 0; 3596 return 0;
3594 if (!fixed && !ext && !dock) 3597 if (!fixed || (!ext && !dock))
3595 return 0; /* no input to switch */ 3598 return 0; /* no input to switch */
3596 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 3599 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
3597 return 0; /* no unsol support */ 3600 return 0; /* no unsol support */
@@ -5422,7 +5425,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5422 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); 5425 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
5423 codec->no_trigger_sense = 1; 5426 codec->no_trigger_sense = 1;
5424 codec->spec = spec; 5427 codec->spec = spec;
5425 spec->linear_tone_beep = 1; 5428 spec->linear_tone_beep = 0;
5426 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; 5429 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
5427 spec->digbeep_nid = 0x21; 5430 spec->digbeep_nid = 0x21;
5428 spec->dmic_nids = stac92hd83xxx_dmic_nids; 5431 spec->dmic_nids = stac92hd83xxx_dmic_nids;
@@ -5462,15 +5465,21 @@ again:
5462 spec->num_dmics = stac92xx_connected_ports(codec, 5465 spec->num_dmics = stac92xx_connected_ports(codec,
5463 stac92hd87b_dmic_nids, 5466 stac92hd87b_dmic_nids,
5464 STAC92HD87B_NUM_DMICS); 5467 STAC92HD87B_NUM_DMICS);
5465 /* Fall through */ 5468 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5469 spec->pin_nids = stac92hd88xxx_pin_nids;
5470 spec->mono_nid = 0;
5471 spec->num_pwrs = 0;
5472 break;
5466 case 0x111d7666: 5473 case 0x111d7666:
5467 case 0x111d7667: 5474 case 0x111d7667:
5468 case 0x111d7668: 5475 case 0x111d7668:
5469 case 0x111d7669: 5476 case 0x111d7669:
5477 spec->num_dmics = stac92xx_connected_ports(codec,
5478 stac92hd88xxx_dmic_nids,
5479 STAC92HD88XXX_NUM_DMICS);
5470 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); 5480 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5471 spec->pin_nids = stac92hd88xxx_pin_nids; 5481 spec->pin_nids = stac92hd88xxx_pin_nids;
5472 spec->mono_nid = 0; 5482 spec->mono_nid = 0;
5473 spec->digbeep_nid = 0;
5474 spec->num_pwrs = 0; 5483 spec->num_pwrs = 0;
5475 break; 5484 break;
5476 case 0x111d7604: 5485 case 0x111d7604:
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index d1c3f8defc48..7f4852a478a1 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -263,8 +263,7 @@ static void vt1708_stop_hp_work(struct via_spec *spec)
263 return; 263 return;
264 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 264 snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81,
265 !spec->vt1708_jack_detectect); 265 !spec->vt1708_jack_detectect);
266 cancel_delayed_work(&spec->vt1708_hp_work); 266 cancel_delayed_work_sync(&spec->vt1708_hp_work);
267 flush_scheduled_work();
268} 267}
269 268
270 269
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 712c1710f9a2..7b62de089fee 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -96,6 +96,11 @@ static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice)
96 tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC; 96 tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
97 tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL; 97 tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
98 break; 98 break;
99 case ICE1712_SUBDEVICE_DELTA66E:
100 tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A |
101 ICE1712_DELTA_66E_CS_CHIP_B;
102 tmp &= ~ICE1712_DELTA_66E_CS_CS8427;
103 break;
99 case ICE1712_SUBDEVICE_VX442: 104 case ICE1712_SUBDEVICE_VX442:
100 tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B; 105 tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
101 tmp &= ~ICE1712_VX442_CS_DIGITAL; 106 tmp &= ~ICE1712_VX442_CS_DIGITAL;
@@ -119,6 +124,9 @@ static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp)
119 case ICE1712_SUBDEVICE_DELTA410: 124 case ICE1712_SUBDEVICE_DELTA410:
120 tmp |= ICE1712_DELTA_AP_CS_DIGITAL; 125 tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
121 break; 126 break;
127 case ICE1712_SUBDEVICE_DELTA66E:
128 tmp |= ICE1712_DELTA_66E_CS_CS8427;
129 break;
122 case ICE1712_SUBDEVICE_VX442: 130 case ICE1712_SUBDEVICE_VX442:
123 tmp |= ICE1712_VX442_CS_DIGITAL; 131 tmp |= ICE1712_VX442_CS_DIGITAL;
124 break; 132 break;
@@ -276,6 +284,20 @@ static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
276} 284}
277 285
278/* 286/*
287 * AK4524 on Delta66 rev E to choose the chip address
288 */
289static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip)
290{
291 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
292 struct snd_ice1712 *ice = ak->private_data[0];
293
294 snd_ice1712_save_gpio_status(ice);
295 priv->cs_mask =
296 priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A :
297 ICE1712_DELTA_66E_CS_CHIP_B;
298}
299
300/*
279 * AK4528 on VX442 to choose the chip mask 301 * AK4528 on VX442 to choose the chip mask
280 */ 302 */
281static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip) 303static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip)
@@ -487,6 +509,29 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
487 .mask_flags = 0, 509 .mask_flags = 0,
488}; 510};
489 511
512static struct snd_akm4xxx akm_delta66e __devinitdata = {
513 .type = SND_AK4524,
514 .num_adcs = 4,
515 .num_dacs = 4,
516 .ops = {
517 .lock = delta66e_ak4524_lock,
518 .set_rate_val = delta_ak4524_set_rate_val
519 }
520};
521
522static struct snd_ak4xxx_private akm_delta66e_priv __devinitdata = {
523 .caddr = 2,
524 .cif = 0, /* the default level of the CIF pin from AK4524 */
525 .data_mask = ICE1712_DELTA_66E_DOUT,
526 .clk_mask = ICE1712_DELTA_66E_CCLK,
527 .cs_mask = 0,
528 .cs_addr = 0, /* set later */
529 .cs_none = 0,
530 .add_flags = 0,
531 .mask_flags = 0,
532};
533
534
490static struct snd_akm4xxx akm_delta44 __devinitdata = { 535static struct snd_akm4xxx akm_delta44 __devinitdata = {
491 .type = SND_AK4524, 536 .type = SND_AK4524,
492 .num_adcs = 4, 537 .num_adcs = 4,
@@ -644,9 +689,11 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
644 err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice); 689 err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
645 break; 690 break;
646 case ICE1712_SUBDEVICE_VX442: 691 case ICE1712_SUBDEVICE_VX442:
647 case ICE1712_SUBDEVICE_DELTA66E:
648 err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice); 692 err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
649 break; 693 break;
694 case ICE1712_SUBDEVICE_DELTA66E:
695 err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice);
696 break;
650 default: 697 default:
651 snd_BUG(); 698 snd_BUG();
652 return -EINVAL; 699 return -EINVAL;
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index 1a0ac6cd6501..11a9c3a76507 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -144,6 +144,17 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
144#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */ 144#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */
145#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */ 145#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */
146 146
147/* M-Audio Delta 66 rev. E definitions.
148 * Newer revisions of Delta 66 have CS8427 over SPI for
149 * S/PDIF transceiver instead of CS8404/CS8414. */
150/* 0x01 = DFS */
151#define ICE1712_DELTA_66E_CCLK 0x02 /* SPI clock */
152#define ICE1712_DELTA_66E_DIN 0x04 /* data input */
153#define ICE1712_DELTA_66E_DOUT 0x08 /* data output */
154#define ICE1712_DELTA_66E_CS_CS8427 0x10 /* chip select, low = CS8427 */
155#define ICE1712_DELTA_66E_CS_CHIP_A 0x20 /* AK4524 #0 */
156#define ICE1712_DELTA_66E_CS_CHIP_B 0x40 /* AK4524 #1 */
157
147/* Digigram VX442 definitions */ 158/* Digigram VX442 definitions */
148#define ICE1712_VX442_CCLK 0x02 /* SPI clock */ 159#define ICE1712_VX442_CCLK 0x02 /* SPI clock */
149#define ICE1712_VX442_DIN 0x04 /* data input */ 160#define ICE1712_VX442_DIN 0x04 /* data input */
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile
index acd8f15f7bff..0f8726551fde 100644
--- a/sound/pci/oxygen/Makefile
+++ b/sound/pci/oxygen/Makefile
@@ -1,10 +1,8 @@
1snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o 1snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
2snd-hifier-objs := hifier.o 2snd-oxygen-objs := oxygen.o xonar_dg.o
3snd-oxygen-objs := oxygen.o
4snd-virtuoso-objs := virtuoso.o xonar_lib.o \ 3snd-virtuoso-objs := virtuoso.o xonar_lib.o \
5 xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o 4 xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
6 5
7obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o 6obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
8obj-$(CONFIG_SND_HIFIER) += snd-hifier.o
9obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o 7obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o
10obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o 8obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o
diff --git a/sound/pci/oxygen/cs4245.h b/sound/pci/oxygen/cs4245.h
new file mode 100644
index 000000000000..5e0197e07dd1
--- /dev/null
+++ b/sound/pci/oxygen/cs4245.h
@@ -0,0 +1,107 @@
1#define CS4245_CHIP_ID 0x01
2#define CS4245_POWER_CTRL 0x02
3#define CS4245_DAC_CTRL_1 0x03
4#define CS4245_ADC_CTRL 0x04
5#define CS4245_MCLK_FREQ 0x05
6#define CS4245_SIGNAL_SEL 0x06
7#define CS4245_PGA_B_CTRL 0x07
8#define CS4245_PGA_A_CTRL 0x08
9#define CS4245_ANALOG_IN 0x09
10#define CS4245_DAC_A_CTRL 0x0a
11#define CS4245_DAC_B_CTRL 0x0b
12#define CS4245_DAC_CTRL_2 0x0c
13#define CS4245_INT_STATUS 0x0d
14#define CS4245_INT_MASK 0x0e
15#define CS4245_INT_MODE_MSB 0x0f
16#define CS4245_INT_MODE_LSB 0x10
17
18/* Chip ID */
19#define CS4245_CHIP_PART_MASK 0xf0
20#define CS4245_CHIP_REV_MASK 0x0f
21
22/* Power Control */
23#define CS4245_FREEZE 0x80
24#define CS4245_PDN_MIC 0x08
25#define CS4245_PDN_ADC 0x04
26#define CS4245_PDN_DAC 0x02
27#define CS4245_PDN 0x01
28
29/* DAC Control */
30#define CS4245_DAC_FM_MASK 0xc0
31#define CS4245_DAC_FM_SINGLE 0x00
32#define CS4245_DAC_FM_DOUBLE 0x40
33#define CS4245_DAC_FM_QUAD 0x80
34#define CS4245_DAC_DIF_MASK 0x30
35#define CS4245_DAC_DIF_LJUST 0x00
36#define CS4245_DAC_DIF_I2S 0x10
37#define CS4245_DAC_DIF_RJUST_16 0x20
38#define CS4245_DAC_DIF_RJUST_24 0x30
39#define CS4245_RESERVED_1 0x08
40#define CS4245_MUTE_DAC 0x04
41#define CS4245_DEEMPH 0x02
42#define CS4245_DAC_MASTER 0x01
43
44/* ADC Control */
45#define CS4245_ADC_FM_MASK 0xc0
46#define CS4245_ADC_FM_SINGLE 0x00
47#define CS4245_ADC_FM_DOUBLE 0x40
48#define CS4245_ADC_FM_QUAD 0x80
49#define CS4245_ADC_DIF_MASK 0x10
50#define CS4245_ADC_DIF_LJUST 0x00
51#define CS4245_ADC_DIF_I2S 0x10
52#define CS4245_MUTE_ADC 0x04
53#define CS4245_HPF_FREEZE 0x02
54#define CS4245_ADC_MASTER 0x01
55
56/* MCLK Frequency */
57#define CS4245_MCLK1_MASK 0x70
58#define CS4245_MCLK1_SHIFT 4
59#define CS4245_MCLK2_MASK 0x07
60#define CS4245_MCLK2_SHIFT 0
61#define CS4245_MCLK_1 0
62#define CS4245_MCLK_1_5 1
63#define CS4245_MCLK_2 2
64#define CS4245_MCLK_3 3
65#define CS4245_MCLK_4 4
66
67/* Signal Selection */
68#define CS4245_A_OUT_SEL_MASK 0x60
69#define CS4245_A_OUT_SEL_HIZ 0x00
70#define CS4245_A_OUT_SEL_DAC 0x20
71#define CS4245_A_OUT_SEL_PGA 0x40
72#define CS4245_LOOP 0x02
73#define CS4245_ASYNCH 0x01
74
75/* Channel B/A PGA Control */
76#define CS4245_PGA_GAIN_MASK 0x3f
77
78/* ADC Input Control */
79#define CS4245_PGA_SOFT 0x10
80#define CS4245_PGA_ZERO 0x08
81#define CS4245_SEL_MASK 0x07
82#define CS4245_SEL_MIC 0x00
83#define CS4245_SEL_INPUT_1 0x01
84#define CS4245_SEL_INPUT_2 0x02
85#define CS4245_SEL_INPUT_3 0x03
86#define CS4245_SEL_INPUT_4 0x04
87#define CS4245_SEL_INPUT_5 0x05
88#define CS4245_SEL_INPUT_6 0x06
89
90/* DAC Channel A/B Volume Control */
91#define CS4245_VOL_MASK 0xff
92
93/* DAC Control 2 */
94#define CS4245_DAC_SOFT 0x80
95#define CS4245_DAC_ZERO 0x40
96#define CS4245_INVERT_DAC 0x20
97#define CS4245_INT_ACTIVE_HIGH 0x01
98
99/* Interrupt Status/Mask/Mode */
100#define CS4245_ADC_CLK_ERR 0x08
101#define CS4245_DAC_CLK_ERR 0x04
102#define CS4245_ADC_OVFL 0x02
103#define CS4245_ADC_UNDRFL 0x01
104
105
106#define CS4245_SPI_ADDRESS (0x9e << 16)
107#define CS4245_SPI_WRITE (0 << 16)
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
deleted file mode 100644
index 5a87d683691f..000000000000
--- a/sound/pci/oxygen/hifier.c
+++ /dev/null
@@ -1,239 +0,0 @@
1/*
2 * C-Media CMI8788 driver for the MediaTek/TempoTec HiFier Fantasia
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver 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 driver; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * CMI8788:
22 *
23 * SPI 0 -> AK4396
24 */
25
26#include <linux/delay.h>
27#include <linux/pci.h>
28#include <sound/control.h>
29#include <sound/core.h>
30#include <sound/initval.h>
31#include <sound/pcm.h>
32#include <sound/tlv.h>
33#include "oxygen.h"
34#include "ak4396.h"
35
36MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
37MODULE_DESCRIPTION("TempoTec HiFier driver");
38MODULE_LICENSE("GPL v2");
39
40static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
41static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
42static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
43
44module_param_array(index, int, NULL, 0444);
45MODULE_PARM_DESC(index, "card index");
46module_param_array(id, charp, NULL, 0444);
47MODULE_PARM_DESC(id, "ID string");
48module_param_array(enable, bool, NULL, 0444);
49MODULE_PARM_DESC(enable, "enable card");
50
51static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = {
52 { OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
53 { OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
54 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
55 { }
56};
57MODULE_DEVICE_TABLE(pci, hifier_ids);
58
59struct hifier_data {
60 u8 ak4396_regs[5];
61};
62
63static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
64{
65 struct hifier_data *data = chip->model_data;
66
67 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
68 OXYGEN_SPI_DATA_LENGTH_2 |
69 OXYGEN_SPI_CLOCK_160 |
70 (0 << OXYGEN_SPI_CODEC_SHIFT) |
71 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
72 AK4396_WRITE | (reg << 8) | value);
73 data->ak4396_regs[reg] = value;
74}
75
76static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value)
77{
78 struct hifier_data *data = chip->model_data;
79
80 if (value != data->ak4396_regs[reg])
81 ak4396_write(chip, reg, value);
82}
83
84static void hifier_registers_init(struct oxygen *chip)
85{
86 struct hifier_data *data = chip->model_data;
87
88 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
89 ak4396_write(chip, AK4396_CONTROL_2,
90 data->ak4396_regs[AK4396_CONTROL_2]);
91 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
92 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
93 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
94}
95
96static void hifier_init(struct oxygen *chip)
97{
98 struct hifier_data *data = chip->model_data;
99
100 data->ak4396_regs[AK4396_CONTROL_2] =
101 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
102 hifier_registers_init(chip);
103
104 snd_component_add(chip->card, "AK4396");
105 snd_component_add(chip->card, "CS5340");
106}
107
108static void hifier_cleanup(struct oxygen *chip)
109{
110}
111
112static void hifier_resume(struct oxygen *chip)
113{
114 hifier_registers_init(chip);
115}
116
117static void set_ak4396_params(struct oxygen *chip,
118 struct snd_pcm_hw_params *params)
119{
120 struct hifier_data *data = chip->model_data;
121 u8 value;
122
123 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
124 if (params_rate(params) <= 54000)
125 value |= AK4396_DFS_NORMAL;
126 else if (params_rate(params) <= 108000)
127 value |= AK4396_DFS_DOUBLE;
128 else
129 value |= AK4396_DFS_QUAD;
130
131 msleep(1); /* wait for the new MCLK to become stable */
132
133 if (value != data->ak4396_regs[AK4396_CONTROL_2]) {
134 ak4396_write(chip, AK4396_CONTROL_1,
135 AK4396_DIF_24_MSB);
136 ak4396_write(chip, AK4396_CONTROL_2, value);
137 ak4396_write(chip, AK4396_CONTROL_1,
138 AK4396_DIF_24_MSB | AK4396_RSTN);
139 }
140}
141
142static void update_ak4396_volume(struct oxygen *chip)
143{
144 ak4396_write_cached(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
145 ak4396_write_cached(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
146}
147
148static void update_ak4396_mute(struct oxygen *chip)
149{
150 struct hifier_data *data = chip->model_data;
151 u8 value;
152
153 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE;
154 if (chip->dac_mute)
155 value |= AK4396_SMUTE;
156 ak4396_write_cached(chip, AK4396_CONTROL_2, value);
157}
158
159static void set_cs5340_params(struct oxygen *chip,
160 struct snd_pcm_hw_params *params)
161{
162}
163
164static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
165
166static const struct oxygen_model model_hifier = {
167 .shortname = "C-Media CMI8787",
168 .longname = "C-Media Oxygen HD Audio",
169 .chip = "CMI8788",
170 .init = hifier_init,
171 .cleanup = hifier_cleanup,
172 .resume = hifier_resume,
173 .get_i2s_mclk = oxygen_default_i2s_mclk,
174 .set_dac_params = set_ak4396_params,
175 .set_adc_params = set_cs5340_params,
176 .update_dac_volume = update_ak4396_volume,
177 .update_dac_mute = update_ak4396_mute,
178 .dac_tlv = ak4396_db_scale,
179 .model_data_size = sizeof(struct hifier_data),
180 .device_config = PLAYBACK_0_TO_I2S |
181 PLAYBACK_1_TO_SPDIF |
182 CAPTURE_0_FROM_I2S_1,
183 .dac_channels = 2,
184 .dac_volume_min = 0,
185 .dac_volume_max = 255,
186 .function_flags = OXYGEN_FUNCTION_SPI,
187 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
188 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
189};
190
191static int __devinit get_hifier_model(struct oxygen *chip,
192 const struct pci_device_id *id)
193{
194 chip->model = model_hifier;
195 return 0;
196}
197
198static int __devinit hifier_probe(struct pci_dev *pci,
199 const struct pci_device_id *pci_id)
200{
201 static int dev;
202 int err;
203
204 if (dev >= SNDRV_CARDS)
205 return -ENODEV;
206 if (!enable[dev]) {
207 ++dev;
208 return -ENOENT;
209 }
210 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
211 hifier_ids, get_hifier_model);
212 if (err >= 0)
213 ++dev;
214 return err;
215}
216
217static struct pci_driver hifier_driver = {
218 .name = "CMI8787HiFier",
219 .id_table = hifier_ids,
220 .probe = hifier_probe,
221 .remove = __devexit_p(oxygen_pci_remove),
222#ifdef CONFIG_PM
223 .suspend = oxygen_pci_suspend,
224 .resume = oxygen_pci_resume,
225#endif
226};
227
228static int __init alsa_card_hifier_init(void)
229{
230 return pci_register_driver(&hifier_driver);
231}
232
233static void __exit alsa_card_hifier_exit(void)
234{
235 pci_unregister_driver(&hifier_driver);
236}
237
238module_init(alsa_card_hifier_init)
239module_exit(alsa_card_hifier_exit)
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 98a8eb3c92f7..d7e8ddd9a67b 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -20,19 +20,32 @@
20/* 20/*
21 * CMI8788: 21 * CMI8788:
22 * 22 *
23 * SPI 0 -> 1st AK4396 (front) 23 * SPI 0 -> 1st AK4396 (front)
24 * SPI 1 -> 2nd AK4396 (surround) 24 * SPI 1 -> 2nd AK4396 (surround)
25 * SPI 2 -> 3rd AK4396 (center/LFE) 25 * SPI 2 -> 3rd AK4396 (center/LFE)
26 * SPI 3 -> WM8785 26 * SPI 3 -> WM8785
27 * SPI 4 -> 4th AK4396 (back) 27 * SPI 4 -> 4th AK4396 (back)
28 * 28 *
29 * GPIO 0 -> DFS0 of AK5385 29 * GPIO 0 -> DFS0 of AK5385
30 * GPIO 1 -> DFS1 of AK5385 30 * GPIO 1 -> DFS1 of AK5385
31 * GPIO 8 -> enable headphone amplifier on HT-Omega models 31 *
32 * X-Meridian models:
33 * GPIO 4 -> enable extension S/PDIF input
34 * GPIO 6 -> enable on-board S/PDIF input
35 *
36 * Claro models:
37 * GPIO 6 -> S/PDIF from optical (0) or coaxial (1) input
38 * GPIO 8 -> enable headphone amplifier
32 * 39 *
33 * CM9780: 40 * CM9780:
34 * 41 *
35 * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input 42 * LINE_OUT -> input of ADC
43 *
44 * AUX_IN <- aux
45 * CD_IN <- CD
46 * MIC_IN <- mic
47 *
48 * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input
36 */ 49 */
37 50
38#include <linux/delay.h> 51#include <linux/delay.h>
@@ -41,18 +54,22 @@
41#include <sound/ac97_codec.h> 54#include <sound/ac97_codec.h>
42#include <sound/control.h> 55#include <sound/control.h>
43#include <sound/core.h> 56#include <sound/core.h>
57#include <sound/info.h>
44#include <sound/initval.h> 58#include <sound/initval.h>
45#include <sound/pcm.h> 59#include <sound/pcm.h>
46#include <sound/pcm_params.h> 60#include <sound/pcm_params.h>
47#include <sound/tlv.h> 61#include <sound/tlv.h>
48#include "oxygen.h" 62#include "oxygen.h"
63#include "xonar_dg.h"
49#include "ak4396.h" 64#include "ak4396.h"
50#include "wm8785.h" 65#include "wm8785.h"
51 66
52MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 67MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
53MODULE_DESCRIPTION("C-Media CMI8788 driver"); 68MODULE_DESCRIPTION("C-Media CMI8788 driver");
54MODULE_LICENSE("GPL v2"); 69MODULE_LICENSE("GPL v2");
55MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}"); 70MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8786}"
71 ",{C-Media,CMI8787}"
72 ",{C-Media,CMI8788}}");
56 73
57static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 74static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
58static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 75static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -66,24 +83,46 @@ module_param_array(enable, bool, NULL, 0444);
66MODULE_PARM_DESC(enable, "enable card"); 83MODULE_PARM_DESC(enable, "enable card");
67 84
68enum { 85enum {
69 MODEL_CMEDIA_REF, /* C-Media's reference design */ 86 MODEL_CMEDIA_REF,
70 MODEL_MERIDIAN, /* AuzenTech X-Meridian */ 87 MODEL_MERIDIAN,
71 MODEL_CLARO, /* HT-Omega Claro */ 88 MODEL_MERIDIAN_2G,
72 MODEL_CLARO_HALO, /* HT-Omega Claro halo */ 89 MODEL_CLARO,
90 MODEL_CLARO_HALO,
91 MODEL_FANTASIA,
92 MODEL_SERENADE,
93 MODEL_2CH_OUTPUT,
94 MODEL_HG2PCI,
95 MODEL_XONAR_DG,
73}; 96};
74 97
75static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { 98static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
99 /* C-Media's reference design */
76 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, 100 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF },
101 { OXYGEN_PCI_SUBID(0x10b0, 0x0217), .driver_data = MODEL_CMEDIA_REF },
77 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, 102 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF },
78 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, 103 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF },
79 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, 104 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF },
80 { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, 105 { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF },
81 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, 106 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
82 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF },
83 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, 107 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
84 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 108 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
109 /* Asus Xonar DG */
110 { OXYGEN_PCI_SUBID(0x1043, 0x8467), .driver_data = MODEL_XONAR_DG },
111 /* PCI 2.0 HD Audio */
112 { OXYGEN_PCI_SUBID(0x13f6, 0x8782), .driver_data = MODEL_2CH_OUTPUT },
113 /* Kuroutoshikou CMI8787-HG2PCI */
114 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI },
115 /* TempoTec HiFier Fantasia */
116 { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_FANTASIA },
117 /* TempoTec HiFier Serenade */
118 { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_SERENADE },
119 /* AuzenTech X-Meridian */
85 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 120 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
121 /* AuzenTech X-Meridian 2G */
122 { OXYGEN_PCI_SUBID(0x5431, 0x017a), .driver_data = MODEL_MERIDIAN_2G },
123 /* HT-Omega Claro */
86 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, 124 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO },
125 /* HT-Omega Claro halo */
87 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO }, 126 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO },
88 { } 127 { }
89}; 128};
@@ -95,9 +134,15 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
95#define GPIO_AK5385_DFS_DOUBLE 0x0001 134#define GPIO_AK5385_DFS_DOUBLE 0x0001
96#define GPIO_AK5385_DFS_QUAD 0x0002 135#define GPIO_AK5385_DFS_QUAD 0x0002
97 136
137#define GPIO_MERIDIAN_DIG_MASK 0x0050
138#define GPIO_MERIDIAN_DIG_EXT 0x0010
139#define GPIO_MERIDIAN_DIG_BOARD 0x0040
140
141#define GPIO_CLARO_DIG_COAX 0x0040
98#define GPIO_CLARO_HP 0x0100 142#define GPIO_CLARO_HP 0x0100
99 143
100struct generic_data { 144struct generic_data {
145 unsigned int dacs;
101 u8 ak4396_regs[4][5]; 146 u8 ak4396_regs[4][5];
102 u16 wm8785_regs[3]; 147 u16 wm8785_regs[3];
103}; 148};
@@ -148,7 +193,7 @@ static void ak4396_registers_init(struct oxygen *chip)
148 struct generic_data *data = chip->model_data; 193 struct generic_data *data = chip->model_data;
149 unsigned int i; 194 unsigned int i;
150 195
151 for (i = 0; i < 4; ++i) { 196 for (i = 0; i < data->dacs; ++i) {
152 ak4396_write(chip, i, AK4396_CONTROL_1, 197 ak4396_write(chip, i, AK4396_CONTROL_1,
153 AK4396_DIF_24_MSB | AK4396_RSTN); 198 AK4396_DIF_24_MSB | AK4396_RSTN);
154 ak4396_write(chip, i, AK4396_CONTROL_2, 199 ak4396_write(chip, i, AK4396_CONTROL_2,
@@ -166,6 +211,7 @@ static void ak4396_init(struct oxygen *chip)
166{ 211{
167 struct generic_data *data = chip->model_data; 212 struct generic_data *data = chip->model_data;
168 213
214 data->dacs = chip->model.dac_channels_pcm / 2;
169 data->ak4396_regs[0][AK4396_CONTROL_2] = 215 data->ak4396_regs[0][AK4396_CONTROL_2] =
170 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; 216 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
171 ak4396_registers_init(chip); 217 ak4396_registers_init(chip);
@@ -207,6 +253,10 @@ static void generic_init(struct oxygen *chip)
207 253
208static void meridian_init(struct oxygen *chip) 254static void meridian_init(struct oxygen *chip)
209{ 255{
256 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
257 GPIO_MERIDIAN_DIG_MASK);
258 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
259 GPIO_MERIDIAN_DIG_BOARD, GPIO_MERIDIAN_DIG_MASK);
210 ak4396_init(chip); 260 ak4396_init(chip);
211 ak5385_init(chip); 261 ak5385_init(chip);
212} 262}
@@ -220,6 +270,8 @@ static void claro_enable_hp(struct oxygen *chip)
220 270
221static void claro_init(struct oxygen *chip) 271static void claro_init(struct oxygen *chip)
222{ 272{
273 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX);
274 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX);
223 ak4396_init(chip); 275 ak4396_init(chip);
224 wm8785_init(chip); 276 wm8785_init(chip);
225 claro_enable_hp(chip); 277 claro_enable_hp(chip);
@@ -227,11 +279,24 @@ static void claro_init(struct oxygen *chip)
227 279
228static void claro_halo_init(struct oxygen *chip) 280static void claro_halo_init(struct oxygen *chip)
229{ 281{
282 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX);
283 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX);
230 ak4396_init(chip); 284 ak4396_init(chip);
231 ak5385_init(chip); 285 ak5385_init(chip);
232 claro_enable_hp(chip); 286 claro_enable_hp(chip);
233} 287}
234 288
289static void fantasia_init(struct oxygen *chip)
290{
291 ak4396_init(chip);
292 snd_component_add(chip->card, "CS5340");
293}
294
295static void stereo_output_init(struct oxygen *chip)
296{
297 ak4396_init(chip);
298}
299
235static void generic_cleanup(struct oxygen *chip) 300static void generic_cleanup(struct oxygen *chip)
236{ 301{
237} 302}
@@ -268,6 +333,11 @@ static void claro_resume(struct oxygen *chip)
268 claro_enable_hp(chip); 333 claro_enable_hp(chip);
269} 334}
270 335
336static void stereo_resume(struct oxygen *chip)
337{
338 ak4396_registers_init(chip);
339}
340
271static void set_ak4396_params(struct oxygen *chip, 341static void set_ak4396_params(struct oxygen *chip,
272 struct snd_pcm_hw_params *params) 342 struct snd_pcm_hw_params *params)
273{ 343{
@@ -286,7 +356,7 @@ static void set_ak4396_params(struct oxygen *chip,
286 msleep(1); /* wait for the new MCLK to become stable */ 356 msleep(1); /* wait for the new MCLK to become stable */
287 357
288 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) { 358 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) {
289 for (i = 0; i < 4; ++i) { 359 for (i = 0; i < data->dacs; ++i) {
290 ak4396_write(chip, i, AK4396_CONTROL_1, 360 ak4396_write(chip, i, AK4396_CONTROL_1,
291 AK4396_DIF_24_MSB); 361 AK4396_DIF_24_MSB);
292 ak4396_write(chip, i, AK4396_CONTROL_2, value); 362 ak4396_write(chip, i, AK4396_CONTROL_2, value);
@@ -298,9 +368,10 @@ static void set_ak4396_params(struct oxygen *chip,
298 368
299static void update_ak4396_volume(struct oxygen *chip) 369static void update_ak4396_volume(struct oxygen *chip)
300{ 370{
371 struct generic_data *data = chip->model_data;
301 unsigned int i; 372 unsigned int i;
302 373
303 for (i = 0; i < 4; ++i) { 374 for (i = 0; i < data->dacs; ++i) {
304 ak4396_write_cached(chip, i, AK4396_LCH_ATT, 375 ak4396_write_cached(chip, i, AK4396_LCH_ATT,
305 chip->dac_volume[i * 2]); 376 chip->dac_volume[i * 2]);
306 ak4396_write_cached(chip, i, AK4396_RCH_ATT, 377 ak4396_write_cached(chip, i, AK4396_RCH_ATT,
@@ -317,7 +388,7 @@ static void update_ak4396_mute(struct oxygen *chip)
317 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE; 388 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE;
318 if (chip->dac_mute) 389 if (chip->dac_mute)
319 value |= AK4396_SMUTE; 390 value |= AK4396_SMUTE;
320 for (i = 0; i < 4; ++i) 391 for (i = 0; i < data->dacs; ++i)
321 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value); 392 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value);
322} 393}
323 394
@@ -356,6 +427,10 @@ static void set_ak5385_params(struct oxygen *chip,
356 value, GPIO_AK5385_DFS_MASK); 427 value, GPIO_AK5385_DFS_MASK);
357} 428}
358 429
430static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params)
431{
432}
433
359static int rolloff_info(struct snd_kcontrol *ctl, 434static int rolloff_info(struct snd_kcontrol *ctl,
360 struct snd_ctl_elem_info *info) 435 struct snd_ctl_elem_info *info)
361{ 436{
@@ -363,13 +438,7 @@ static int rolloff_info(struct snd_kcontrol *ctl,
363 "Sharp Roll-off", "Slow Roll-off" 438 "Sharp Roll-off", "Slow Roll-off"
364 }; 439 };
365 440
366 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 441 return snd_ctl_enum_info(info, 1, 2, names);
367 info->count = 1;
368 info->value.enumerated.items = 2;
369 if (info->value.enumerated.item >= 2)
370 info->value.enumerated.item = 1;
371 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
372 return 0;
373} 442}
374 443
375static int rolloff_get(struct snd_kcontrol *ctl, 444static int rolloff_get(struct snd_kcontrol *ctl,
@@ -400,7 +469,7 @@ static int rolloff_put(struct snd_kcontrol *ctl,
400 reg &= ~AK4396_SLOW; 469 reg &= ~AK4396_SLOW;
401 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2]; 470 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2];
402 if (changed) { 471 if (changed) {
403 for (i = 0; i < 4; ++i) 472 for (i = 0; i < data->dacs; ++i)
404 ak4396_write(chip, i, AK4396_CONTROL_2, reg); 473 ak4396_write(chip, i, AK4396_CONTROL_2, reg);
405 } 474 }
406 mutex_unlock(&chip->mutex); 475 mutex_unlock(&chip->mutex);
@@ -421,13 +490,7 @@ static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
421 "None", "High-pass Filter" 490 "None", "High-pass Filter"
422 }; 491 };
423 492
424 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 493 return snd_ctl_enum_info(info, 1, 2, names);
425 info->count = 1;
426 info->value.enumerated.items = 2;
427 if (info->value.enumerated.item >= 2)
428 info->value.enumerated.item = 1;
429 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
430 return 0;
431} 494}
432 495
433static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 496static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
@@ -466,6 +529,100 @@ static const struct snd_kcontrol_new hpf_control = {
466 .put = hpf_put, 529 .put = hpf_put,
467}; 530};
468 531
532static int meridian_dig_source_info(struct snd_kcontrol *ctl,
533 struct snd_ctl_elem_info *info)
534{
535 static const char *const names[2] = { "On-board", "Extension" };
536
537 return snd_ctl_enum_info(info, 1, 2, names);
538}
539
540static int claro_dig_source_info(struct snd_kcontrol *ctl,
541 struct snd_ctl_elem_info *info)
542{
543 static const char *const names[2] = { "Optical", "Coaxial" };
544
545 return snd_ctl_enum_info(info, 1, 2, names);
546}
547
548static int meridian_dig_source_get(struct snd_kcontrol *ctl,
549 struct snd_ctl_elem_value *value)
550{
551 struct oxygen *chip = ctl->private_data;
552
553 value->value.enumerated.item[0] =
554 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
555 GPIO_MERIDIAN_DIG_EXT);
556 return 0;
557}
558
559static int claro_dig_source_get(struct snd_kcontrol *ctl,
560 struct snd_ctl_elem_value *value)
561{
562 struct oxygen *chip = ctl->private_data;
563
564 value->value.enumerated.item[0] =
565 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
566 GPIO_CLARO_DIG_COAX);
567 return 0;
568}
569
570static int meridian_dig_source_put(struct snd_kcontrol *ctl,
571 struct snd_ctl_elem_value *value)
572{
573 struct oxygen *chip = ctl->private_data;
574 u16 old_reg, new_reg;
575 int changed;
576
577 mutex_lock(&chip->mutex);
578 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
579 new_reg = old_reg & ~GPIO_MERIDIAN_DIG_MASK;
580 if (value->value.enumerated.item[0] == 0)
581 new_reg |= GPIO_MERIDIAN_DIG_BOARD;
582 else
583 new_reg |= GPIO_MERIDIAN_DIG_EXT;
584 changed = new_reg != old_reg;
585 if (changed)
586 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
587 mutex_unlock(&chip->mutex);
588 return changed;
589}
590
591static int claro_dig_source_put(struct snd_kcontrol *ctl,
592 struct snd_ctl_elem_value *value)
593{
594 struct oxygen *chip = ctl->private_data;
595 u16 old_reg, new_reg;
596 int changed;
597
598 mutex_lock(&chip->mutex);
599 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
600 new_reg = old_reg & ~GPIO_CLARO_DIG_COAX;
601 if (value->value.enumerated.item[0])
602 new_reg |= GPIO_CLARO_DIG_COAX;
603 changed = new_reg != old_reg;
604 if (changed)
605 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
606 mutex_unlock(&chip->mutex);
607 return changed;
608}
609
610static const struct snd_kcontrol_new meridian_dig_source_control = {
611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
612 .name = "IEC958 Source Capture Enum",
613 .info = meridian_dig_source_info,
614 .get = meridian_dig_source_get,
615 .put = meridian_dig_source_put,
616};
617
618static const struct snd_kcontrol_new claro_dig_source_control = {
619 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
620 .name = "IEC958 Source Capture Enum",
621 .info = claro_dig_source_info,
622 .get = claro_dig_source_get,
623 .put = claro_dig_source_put,
624};
625
469static int generic_mixer_init(struct oxygen *chip) 626static int generic_mixer_init(struct oxygen *chip)
470{ 627{
471 return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); 628 return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
@@ -484,6 +641,81 @@ static int generic_wm8785_mixer_init(struct oxygen *chip)
484 return 0; 641 return 0;
485} 642}
486 643
644static int meridian_mixer_init(struct oxygen *chip)
645{
646 int err;
647
648 err = generic_mixer_init(chip);
649 if (err < 0)
650 return err;
651 err = snd_ctl_add(chip->card,
652 snd_ctl_new1(&meridian_dig_source_control, chip));
653 if (err < 0)
654 return err;
655 return 0;
656}
657
658static int claro_mixer_init(struct oxygen *chip)
659{
660 int err;
661
662 err = generic_wm8785_mixer_init(chip);
663 if (err < 0)
664 return err;
665 err = snd_ctl_add(chip->card,
666 snd_ctl_new1(&claro_dig_source_control, chip));
667 if (err < 0)
668 return err;
669 return 0;
670}
671
672static int claro_halo_mixer_init(struct oxygen *chip)
673{
674 int err;
675
676 err = generic_mixer_init(chip);
677 if (err < 0)
678 return err;
679 err = snd_ctl_add(chip->card,
680 snd_ctl_new1(&claro_dig_source_control, chip));
681 if (err < 0)
682 return err;
683 return 0;
684}
685
686static void dump_ak4396_registers(struct oxygen *chip,
687 struct snd_info_buffer *buffer)
688{
689 struct generic_data *data = chip->model_data;
690 unsigned int dac, i;
691
692 for (dac = 0; dac < data->dacs; ++dac) {
693 snd_iprintf(buffer, "\nAK4396 %u:", dac + 1);
694 for (i = 0; i < 5; ++i)
695 snd_iprintf(buffer, " %02x", data->ak4396_regs[dac][i]);
696 }
697 snd_iprintf(buffer, "\n");
698}
699
700static void dump_wm8785_registers(struct oxygen *chip,
701 struct snd_info_buffer *buffer)
702{
703 struct generic_data *data = chip->model_data;
704 unsigned int i;
705
706 snd_iprintf(buffer, "\nWM8785:");
707 for (i = 0; i < 3; ++i)
708 snd_iprintf(buffer, " %03x", data->wm8785_regs[i]);
709 snd_iprintf(buffer, "\n");
710}
711
712static void dump_oxygen_registers(struct oxygen *chip,
713 struct snd_info_buffer *buffer)
714{
715 dump_ak4396_registers(chip, buffer);
716 dump_wm8785_registers(chip, buffer);
717}
718
487static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); 719static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
488 720
489static const struct oxygen_model model_generic = { 721static const struct oxygen_model model_generic = {
@@ -494,11 +726,11 @@ static const struct oxygen_model model_generic = {
494 .mixer_init = generic_wm8785_mixer_init, 726 .mixer_init = generic_wm8785_mixer_init,
495 .cleanup = generic_cleanup, 727 .cleanup = generic_cleanup,
496 .resume = generic_resume, 728 .resume = generic_resume,
497 .get_i2s_mclk = oxygen_default_i2s_mclk,
498 .set_dac_params = set_ak4396_params, 729 .set_dac_params = set_ak4396_params,
499 .set_adc_params = set_wm8785_params, 730 .set_adc_params = set_wm8785_params,
500 .update_dac_volume = update_ak4396_volume, 731 .update_dac_volume = update_ak4396_volume,
501 .update_dac_mute = update_ak4396_mute, 732 .update_dac_mute = update_ak4396_mute,
733 .dump_registers = dump_oxygen_registers,
502 .dac_tlv = ak4396_db_scale, 734 .dac_tlv = ak4396_db_scale,
503 .model_data_size = sizeof(struct generic_data), 735 .model_data_size = sizeof(struct generic_data),
504 .device_config = PLAYBACK_0_TO_I2S | 736 .device_config = PLAYBACK_0_TO_I2S |
@@ -508,11 +740,14 @@ static const struct oxygen_model model_generic = {
508 CAPTURE_1_FROM_SPDIF | 740 CAPTURE_1_FROM_SPDIF |
509 CAPTURE_2_FROM_AC97_1 | 741 CAPTURE_2_FROM_AC97_1 |
510 AC97_CD_INPUT, 742 AC97_CD_INPUT,
511 .dac_channels = 8, 743 .dac_channels_pcm = 8,
744 .dac_channels_mixer = 8,
512 .dac_volume_min = 0, 745 .dac_volume_min = 0,
513 .dac_volume_max = 255, 746 .dac_volume_max = 255,
514 .function_flags = OXYGEN_FUNCTION_SPI | 747 .function_flags = OXYGEN_FUNCTION_SPI |
515 OXYGEN_FUNCTION_ENABLE_SPI_4_5, 748 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
749 .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
750 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
516 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 751 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
517 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 752 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
518}; 753};
@@ -520,42 +755,87 @@ static const struct oxygen_model model_generic = {
520static int __devinit get_oxygen_model(struct oxygen *chip, 755static int __devinit get_oxygen_model(struct oxygen *chip,
521 const struct pci_device_id *id) 756 const struct pci_device_id *id)
522{ 757{
758 static const char *const names[] = {
759 [MODEL_MERIDIAN] = "AuzenTech X-Meridian",
760 [MODEL_MERIDIAN_2G] = "AuzenTech X-Meridian 2G",
761 [MODEL_CLARO] = "HT-Omega Claro",
762 [MODEL_CLARO_HALO] = "HT-Omega Claro halo",
763 [MODEL_FANTASIA] = "TempoTec HiFier Fantasia",
764 [MODEL_SERENADE] = "TempoTec HiFier Serenade",
765 [MODEL_HG2PCI] = "CMI8787-HG2PCI",
766 };
767
523 chip->model = model_generic; 768 chip->model = model_generic;
524 switch (id->driver_data) { 769 switch (id->driver_data) {
525 case MODEL_MERIDIAN: 770 case MODEL_MERIDIAN:
771 case MODEL_MERIDIAN_2G:
526 chip->model.init = meridian_init; 772 chip->model.init = meridian_init;
527 chip->model.mixer_init = generic_mixer_init; 773 chip->model.mixer_init = meridian_mixer_init;
528 chip->model.resume = meridian_resume; 774 chip->model.resume = meridian_resume;
529 chip->model.set_adc_params = set_ak5385_params; 775 chip->model.set_adc_params = set_ak5385_params;
776 chip->model.dump_registers = dump_ak4396_registers;
530 chip->model.device_config = PLAYBACK_0_TO_I2S | 777 chip->model.device_config = PLAYBACK_0_TO_I2S |
531 PLAYBACK_1_TO_SPDIF | 778 PLAYBACK_1_TO_SPDIF |
532 CAPTURE_0_FROM_I2S_2 | 779 CAPTURE_0_FROM_I2S_2 |
533 CAPTURE_1_FROM_SPDIF; 780 CAPTURE_1_FROM_SPDIF;
781 if (id->driver_data == MODEL_MERIDIAN)
782 chip->model.device_config |= AC97_CD_INPUT;
534 break; 783 break;
535 case MODEL_CLARO: 784 case MODEL_CLARO:
536 chip->model.init = claro_init; 785 chip->model.init = claro_init;
786 chip->model.mixer_init = claro_mixer_init;
537 chip->model.cleanup = claro_cleanup; 787 chip->model.cleanup = claro_cleanup;
538 chip->model.suspend = claro_suspend; 788 chip->model.suspend = claro_suspend;
539 chip->model.resume = claro_resume; 789 chip->model.resume = claro_resume;
540 break; 790 break;
541 case MODEL_CLARO_HALO: 791 case MODEL_CLARO_HALO:
542 chip->model.init = claro_halo_init; 792 chip->model.init = claro_halo_init;
543 chip->model.mixer_init = generic_mixer_init; 793 chip->model.mixer_init = claro_halo_mixer_init;
544 chip->model.cleanup = claro_cleanup; 794 chip->model.cleanup = claro_cleanup;
545 chip->model.suspend = claro_suspend; 795 chip->model.suspend = claro_suspend;
546 chip->model.resume = claro_resume; 796 chip->model.resume = claro_resume;
547 chip->model.set_adc_params = set_ak5385_params; 797 chip->model.set_adc_params = set_ak5385_params;
798 chip->model.dump_registers = dump_ak4396_registers;
548 chip->model.device_config = PLAYBACK_0_TO_I2S | 799 chip->model.device_config = PLAYBACK_0_TO_I2S |
549 PLAYBACK_1_TO_SPDIF | 800 PLAYBACK_1_TO_SPDIF |
550 CAPTURE_0_FROM_I2S_2 | 801 CAPTURE_0_FROM_I2S_2 |
551 CAPTURE_1_FROM_SPDIF; 802 CAPTURE_1_FROM_SPDIF;
552 break; 803 break;
804 case MODEL_FANTASIA:
805 case MODEL_SERENADE:
806 case MODEL_2CH_OUTPUT:
807 case MODEL_HG2PCI:
808 chip->model.shortname = "C-Media CMI8787";
809 chip->model.chip = "CMI8787";
810 if (id->driver_data == MODEL_FANTASIA)
811 chip->model.init = fantasia_init;
812 else
813 chip->model.init = stereo_output_init;
814 chip->model.resume = stereo_resume;
815 chip->model.mixer_init = generic_mixer_init;
816 chip->model.set_adc_params = set_no_params;
817 chip->model.dump_registers = dump_ak4396_registers;
818 chip->model.device_config = PLAYBACK_0_TO_I2S |
819 PLAYBACK_1_TO_SPDIF;
820 if (id->driver_data == MODEL_FANTASIA) {
821 chip->model.device_config |= CAPTURE_0_FROM_I2S_1;
822 chip->model.adc_mclks = OXYGEN_MCLKS(256, 128, 128);
823 }
824 chip->model.dac_channels_pcm = 2;
825 chip->model.dac_channels_mixer = 2;
826 break;
827 case MODEL_XONAR_DG:
828 chip->model = model_xonar_dg;
829 break;
553 } 830 }
554 if (id->driver_data == MODEL_MERIDIAN || 831 if (id->driver_data == MODEL_MERIDIAN ||
832 id->driver_data == MODEL_MERIDIAN_2G ||
555 id->driver_data == MODEL_CLARO_HALO) { 833 id->driver_data == MODEL_CLARO_HALO) {
556 chip->model.misc_flags = OXYGEN_MISC_MIDI; 834 chip->model.misc_flags = OXYGEN_MISC_MIDI;
557 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; 835 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
558 } 836 }
837 if (id->driver_data < ARRAY_SIZE(names) && names[id->driver_data])
838 chip->model.shortname = names[id->driver_data];
559 return 0; 839 return 0;
560} 840}
561 841
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 7d5222caa0a9..c2ae63d17cd2 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -16,6 +16,10 @@
16#define PCM_AC97 5 16#define PCM_AC97 5
17#define PCM_COUNT 6 17#define PCM_COUNT 6
18 18
19#define OXYGEN_MCLKS(f_single, f_double, f_quad) ((MCLK_##f_single << 0) | \
20 (MCLK_##f_double << 2) | \
21 (MCLK_##f_quad << 4))
22
19#define OXYGEN_IO_SIZE 0x100 23#define OXYGEN_IO_SIZE 0x100
20 24
21#define OXYGEN_EEPROM_ID 0x434d /* "CM" */ 25#define OXYGEN_EEPROM_ID 0x434d /* "CM" */
@@ -35,6 +39,7 @@
35#define MIDI_OUTPUT 0x0800 39#define MIDI_OUTPUT 0x0800
36#define MIDI_INPUT 0x1000 40#define MIDI_INPUT 0x1000
37#define AC97_CD_INPUT 0x2000 41#define AC97_CD_INPUT 0x2000
42#define AC97_FMIC_SWITCH 0x4000
38 43
39enum { 44enum {
40 CONTROL_SPDIF_PCM, 45 CONTROL_SPDIF_PCM,
@@ -65,6 +70,7 @@ struct snd_pcm_hardware;
65struct snd_pcm_hw_params; 70struct snd_pcm_hw_params;
66struct snd_kcontrol_new; 71struct snd_kcontrol_new;
67struct snd_rawmidi; 72struct snd_rawmidi;
73struct snd_info_buffer;
68struct oxygen; 74struct oxygen;
69 75
70struct oxygen_model { 76struct oxygen_model {
@@ -79,8 +85,6 @@ struct oxygen_model {
79 void (*resume)(struct oxygen *chip); 85 void (*resume)(struct oxygen *chip);
80 void (*pcm_hardware_filter)(unsigned int channel, 86 void (*pcm_hardware_filter)(unsigned int channel,
81 struct snd_pcm_hardware *hardware); 87 struct snd_pcm_hardware *hardware);
82 unsigned int (*get_i2s_mclk)(struct oxygen *chip, unsigned int channel,
83 struct snd_pcm_hw_params *hw_params);
84 void (*set_dac_params)(struct oxygen *chip, 88 void (*set_dac_params)(struct oxygen *chip,
85 struct snd_pcm_hw_params *params); 89 struct snd_pcm_hw_params *params);
86 void (*set_adc_params)(struct oxygen *chip, 90 void (*set_adc_params)(struct oxygen *chip,
@@ -92,15 +96,19 @@ struct oxygen_model {
92 void (*uart_input)(struct oxygen *chip); 96 void (*uart_input)(struct oxygen *chip);
93 void (*ac97_switch)(struct oxygen *chip, 97 void (*ac97_switch)(struct oxygen *chip,
94 unsigned int reg, unsigned int mute); 98 unsigned int reg, unsigned int mute);
99 void (*dump_registers)(struct oxygen *chip,
100 struct snd_info_buffer *buffer);
95 const unsigned int *dac_tlv; 101 const unsigned int *dac_tlv;
96 unsigned long private_data;
97 size_t model_data_size; 102 size_t model_data_size;
98 unsigned int device_config; 103 unsigned int device_config;
99 u8 dac_channels; 104 u8 dac_channels_pcm;
105 u8 dac_channels_mixer;
100 u8 dac_volume_min; 106 u8 dac_volume_min;
101 u8 dac_volume_max; 107 u8 dac_volume_max;
102 u8 misc_flags; 108 u8 misc_flags;
103 u8 function_flags; 109 u8 function_flags;
110 u8 dac_mclks;
111 u8 adc_mclks;
104 u16 dac_i2s_format; 112 u16 dac_i2s_format;
105 u16 adc_i2s_format; 113 u16 adc_i2s_format;
106}; 114};
@@ -121,7 +129,6 @@ struct oxygen {
121 u8 pcm_running; 129 u8 pcm_running;
122 u8 dac_routing; 130 u8 dac_routing;
123 u8 spdif_playback_enable; 131 u8 spdif_playback_enable;
124 u8 revision;
125 u8 has_ac97_0; 132 u8 has_ac97_0;
126 u8 has_ac97_1; 133 u8 has_ac97_1;
127 u32 spdif_bits; 134 u32 spdif_bits;
@@ -167,8 +174,6 @@ void oxygen_update_spdif_source(struct oxygen *chip);
167/* oxygen_pcm.c */ 174/* oxygen_pcm.c */
168 175
169int oxygen_pcm_init(struct oxygen *chip); 176int oxygen_pcm_init(struct oxygen *chip);
170unsigned int oxygen_default_i2s_mclk(struct oxygen *chip, unsigned int channel,
171 struct snd_pcm_hw_params *hw_params);
172 177
173/* oxygen_io.c */ 178/* oxygen_io.c */
174 179
diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c
index 09b2b2a36df5..f5164b1e1c80 100644
--- a/sound/pci/oxygen/oxygen_io.c
+++ b/sound/pci/oxygen/oxygen_io.c
@@ -197,11 +197,11 @@ void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data)
197{ 197{
198 unsigned int count; 198 unsigned int count;
199 199
200 /* should not need more than 7.68 us (24 * 320 ns) */ 200 /* should not need more than 30.72 us (24 * 1.28 us) */
201 count = 10; 201 count = 10;
202 while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY) 202 while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY)
203 && count > 0) { 203 && count > 0) {
204 udelay(1); 204 udelay(4);
205 --count; 205 --count;
206 } 206 }
207 207
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index e5ebe56fb0c5..70b739816fcc 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -202,7 +202,13 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
202 struct oxygen *chip = entry->private_data; 202 struct oxygen *chip = entry->private_data;
203 int i, j; 203 int i, j;
204 204
205 snd_iprintf(buffer, "CMI8788\n\n"); 205 switch (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_PACKAGE_ID_MASK) {
206 case OXYGEN_PACKAGE_ID_8786: i = '6'; break;
207 case OXYGEN_PACKAGE_ID_8787: i = '7'; break;
208 case OXYGEN_PACKAGE_ID_8788: i = '8'; break;
209 default: i = '?'; break;
210 }
211 snd_iprintf(buffer, "CMI878%c:\n", i);
206 for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) { 212 for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) {
207 snd_iprintf(buffer, "%02x:", i); 213 snd_iprintf(buffer, "%02x:", i);
208 for (j = 0; j < 0x10; ++j) 214 for (j = 0; j < 0x10; ++j)
@@ -212,7 +218,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
212 if (mutex_lock_interruptible(&chip->mutex) < 0) 218 if (mutex_lock_interruptible(&chip->mutex) < 0)
213 return; 219 return;
214 if (chip->has_ac97_0) { 220 if (chip->has_ac97_0) {
215 snd_iprintf(buffer, "\nAC97\n"); 221 snd_iprintf(buffer, "\nAC97:\n");
216 for (i = 0; i < 0x80; i += 0x10) { 222 for (i = 0; i < 0x80; i += 0x10) {
217 snd_iprintf(buffer, "%02x:", i); 223 snd_iprintf(buffer, "%02x:", i);
218 for (j = 0; j < 0x10; j += 2) 224 for (j = 0; j < 0x10; j += 2)
@@ -222,7 +228,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
222 } 228 }
223 } 229 }
224 if (chip->has_ac97_1) { 230 if (chip->has_ac97_1) {
225 snd_iprintf(buffer, "\nAC97 2\n"); 231 snd_iprintf(buffer, "\nAC97 2:\n");
226 for (i = 0; i < 0x80; i += 0x10) { 232 for (i = 0; i < 0x80; i += 0x10) {
227 snd_iprintf(buffer, "%02x:", i); 233 snd_iprintf(buffer, "%02x:", i);
228 for (j = 0; j < 0x10; j += 2) 234 for (j = 0; j < 0x10; j += 2)
@@ -232,13 +238,15 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
232 } 238 }
233 } 239 }
234 mutex_unlock(&chip->mutex); 240 mutex_unlock(&chip->mutex);
241 if (chip->model.dump_registers)
242 chip->model.dump_registers(chip, buffer);
235} 243}
236 244
237static void oxygen_proc_init(struct oxygen *chip) 245static void oxygen_proc_init(struct oxygen *chip)
238{ 246{
239 struct snd_info_entry *entry; 247 struct snd_info_entry *entry;
240 248
241 if (!snd_card_proc_new(chip->card, "cmi8788", &entry)) 249 if (!snd_card_proc_new(chip->card, "oxygen", &entry))
242 snd_info_set_text_ops(entry, chip, oxygen_proc_read); 250 snd_info_set_text_ops(entry, chip, oxygen_proc_read);
243} 251}
244#else 252#else
@@ -262,7 +270,7 @@ oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
262 */ 270 */
263 subdevice = oxygen_read_eeprom(chip, 2); 271 subdevice = oxygen_read_eeprom(chip, 2);
264 /* use default ID if EEPROM is missing */ 272 /* use default ID if EEPROM is missing */
265 if (subdevice == 0xffff) 273 if (subdevice == 0xffff && oxygen_read_eeprom(chip, 1) == 0xffff)
266 subdevice = 0x8788; 274 subdevice = 0x8788;
267 /* 275 /*
268 * We use only the subsystem device ID for searching because it is 276 * We use only the subsystem device ID for searching because it is
@@ -364,12 +372,7 @@ static void oxygen_init(struct oxygen *chip)
364 (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT); 372 (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT);
365 chip->spdif_pcm_bits = chip->spdif_bits; 373 chip->spdif_pcm_bits = chip->spdif_bits;
366 374
367 if (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2) 375 if (!(oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2))
368 chip->revision = 2;
369 else
370 chip->revision = 1;
371
372 if (chip->revision == 1)
373 oxygen_set_bits8(chip, OXYGEN_MISC, 376 oxygen_set_bits8(chip, OXYGEN_MISC,
374 OXYGEN_MISC_PCI_MEM_W_1_CLOCK); 377 OXYGEN_MISC_PCI_MEM_W_1_CLOCK);
375 378
@@ -406,28 +409,40 @@ static void oxygen_init(struct oxygen *chip)
406 (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT)); 409 (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT));
407 oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2); 410 oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2);
408 oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT, 411 oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT,
409 OXYGEN_RATE_48000 | chip->model.dac_i2s_format | 412 OXYGEN_RATE_48000 |
410 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 413 chip->model.dac_i2s_format |
411 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 414 OXYGEN_I2S_MCLK(chip->model.dac_mclks) |
415 OXYGEN_I2S_BITS_16 |
416 OXYGEN_I2S_MASTER |
417 OXYGEN_I2S_BCLK_64);
412 if (chip->model.device_config & CAPTURE_0_FROM_I2S_1) 418 if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
413 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 419 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
414 OXYGEN_RATE_48000 | chip->model.adc_i2s_format | 420 OXYGEN_RATE_48000 |
415 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 421 chip->model.adc_i2s_format |
416 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 422 OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
423 OXYGEN_I2S_BITS_16 |
424 OXYGEN_I2S_MASTER |
425 OXYGEN_I2S_BCLK_64);
417 else 426 else
418 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 427 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
419 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); 428 OXYGEN_I2S_MASTER |
429 OXYGEN_I2S_MUTE_MCLK);
420 if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 | 430 if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 |
421 CAPTURE_2_FROM_I2S_2)) 431 CAPTURE_2_FROM_I2S_2))
422 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, 432 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
423 OXYGEN_RATE_48000 | chip->model.adc_i2s_format | 433 OXYGEN_RATE_48000 |
424 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 434 chip->model.adc_i2s_format |
425 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 435 OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
436 OXYGEN_I2S_BITS_16 |
437 OXYGEN_I2S_MASTER |
438 OXYGEN_I2S_BCLK_64);
426 else 439 else
427 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, 440 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
428 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); 441 OXYGEN_I2S_MASTER |
442 OXYGEN_I2S_MUTE_MCLK);
429 oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, 443 oxygen_write16(chip, OXYGEN_I2S_C_FORMAT,
430 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); 444 OXYGEN_I2S_MASTER |
445 OXYGEN_I2S_MUTE_MCLK);
431 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, 446 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
432 OXYGEN_SPDIF_OUT_ENABLE | 447 OXYGEN_SPDIF_OUT_ENABLE |
433 OXYGEN_SPDIF_LOOPBACK); 448 OXYGEN_SPDIF_LOOPBACK);
@@ -557,7 +572,8 @@ static void oxygen_card_free(struct snd_card *card)
557 oxygen_shutdown(chip); 572 oxygen_shutdown(chip);
558 if (chip->irq >= 0) 573 if (chip->irq >= 0)
559 free_irq(chip->irq, chip); 574 free_irq(chip->irq, chip);
560 flush_scheduled_work(); 575 flush_work_sync(&chip->spdif_input_bits_work);
576 flush_work_sync(&chip->gpio_work);
561 chip->model.cleanup(chip); 577 chip->model.cleanup(chip);
562 kfree(chip->model_data); 578 kfree(chip->model_data);
563 mutex_destroy(&chip->mutex); 579 mutex_destroy(&chip->mutex);
@@ -648,8 +664,8 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
648 664
649 strcpy(card->driver, chip->model.chip); 665 strcpy(card->driver, chip->model.chip);
650 strcpy(card->shortname, chip->model.shortname); 666 strcpy(card->shortname, chip->model.shortname);
651 sprintf(card->longname, "%s (rev %u) at %#lx, irq %i", 667 sprintf(card->longname, "%s at %#lx, irq %i",
652 chip->model.longname, chip->revision, chip->addr, chip->irq); 668 chip->model.longname, chip->addr, chip->irq);
653 strcpy(card->mixername, chip->model.chip); 669 strcpy(card->mixername, chip->model.chip);
654 snd_component_add(card, chip->model.chip); 670 snd_component_add(card, chip->model.chip);
655 671
@@ -733,7 +749,8 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
733 spin_unlock_irq(&chip->reg_lock); 749 spin_unlock_irq(&chip->reg_lock);
734 750
735 synchronize_irq(chip->irq); 751 synchronize_irq(chip->irq);
736 flush_scheduled_work(); 752 flush_work_sync(&chip->spdif_input_bits_work);
753 flush_work_sync(&chip->gpio_work);
737 chip->interrupt_mask = saved_interrupt_mask; 754 chip->interrupt_mask = saved_interrupt_mask;
738 755
739 pci_disable_device(pci); 756 pci_disable_device(pci);
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 2849b36f5f7e..9bff14d5895d 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -31,7 +31,7 @@ static int dac_volume_info(struct snd_kcontrol *ctl,
31 struct oxygen *chip = ctl->private_data; 31 struct oxygen *chip = ctl->private_data;
32 32
33 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 33 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
34 info->count = chip->model.dac_channels; 34 info->count = chip->model.dac_channels_mixer;
35 info->value.integer.min = chip->model.dac_volume_min; 35 info->value.integer.min = chip->model.dac_volume_min;
36 info->value.integer.max = chip->model.dac_volume_max; 36 info->value.integer.max = chip->model.dac_volume_max;
37 return 0; 37 return 0;
@@ -44,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl,
44 unsigned int i; 44 unsigned int i;
45 45
46 mutex_lock(&chip->mutex); 46 mutex_lock(&chip->mutex);
47 for (i = 0; i < chip->model.dac_channels; ++i) 47 for (i = 0; i < chip->model.dac_channels_mixer; ++i)
48 value->value.integer.value[i] = chip->dac_volume[i]; 48 value->value.integer.value[i] = chip->dac_volume[i];
49 mutex_unlock(&chip->mutex); 49 mutex_unlock(&chip->mutex);
50 return 0; 50 return 0;
@@ -59,7 +59,7 @@ static int dac_volume_put(struct snd_kcontrol *ctl,
59 59
60 changed = 0; 60 changed = 0;
61 mutex_lock(&chip->mutex); 61 mutex_lock(&chip->mutex);
62 for (i = 0; i < chip->model.dac_channels; ++i) 62 for (i = 0; i < chip->model.dac_channels_mixer; ++i)
63 if (value->value.integer.value[i] != chip->dac_volume[i]) { 63 if (value->value.integer.value[i] != chip->dac_volume[i]) {
64 chip->dac_volume[i] = value->value.integer.value[i]; 64 chip->dac_volume[i] = value->value.integer.value[i];
65 changed = 1; 65 changed = 1;
@@ -97,6 +97,16 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
97 return changed; 97 return changed;
98} 98}
99 99
100static unsigned int upmix_item_count(struct oxygen *chip)
101{
102 if (chip->model.dac_channels_pcm < 8)
103 return 2;
104 else if (chip->model.update_center_lfe_mix)
105 return 5;
106 else
107 return 3;
108}
109
100static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 110static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
101{ 111{
102 static const char *const names[5] = { 112 static const char *const names[5] = {
@@ -107,15 +117,9 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
107 "Front+Surround+Center/LFE+Back", 117 "Front+Surround+Center/LFE+Back",
108 }; 118 };
109 struct oxygen *chip = ctl->private_data; 119 struct oxygen *chip = ctl->private_data;
110 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; 120 unsigned int count = upmix_item_count(chip);
111 121
112 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 122 return snd_ctl_enum_info(info, 1, count, names);
113 info->count = 1;
114 info->value.enumerated.items = count;
115 if (info->value.enumerated.item >= count)
116 info->value.enumerated.item = count - 1;
117 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
118 return 0;
119} 123}
120 124
121static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 125static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
@@ -188,7 +192,7 @@ void oxygen_update_dac_routing(struct oxygen *chip)
188static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 192static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
189{ 193{
190 struct oxygen *chip = ctl->private_data; 194 struct oxygen *chip = ctl->private_data;
191 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; 195 unsigned int count = upmix_item_count(chip);
192 int changed; 196 int changed;
193 197
194 if (value->value.enumerated.item[0] >= count) 198 if (value->value.enumerated.item[0] >= count)
@@ -430,30 +434,31 @@ static int spdif_input_default_get(struct snd_kcontrol *ctl,
430 return 0; 434 return 0;
431} 435}
432 436
433static int spdif_loopback_get(struct snd_kcontrol *ctl, 437static int spdif_bit_switch_get(struct snd_kcontrol *ctl,
434 struct snd_ctl_elem_value *value) 438 struct snd_ctl_elem_value *value)
435{ 439{
436 struct oxygen *chip = ctl->private_data; 440 struct oxygen *chip = ctl->private_data;
441 u32 bit = ctl->private_value;
437 442
438 value->value.integer.value[0] = 443 value->value.integer.value[0] =
439 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) 444 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) & bit);
440 & OXYGEN_SPDIF_LOOPBACK);
441 return 0; 445 return 0;
442} 446}
443 447
444static int spdif_loopback_put(struct snd_kcontrol *ctl, 448static int spdif_bit_switch_put(struct snd_kcontrol *ctl,
445 struct snd_ctl_elem_value *value) 449 struct snd_ctl_elem_value *value)
446{ 450{
447 struct oxygen *chip = ctl->private_data; 451 struct oxygen *chip = ctl->private_data;
452 u32 bit = ctl->private_value;
448 u32 oldreg, newreg; 453 u32 oldreg, newreg;
449 int changed; 454 int changed;
450 455
451 spin_lock_irq(&chip->reg_lock); 456 spin_lock_irq(&chip->reg_lock);
452 oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL); 457 oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
453 if (value->value.integer.value[0]) 458 if (value->value.integer.value[0])
454 newreg = oldreg | OXYGEN_SPDIF_LOOPBACK; 459 newreg = oldreg | bit;
455 else 460 else
456 newreg = oldreg & ~OXYGEN_SPDIF_LOOPBACK; 461 newreg = oldreg & ~bit;
457 changed = newreg != oldreg; 462 changed = newreg != oldreg;
458 if (changed) 463 if (changed)
459 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg); 464 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg);
@@ -644,6 +649,46 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
644 return change; 649 return change;
645} 650}
646 651
652static int mic_fmic_source_info(struct snd_kcontrol *ctl,
653 struct snd_ctl_elem_info *info)
654{
655 static const char *const names[] = { "Mic Jack", "Front Panel" };
656
657 return snd_ctl_enum_info(info, 1, 2, names);
658}
659
660static int mic_fmic_source_get(struct snd_kcontrol *ctl,
661 struct snd_ctl_elem_value *value)
662{
663 struct oxygen *chip = ctl->private_data;
664
665 mutex_lock(&chip->mutex);
666 value->value.enumerated.item[0] =
667 !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC);
668 mutex_unlock(&chip->mutex);
669 return 0;
670}
671
672static int mic_fmic_source_put(struct snd_kcontrol *ctl,
673 struct snd_ctl_elem_value *value)
674{
675 struct oxygen *chip = ctl->private_data;
676 u16 oldreg, newreg;
677 int change;
678
679 mutex_lock(&chip->mutex);
680 oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK);
681 if (value->value.enumerated.item[0])
682 newreg = oldreg | CM9780_FMIC2MIC;
683 else
684 newreg = oldreg & ~CM9780_FMIC2MIC;
685 change = newreg != oldreg;
686 if (change)
687 oxygen_write_ac97(chip, 0, CM9780_JACK, newreg);
688 mutex_unlock(&chip->mutex);
689 return change;
690}
691
647static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl, 692static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl,
648 struct snd_ctl_elem_info *info) 693 struct snd_ctl_elem_info *info)
649{ 694{
@@ -791,8 +836,17 @@ static const struct snd_kcontrol_new spdif_input_controls[] = {
791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 836 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
792 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH), 837 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH),
793 .info = snd_ctl_boolean_mono_info, 838 .info = snd_ctl_boolean_mono_info,
794 .get = spdif_loopback_get, 839 .get = spdif_bit_switch_get,
795 .put = spdif_loopback_put, 840 .put = spdif_bit_switch_put,
841 .private_value = OXYGEN_SPDIF_LOOPBACK,
842 },
843 {
844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
845 .name = SNDRV_CTL_NAME_IEC958("Validity Check ",CAPTURE,SWITCH),
846 .info = snd_ctl_boolean_mono_info,
847 .get = spdif_bit_switch_get,
848 .put = spdif_bit_switch_put,
849 .private_value = OXYGEN_SPDIF_SPDVALID,
796 }, 850 },
797}; 851};
798 852
@@ -908,6 +962,13 @@ static const struct snd_kcontrol_new ac97_controls[] = {
908 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), 962 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0),
909 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), 963 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
910 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), 964 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
965 {
966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
967 .name = "Mic Source Capture Enum",
968 .info = mic_fmic_source_info,
969 .get = mic_fmic_source_get,
970 .put = mic_fmic_source_put,
971 },
911 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), 972 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
912 AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), 973 AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1),
913 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), 974 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
@@ -970,7 +1031,10 @@ static int add_controls(struct oxygen *chip,
970 continue; 1031 continue;
971 } 1032 }
972 if (!strcmp(template.name, "Stereo Upmixing") && 1033 if (!strcmp(template.name, "Stereo Upmixing") &&
973 chip->model.dac_channels == 2) 1034 chip->model.dac_channels_pcm == 2)
1035 continue;
1036 if (!strcmp(template.name, "Mic Source Capture Enum") &&
1037 !(chip->model.device_config & AC97_FMIC_SWITCH))
974 continue; 1038 continue;
975 if (!strncmp(template.name, "CD Capture ", 11) && 1039 if (!strncmp(template.name, "CD Capture ", 11) &&
976 !(chip->model.device_config & AC97_CD_INPUT)) 1040 !(chip->model.device_config & AC97_CD_INPUT))
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index 814667442eb0..d5533e34ece9 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -39,7 +39,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = {
39 SNDRV_PCM_INFO_MMAP_VALID | 39 SNDRV_PCM_INFO_MMAP_VALID |
40 SNDRV_PCM_INFO_INTERLEAVED | 40 SNDRV_PCM_INFO_INTERLEAVED |
41 SNDRV_PCM_INFO_PAUSE | 41 SNDRV_PCM_INFO_PAUSE |
42 SNDRV_PCM_INFO_SYNC_START, 42 SNDRV_PCM_INFO_SYNC_START |
43 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE | 44 .formats = SNDRV_PCM_FMTBIT_S16_LE |
44 SNDRV_PCM_FMTBIT_S32_LE, 45 SNDRV_PCM_FMTBIT_S32_LE,
45 .rates = SNDRV_PCM_RATE_32000 | 46 .rates = SNDRV_PCM_RATE_32000 |
@@ -65,7 +66,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
65 SNDRV_PCM_INFO_MMAP_VALID | 66 SNDRV_PCM_INFO_MMAP_VALID |
66 SNDRV_PCM_INFO_INTERLEAVED | 67 SNDRV_PCM_INFO_INTERLEAVED |
67 SNDRV_PCM_INFO_PAUSE | 68 SNDRV_PCM_INFO_PAUSE |
68 SNDRV_PCM_INFO_SYNC_START, 69 SNDRV_PCM_INFO_SYNC_START |
70 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
69 .formats = SNDRV_PCM_FMTBIT_S16_LE | 71 .formats = SNDRV_PCM_FMTBIT_S16_LE |
70 SNDRV_PCM_FMTBIT_S32_LE, 72 SNDRV_PCM_FMTBIT_S32_LE,
71 .rates = SNDRV_PCM_RATE_32000 | 73 .rates = SNDRV_PCM_RATE_32000 |
@@ -91,7 +93,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = {
91 SNDRV_PCM_INFO_MMAP_VALID | 93 SNDRV_PCM_INFO_MMAP_VALID |
92 SNDRV_PCM_INFO_INTERLEAVED | 94 SNDRV_PCM_INFO_INTERLEAVED |
93 SNDRV_PCM_INFO_PAUSE | 95 SNDRV_PCM_INFO_PAUSE |
94 SNDRV_PCM_INFO_SYNC_START, 96 SNDRV_PCM_INFO_SYNC_START |
97 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
95 .formats = SNDRV_PCM_FMTBIT_S16_LE, 98 .formats = SNDRV_PCM_FMTBIT_S16_LE,
96 .rates = SNDRV_PCM_RATE_48000, 99 .rates = SNDRV_PCM_RATE_48000,
97 .rate_min = 48000, 100 .rate_min = 48000,
@@ -140,7 +143,7 @@ static int oxygen_open(struct snd_pcm_substream *substream,
140 runtime->hw.rate_min = 44100; 143 runtime->hw.rate_min = 44100;
141 break; 144 break;
142 case PCM_MULTICH: 145 case PCM_MULTICH:
143 runtime->hw.channels_max = chip->model.dac_channels; 146 runtime->hw.channels_max = chip->model.dac_channels_pcm;
144 break; 147 break;
145 } 148 }
146 if (chip->model.pcm_hardware_filter) 149 if (chip->model.pcm_hardware_filter)
@@ -271,17 +274,6 @@ static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params)
271 } 274 }
272} 275}
273 276
274unsigned int oxygen_default_i2s_mclk(struct oxygen *chip,
275 unsigned int channel,
276 struct snd_pcm_hw_params *hw_params)
277{
278 if (params_rate(hw_params) <= 96000)
279 return OXYGEN_I2S_MCLK_256;
280 else
281 return OXYGEN_I2S_MCLK_128;
282}
283EXPORT_SYMBOL(oxygen_default_i2s_mclk);
284
285static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params) 277static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params)
286{ 278{
287 if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE) 279 if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
@@ -341,6 +333,26 @@ static int oxygen_hw_params(struct snd_pcm_substream *substream,
341 return 0; 333 return 0;
342} 334}
343 335
336static u16 get_mclk(struct oxygen *chip, unsigned int channel,
337 struct snd_pcm_hw_params *params)
338{
339 unsigned int mclks, shift;
340
341 if (channel == PCM_MULTICH)
342 mclks = chip->model.dac_mclks;
343 else
344 mclks = chip->model.adc_mclks;
345
346 if (params_rate(params) <= 48000)
347 shift = 0;
348 else if (params_rate(params) <= 96000)
349 shift = 2;
350 else
351 shift = 4;
352
353 return OXYGEN_I2S_MCLK(mclks >> shift);
354}
355
344static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, 356static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
345 struct snd_pcm_hw_params *hw_params) 357 struct snd_pcm_hw_params *hw_params)
346{ 358{
@@ -357,8 +369,8 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
357 OXYGEN_REC_FORMAT_A_MASK); 369 OXYGEN_REC_FORMAT_A_MASK);
358 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, 370 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
359 oxygen_rate(hw_params) | 371 oxygen_rate(hw_params) |
360 chip->model.get_i2s_mclk(chip, PCM_A, hw_params) |
361 chip->model.adc_i2s_format | 372 chip->model.adc_i2s_format |
373 get_mclk(chip, PCM_A, hw_params) |
362 oxygen_i2s_bits(hw_params), 374 oxygen_i2s_bits(hw_params),
363 OXYGEN_I2S_RATE_MASK | 375 OXYGEN_I2S_RATE_MASK |
364 OXYGEN_I2S_FORMAT_MASK | 376 OXYGEN_I2S_FORMAT_MASK |
@@ -393,9 +405,8 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
393 if (!is_ac97) 405 if (!is_ac97)
394 oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, 406 oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
395 oxygen_rate(hw_params) | 407 oxygen_rate(hw_params) |
396 chip->model.get_i2s_mclk(chip, PCM_B,
397 hw_params) |
398 chip->model.adc_i2s_format | 408 chip->model.adc_i2s_format |
409 get_mclk(chip, PCM_B, hw_params) |
399 oxygen_i2s_bits(hw_params), 410 oxygen_i2s_bits(hw_params),
400 OXYGEN_I2S_RATE_MASK | 411 OXYGEN_I2S_RATE_MASK |
401 OXYGEN_I2S_FORMAT_MASK | 412 OXYGEN_I2S_FORMAT_MASK |
@@ -476,8 +487,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
476 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, 487 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
477 oxygen_rate(hw_params) | 488 oxygen_rate(hw_params) |
478 chip->model.dac_i2s_format | 489 chip->model.dac_i2s_format |
479 chip->model.get_i2s_mclk(chip, PCM_MULTICH, 490 get_mclk(chip, PCM_MULTICH, hw_params) |
480 hw_params) |
481 oxygen_i2s_bits(hw_params), 491 oxygen_i2s_bits(hw_params),
482 OXYGEN_I2S_RATE_MASK | 492 OXYGEN_I2S_RATE_MASK |
483 OXYGEN_I2S_FORMAT_MASK | 493 OXYGEN_I2S_FORMAT_MASK |
@@ -530,7 +540,10 @@ static int oxygen_prepare(struct snd_pcm_substream *substream)
530 oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); 540 oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
531 oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); 541 oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
532 542
533 chip->interrupt_mask |= channel_mask; 543 if (substream->runtime->no_period_wakeup)
544 chip->interrupt_mask &= ~channel_mask;
545 else
546 chip->interrupt_mask |= channel_mask;
534 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); 547 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
535 spin_unlock_irq(&chip->reg_lock); 548 spin_unlock_irq(&chip->reg_lock);
536 return 0; 549 return 0;
diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h
index 4dcd41b78258..63dc7a0ab555 100644
--- a/sound/pci/oxygen/oxygen_regs.h
+++ b/sound/pci/oxygen/oxygen_regs.h
@@ -139,9 +139,11 @@
139#define OXYGEN_I2S_FORMAT_I2S 0x0000 139#define OXYGEN_I2S_FORMAT_I2S 0x0000
140#define OXYGEN_I2S_FORMAT_LJUST 0x0008 140#define OXYGEN_I2S_FORMAT_LJUST 0x0008
141#define OXYGEN_I2S_MCLK_MASK 0x0030 /* MCLK/LRCK */ 141#define OXYGEN_I2S_MCLK_MASK 0x0030 /* MCLK/LRCK */
142#define OXYGEN_I2S_MCLK_128 0x0000 142#define OXYGEN_I2S_MCLK_SHIFT 4
143#define OXYGEN_I2S_MCLK_256 0x0010 143#define MCLK_128 0
144#define OXYGEN_I2S_MCLK_512 0x0020 144#define MCLK_256 1
145#define MCLK_512 2
146#define OXYGEN_I2S_MCLK(f) (((f) & 3) << OXYGEN_I2S_MCLK_SHIFT)
145#define OXYGEN_I2S_BITS_MASK 0x00c0 147#define OXYGEN_I2S_BITS_MASK 0x00c0
146#define OXYGEN_I2S_BITS_16 0x0000 148#define OXYGEN_I2S_BITS_16 0x0000
147#define OXYGEN_I2S_BITS_20 0x0040 149#define OXYGEN_I2S_BITS_20 0x0040
@@ -238,11 +240,11 @@
238#define OXYGEN_SPI_DATA_LENGTH_MASK 0x02 240#define OXYGEN_SPI_DATA_LENGTH_MASK 0x02
239#define OXYGEN_SPI_DATA_LENGTH_2 0x00 241#define OXYGEN_SPI_DATA_LENGTH_2 0x00
240#define OXYGEN_SPI_DATA_LENGTH_3 0x02 242#define OXYGEN_SPI_DATA_LENGTH_3 0x02
241#define OXYGEN_SPI_CLOCK_MASK 0xc0 243#define OXYGEN_SPI_CLOCK_MASK 0x0c
242#define OXYGEN_SPI_CLOCK_160 0x00 /* ns */ 244#define OXYGEN_SPI_CLOCK_160 0x00 /* ns */
243#define OXYGEN_SPI_CLOCK_320 0x40 245#define OXYGEN_SPI_CLOCK_320 0x04
244#define OXYGEN_SPI_CLOCK_640 0x80 246#define OXYGEN_SPI_CLOCK_640 0x08
245#define OXYGEN_SPI_CLOCK_1280 0xc0 247#define OXYGEN_SPI_CLOCK_1280 0x0c
246#define OXYGEN_SPI_CODEC_MASK 0x70 /* 0..5 */ 248#define OXYGEN_SPI_CODEC_MASK 0x70 /* 0..5 */
247#define OXYGEN_SPI_CODEC_SHIFT 4 249#define OXYGEN_SPI_CODEC_SHIFT 4
248#define OXYGEN_SPI_CEN_MASK 0x80 250#define OXYGEN_SPI_CEN_MASK 0x80
diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h
index b35343b0a9a5..0434c207e811 100644
--- a/sound/pci/oxygen/xonar.h
+++ b/sound/pci/oxygen/xonar.h
@@ -24,6 +24,8 @@ void xonar_init_ext_power(struct oxygen *chip);
24void xonar_init_cs53x1(struct oxygen *chip); 24void xonar_init_cs53x1(struct oxygen *chip);
25void xonar_set_cs53x1_params(struct oxygen *chip, 25void xonar_set_cs53x1_params(struct oxygen *chip,
26 struct snd_pcm_hw_params *params); 26 struct snd_pcm_hw_params *params);
27
28#define XONAR_GPIO_BIT_INVERT (1 << 16)
27int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl, 29int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
28 struct snd_ctl_elem_value *value); 30 struct snd_ctl_elem_value *value);
29int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl, 31int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index aa27c31049af..9f72d424969c 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -22,29 +22,28 @@
22 * 22 *
23 * CMI8788: 23 * CMI8788:
24 * 24 *
25 * I²C <-> CS4398 (front) 25 * I²C <-> CS4398 (addr 1001111) (front)
26 * <-> CS4362A (surround, center/LFE, back) 26 * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
27 * 27 *
28 * GPI 0 <- external power present (DX only) 28 * GPI 0 <- external power present (DX only)
29 * 29 *
30 * GPIO 0 -> enable output to speakers 30 * GPIO 0 -> enable output to speakers
31 * GPIO 1 -> enable front panel I/O 31 * GPIO 1 -> route output to front panel
32 * GPIO 2 -> M0 of CS5361 32 * GPIO 2 -> M0 of CS5361
33 * GPIO 3 -> M1 of CS5361 33 * GPIO 3 -> M1 of CS5361
34 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) 34 * GPIO 6 -> ?
35 * GPIO 7 -> ?
36 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
35 * 37 *
36 * CS4398: 38 * CM9780:
37 *
38 * AD0 <- 1
39 * AD1 <- 1
40 * 39 *
41 * CS4362A: 40 * LINE_OUT -> input of ADC
42 * 41 *
43 * AD0 <- 0 42 * AUX_IN <- aux
43 * MIC_IN <- mic
44 * FMIC_IN <- front mic
44 * 45 *
45 * CM9780: 46 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
46 *
47 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
48 */ 47 */
49 48
50#include <linux/pci.h> 49#include <linux/pci.h>
@@ -63,6 +62,7 @@
63#define GPI_EXT_POWER 0x01 62#define GPI_EXT_POWER 0x01
64#define GPIO_D1_OUTPUT_ENABLE 0x0001 63#define GPIO_D1_OUTPUT_ENABLE 0x0001
65#define GPIO_D1_FRONT_PANEL 0x0002 64#define GPIO_D1_FRONT_PANEL 0x0002
65#define GPIO_D1_MAGIC 0x00c0
66#define GPIO_D1_INPUT_ROUTE 0x0100 66#define GPIO_D1_INPUT_ROUTE 0x0100
67 67
68#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */ 68#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
@@ -169,12 +169,12 @@ static void xonar_d1_init(struct oxygen *chip)
169 cs43xx_registers_init(chip); 169 cs43xx_registers_init(chip);
170 170
171 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 171 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
172 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); 172 GPIO_D1_FRONT_PANEL |
173 GPIO_D1_MAGIC |
174 GPIO_D1_INPUT_ROUTE);
173 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 175 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
174 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); 176 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
175 177
176 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
177
178 xonar_init_cs53x1(chip); 178 xonar_init_cs53x1(chip);
179 xonar_enable_output(chip); 179 xonar_enable_output(chip);
180 180
@@ -284,7 +284,7 @@ static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
284 284
285static const struct snd_kcontrol_new front_panel_switch = { 285static const struct snd_kcontrol_new front_panel_switch = {
286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
287 .name = "Front Panel Switch", 287 .name = "Front Panel Playback Switch",
288 .info = snd_ctl_boolean_mono_info, 288 .info = snd_ctl_boolean_mono_info,
289 .get = xonar_gpio_bit_switch_get, 289 .get = xonar_gpio_bit_switch_get,
290 .put = xonar_gpio_bit_switch_put, 290 .put = xonar_gpio_bit_switch_put,
@@ -298,13 +298,7 @@ static int rolloff_info(struct snd_kcontrol *ctl,
298 "Fast Roll-off", "Slow Roll-off" 298 "Fast Roll-off", "Slow Roll-off"
299 }; 299 };
300 300
301 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 301 return snd_ctl_enum_info(info, 1, 2, names);
302 info->count = 1;
303 info->value.enumerated.items = 2;
304 if (info->value.enumerated.item >= 2)
305 info->value.enumerated.item = 1;
306 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
307 return 0;
308} 302}
309 303
310static int rolloff_get(struct snd_kcontrol *ctl, 304static int rolloff_get(struct snd_kcontrol *ctl,
@@ -380,6 +374,30 @@ static int xonar_d1_mixer_init(struct oxygen *chip)
380 return 0; 374 return 0;
381} 375}
382 376
377static void dump_cs4362a_registers(struct xonar_cs43xx *data,
378 struct snd_info_buffer *buffer)
379{
380 unsigned int i;
381
382 snd_iprintf(buffer, "\nCS4362A:");
383 for (i = 1; i <= 14; ++i)
384 snd_iprintf(buffer, " %02x", data->cs4362a_regs[i]);
385 snd_iprintf(buffer, "\n");
386}
387
388static void dump_d1_registers(struct oxygen *chip,
389 struct snd_info_buffer *buffer)
390{
391 struct xonar_cs43xx *data = chip->model_data;
392 unsigned int i;
393
394 snd_iprintf(buffer, "\nCS4398: 7?");
395 for (i = 2; i <= 8; ++i)
396 snd_iprintf(buffer, " %02x", data->cs4398_regs[i]);
397 snd_iprintf(buffer, "\n");
398 dump_cs4362a_registers(data, buffer);
399}
400
383static const struct oxygen_model model_xonar_d1 = { 401static const struct oxygen_model model_xonar_d1 = {
384 .longname = "Asus Virtuoso 100", 402 .longname = "Asus Virtuoso 100",
385 .chip = "AV200", 403 .chip = "AV200",
@@ -388,22 +406,26 @@ static const struct oxygen_model model_xonar_d1 = {
388 .cleanup = xonar_d1_cleanup, 406 .cleanup = xonar_d1_cleanup,
389 .suspend = xonar_d1_suspend, 407 .suspend = xonar_d1_suspend,
390 .resume = xonar_d1_resume, 408 .resume = xonar_d1_resume,
391 .get_i2s_mclk = oxygen_default_i2s_mclk,
392 .set_dac_params = set_cs43xx_params, 409 .set_dac_params = set_cs43xx_params,
393 .set_adc_params = xonar_set_cs53x1_params, 410 .set_adc_params = xonar_set_cs53x1_params,
394 .update_dac_volume = update_cs43xx_volume, 411 .update_dac_volume = update_cs43xx_volume,
395 .update_dac_mute = update_cs43xx_mute, 412 .update_dac_mute = update_cs43xx_mute,
396 .update_center_lfe_mix = update_cs43xx_center_lfe_mix, 413 .update_center_lfe_mix = update_cs43xx_center_lfe_mix,
397 .ac97_switch = xonar_d1_line_mic_ac97_switch, 414 .ac97_switch = xonar_d1_line_mic_ac97_switch,
415 .dump_registers = dump_d1_registers,
398 .dac_tlv = cs4362a_db_scale, 416 .dac_tlv = cs4362a_db_scale,
399 .model_data_size = sizeof(struct xonar_cs43xx), 417 .model_data_size = sizeof(struct xonar_cs43xx),
400 .device_config = PLAYBACK_0_TO_I2S | 418 .device_config = PLAYBACK_0_TO_I2S |
401 PLAYBACK_1_TO_SPDIF | 419 PLAYBACK_1_TO_SPDIF |
402 CAPTURE_0_FROM_I2S_2, 420 CAPTURE_0_FROM_I2S_2 |
403 .dac_channels = 8, 421 AC97_FMIC_SWITCH,
422 .dac_channels_pcm = 8,
423 .dac_channels_mixer = 8,
404 .dac_volume_min = 127 - 60, 424 .dac_volume_min = 127 - 60,
405 .dac_volume_max = 127, 425 .dac_volume_max = 127,
406 .function_flags = OXYGEN_FUNCTION_2WIRE, 426 .function_flags = OXYGEN_FUNCTION_2WIRE,
427 .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
428 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
407 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 429 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
408 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 430 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
409}; 431};
diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c
new file mode 100644
index 000000000000..e4de0b8d087a
--- /dev/null
+++ b/sound/pci/oxygen/xonar_dg.c
@@ -0,0 +1,572 @@
1/*
2 * card driver for the Xonar DG
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver 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 driver; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * Xonar DG
21 * --------
22 *
23 * CMI8788:
24 *
25 * SPI 0 -> CS4245
26 *
27 * GPIO 3 <- ?
28 * GPIO 4 <- headphone detect
29 * GPIO 5 -> route input jack to line-in (0) or mic-in (1)
30 * GPIO 6 -> route input jack to line-in (0) or mic-in (1)
31 * GPIO 7 -> enable rear headphone amp
32 * GPIO 8 -> enable output to speakers
33 *
34 * CS4245:
35 *
36 * input 1 <- aux
37 * input 2 <- front mic
38 * input 4 <- line/mic
39 * aux out -> front panel headphones
40 */
41
42#include <linux/pci.h>
43#include <linux/delay.h>
44#include <sound/control.h>
45#include <sound/core.h>
46#include <sound/info.h>
47#include <sound/pcm.h>
48#include <sound/tlv.h>
49#include "oxygen.h"
50#include "xonar_dg.h"
51#include "cs4245.h"
52
53#define GPIO_MAGIC 0x0008
54#define GPIO_HP_DETECT 0x0010
55#define GPIO_INPUT_ROUTE 0x0060
56#define GPIO_HP_REAR 0x0080
57#define GPIO_OUTPUT_ENABLE 0x0100
58
59struct dg {
60 unsigned int output_sel;
61 s8 input_vol[4][2];
62 unsigned int input_sel;
63 u8 hp_vol_att;
64 u8 cs4245_regs[0x11];
65};
66
67static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value)
68{
69 struct dg *data = chip->model_data;
70
71 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
72 OXYGEN_SPI_DATA_LENGTH_3 |
73 OXYGEN_SPI_CLOCK_1280 |
74 (0 << OXYGEN_SPI_CODEC_SHIFT) |
75 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
76 CS4245_SPI_ADDRESS |
77 CS4245_SPI_WRITE |
78 (value << 8) | reg);
79 data->cs4245_regs[reg] = value;
80}
81
82static void cs4245_write_cached(struct oxygen *chip, unsigned int reg, u8 value)
83{
84 struct dg *data = chip->model_data;
85
86 if (value != data->cs4245_regs[reg])
87 cs4245_write(chip, reg, value);
88}
89
90static void cs4245_registers_init(struct oxygen *chip)
91{
92 struct dg *data = chip->model_data;
93
94 cs4245_write(chip, CS4245_POWER_CTRL, CS4245_PDN);
95 cs4245_write(chip, CS4245_DAC_CTRL_1,
96 data->cs4245_regs[CS4245_DAC_CTRL_1]);
97 cs4245_write(chip, CS4245_ADC_CTRL,
98 data->cs4245_regs[CS4245_ADC_CTRL]);
99 cs4245_write(chip, CS4245_SIGNAL_SEL,
100 data->cs4245_regs[CS4245_SIGNAL_SEL]);
101 cs4245_write(chip, CS4245_PGA_B_CTRL,
102 data->cs4245_regs[CS4245_PGA_B_CTRL]);
103 cs4245_write(chip, CS4245_PGA_A_CTRL,
104 data->cs4245_regs[CS4245_PGA_A_CTRL]);
105 cs4245_write(chip, CS4245_ANALOG_IN,
106 data->cs4245_regs[CS4245_ANALOG_IN]);
107 cs4245_write(chip, CS4245_DAC_A_CTRL,
108 data->cs4245_regs[CS4245_DAC_A_CTRL]);
109 cs4245_write(chip, CS4245_DAC_B_CTRL,
110 data->cs4245_regs[CS4245_DAC_B_CTRL]);
111 cs4245_write(chip, CS4245_DAC_CTRL_2,
112 CS4245_DAC_SOFT | CS4245_DAC_ZERO | CS4245_INVERT_DAC);
113 cs4245_write(chip, CS4245_INT_MASK, 0);
114 cs4245_write(chip, CS4245_POWER_CTRL, 0);
115}
116
117static void cs4245_init(struct oxygen *chip)
118{
119 struct dg *data = chip->model_data;
120
121 data->cs4245_regs[CS4245_DAC_CTRL_1] =
122 CS4245_DAC_FM_SINGLE | CS4245_DAC_DIF_LJUST;
123 data->cs4245_regs[CS4245_ADC_CTRL] =
124 CS4245_ADC_FM_SINGLE | CS4245_ADC_DIF_LJUST;
125 data->cs4245_regs[CS4245_SIGNAL_SEL] =
126 CS4245_A_OUT_SEL_HIZ | CS4245_ASYNCH;
127 data->cs4245_regs[CS4245_PGA_B_CTRL] = 0;
128 data->cs4245_regs[CS4245_PGA_A_CTRL] = 0;
129 data->cs4245_regs[CS4245_ANALOG_IN] =
130 CS4245_PGA_SOFT | CS4245_PGA_ZERO | CS4245_SEL_INPUT_4;
131 data->cs4245_regs[CS4245_DAC_A_CTRL] = 0;
132 data->cs4245_regs[CS4245_DAC_B_CTRL] = 0;
133 cs4245_registers_init(chip);
134 snd_component_add(chip->card, "CS4245");
135}
136
137static void dg_output_enable(struct oxygen *chip)
138{
139 msleep(2500);
140 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
141}
142
143static void dg_init(struct oxygen *chip)
144{
145 struct dg *data = chip->model_data;
146
147 data->output_sel = 0;
148 data->input_sel = 3;
149 data->hp_vol_att = 2 * 16;
150
151 cs4245_init(chip);
152
153 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
154 GPIO_MAGIC | GPIO_HP_DETECT);
155 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
156 GPIO_INPUT_ROUTE | GPIO_HP_REAR | GPIO_OUTPUT_ENABLE);
157 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
158 GPIO_INPUT_ROUTE | GPIO_HP_REAR);
159 dg_output_enable(chip);
160}
161
162static void dg_cleanup(struct oxygen *chip)
163{
164 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
165}
166
167static void dg_suspend(struct oxygen *chip)
168{
169 dg_cleanup(chip);
170}
171
172static void dg_resume(struct oxygen *chip)
173{
174 cs4245_registers_init(chip);
175 dg_output_enable(chip);
176}
177
178static void set_cs4245_dac_params(struct oxygen *chip,
179 struct snd_pcm_hw_params *params)
180{
181 struct dg *data = chip->model_data;
182 u8 value;
183
184 value = data->cs4245_regs[CS4245_DAC_CTRL_1] & ~CS4245_DAC_FM_MASK;
185 if (params_rate(params) <= 50000)
186 value |= CS4245_DAC_FM_SINGLE;
187 else if (params_rate(params) <= 100000)
188 value |= CS4245_DAC_FM_DOUBLE;
189 else
190 value |= CS4245_DAC_FM_QUAD;
191 cs4245_write_cached(chip, CS4245_DAC_CTRL_1, value);
192}
193
194static void set_cs4245_adc_params(struct oxygen *chip,
195 struct snd_pcm_hw_params *params)
196{
197 struct dg *data = chip->model_data;
198 u8 value;
199
200 value = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_ADC_FM_MASK;
201 if (params_rate(params) <= 50000)
202 value |= CS4245_ADC_FM_SINGLE;
203 else if (params_rate(params) <= 100000)
204 value |= CS4245_ADC_FM_DOUBLE;
205 else
206 value |= CS4245_ADC_FM_QUAD;
207 cs4245_write_cached(chip, CS4245_ADC_CTRL, value);
208}
209
210static int output_switch_info(struct snd_kcontrol *ctl,
211 struct snd_ctl_elem_info *info)
212{
213 static const char *const names[3] = {
214 "Speakers", "Headphones", "FP Headphones"
215 };
216
217 return snd_ctl_enum_info(info, 1, 3, names);
218}
219
220static int output_switch_get(struct snd_kcontrol *ctl,
221 struct snd_ctl_elem_value *value)
222{
223 struct oxygen *chip = ctl->private_data;
224 struct dg *data = chip->model_data;
225
226 mutex_lock(&chip->mutex);
227 value->value.enumerated.item[0] = data->output_sel;
228 mutex_unlock(&chip->mutex);
229 return 0;
230}
231
232static int output_switch_put(struct snd_kcontrol *ctl,
233 struct snd_ctl_elem_value *value)
234{
235 struct oxygen *chip = ctl->private_data;
236 struct dg *data = chip->model_data;
237 u8 reg;
238 int changed;
239
240 if (value->value.enumerated.item[0] > 2)
241 return -EINVAL;
242
243 mutex_lock(&chip->mutex);
244 changed = value->value.enumerated.item[0] != data->output_sel;
245 if (changed) {
246 data->output_sel = value->value.enumerated.item[0];
247
248 reg = data->cs4245_regs[CS4245_SIGNAL_SEL] &
249 ~CS4245_A_OUT_SEL_MASK;
250 reg |= data->output_sel == 2 ?
251 CS4245_A_OUT_SEL_DAC : CS4245_A_OUT_SEL_HIZ;
252 cs4245_write_cached(chip, CS4245_SIGNAL_SEL, reg);
253
254 cs4245_write_cached(chip, CS4245_DAC_A_CTRL,
255 data->output_sel ? data->hp_vol_att : 0);
256 cs4245_write_cached(chip, CS4245_DAC_B_CTRL,
257 data->output_sel ? data->hp_vol_att : 0);
258
259 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
260 data->output_sel == 1 ? GPIO_HP_REAR : 0,
261 GPIO_HP_REAR);
262 }
263 mutex_unlock(&chip->mutex);
264 return changed;
265}
266
267static int hp_volume_offset_info(struct snd_kcontrol *ctl,
268 struct snd_ctl_elem_info *info)
269{
270 static const char *const names[3] = {
271 "< 64 ohms", "64-150 ohms", "150-300 ohms"
272 };
273
274 return snd_ctl_enum_info(info, 1, 3, names);
275}
276
277static int hp_volume_offset_get(struct snd_kcontrol *ctl,
278 struct snd_ctl_elem_value *value)
279{
280 struct oxygen *chip = ctl->private_data;
281 struct dg *data = chip->model_data;
282
283 mutex_lock(&chip->mutex);
284 if (data->hp_vol_att > 2 * 7)
285 value->value.enumerated.item[0] = 0;
286 else if (data->hp_vol_att > 0)
287 value->value.enumerated.item[0] = 1;
288 else
289 value->value.enumerated.item[0] = 2;
290 mutex_unlock(&chip->mutex);
291 return 0;
292}
293
294static int hp_volume_offset_put(struct snd_kcontrol *ctl,
295 struct snd_ctl_elem_value *value)
296{
297 static const s8 atts[3] = { 2 * 16, 2 * 7, 0 };
298 struct oxygen *chip = ctl->private_data;
299 struct dg *data = chip->model_data;
300 s8 att;
301 int changed;
302
303 if (value->value.enumerated.item[0] > 2)
304 return -EINVAL;
305 att = atts[value->value.enumerated.item[0]];
306 mutex_lock(&chip->mutex);
307 changed = att != data->hp_vol_att;
308 if (changed) {
309 data->hp_vol_att = att;
310 if (data->output_sel) {
311 cs4245_write_cached(chip, CS4245_DAC_A_CTRL, att);
312 cs4245_write_cached(chip, CS4245_DAC_B_CTRL, att);
313 }
314 }
315 mutex_unlock(&chip->mutex);
316 return changed;
317}
318
319static int input_vol_info(struct snd_kcontrol *ctl,
320 struct snd_ctl_elem_info *info)
321{
322 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
323 info->count = 2;
324 info->value.integer.min = 2 * -12;
325 info->value.integer.max = 2 * 12;
326 return 0;
327}
328
329static int input_vol_get(struct snd_kcontrol *ctl,
330 struct snd_ctl_elem_value *value)
331{
332 struct oxygen *chip = ctl->private_data;
333 struct dg *data = chip->model_data;
334 unsigned int idx = ctl->private_value;
335
336 mutex_lock(&chip->mutex);
337 value->value.integer.value[0] = data->input_vol[idx][0];
338 value->value.integer.value[1] = data->input_vol[idx][1];
339 mutex_unlock(&chip->mutex);
340 return 0;
341}
342
343static int input_vol_put(struct snd_kcontrol *ctl,
344 struct snd_ctl_elem_value *value)
345{
346 struct oxygen *chip = ctl->private_data;
347 struct dg *data = chip->model_data;
348 unsigned int idx = ctl->private_value;
349 int changed = 0;
350
351 if (value->value.integer.value[0] < 2 * -12 ||
352 value->value.integer.value[0] > 2 * 12 ||
353 value->value.integer.value[1] < 2 * -12 ||
354 value->value.integer.value[1] > 2 * 12)
355 return -EINVAL;
356 mutex_lock(&chip->mutex);
357 changed = data->input_vol[idx][0] != value->value.integer.value[0] ||
358 data->input_vol[idx][1] != value->value.integer.value[1];
359 if (changed) {
360 data->input_vol[idx][0] = value->value.integer.value[0];
361 data->input_vol[idx][1] = value->value.integer.value[1];
362 if (idx == data->input_sel) {
363 cs4245_write_cached(chip, CS4245_PGA_A_CTRL,
364 data->input_vol[idx][0]);
365 cs4245_write_cached(chip, CS4245_PGA_B_CTRL,
366 data->input_vol[idx][1]);
367 }
368 }
369 mutex_unlock(&chip->mutex);
370 return changed;
371}
372
373static DECLARE_TLV_DB_SCALE(cs4245_pga_db_scale, -1200, 50, 0);
374
375static int input_sel_info(struct snd_kcontrol *ctl,
376 struct snd_ctl_elem_info *info)
377{
378 static const char *const names[4] = {
379 "Mic", "Aux", "Front Mic", "Line"
380 };
381
382 return snd_ctl_enum_info(info, 1, 4, names);
383}
384
385static int input_sel_get(struct snd_kcontrol *ctl,
386 struct snd_ctl_elem_value *value)
387{
388 struct oxygen *chip = ctl->private_data;
389 struct dg *data = chip->model_data;
390
391 mutex_lock(&chip->mutex);
392 value->value.enumerated.item[0] = data->input_sel;
393 mutex_unlock(&chip->mutex);
394 return 0;
395}
396
397static int input_sel_put(struct snd_kcontrol *ctl,
398 struct snd_ctl_elem_value *value)
399{
400 static const u8 sel_values[4] = {
401 CS4245_SEL_MIC,
402 CS4245_SEL_INPUT_1,
403 CS4245_SEL_INPUT_2,
404 CS4245_SEL_INPUT_4
405 };
406 struct oxygen *chip = ctl->private_data;
407 struct dg *data = chip->model_data;
408 int changed;
409
410 if (value->value.enumerated.item[0] > 3)
411 return -EINVAL;
412
413 mutex_lock(&chip->mutex);
414 changed = value->value.enumerated.item[0] != data->input_sel;
415 if (changed) {
416 data->input_sel = value->value.enumerated.item[0];
417
418 cs4245_write(chip, CS4245_ANALOG_IN,
419 (data->cs4245_regs[CS4245_ANALOG_IN] &
420 ~CS4245_SEL_MASK) |
421 sel_values[data->input_sel]);
422
423 cs4245_write_cached(chip, CS4245_PGA_A_CTRL,
424 data->input_vol[data->input_sel][0]);
425 cs4245_write_cached(chip, CS4245_PGA_B_CTRL,
426 data->input_vol[data->input_sel][1]);
427
428 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
429 data->input_sel ? 0 : GPIO_INPUT_ROUTE,
430 GPIO_INPUT_ROUTE);
431 }
432 mutex_unlock(&chip->mutex);
433 return changed;
434}
435
436static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
437{
438 static const char *const names[2] = { "Active", "Frozen" };
439
440 return snd_ctl_enum_info(info, 1, 2, names);
441}
442
443static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
444{
445 struct oxygen *chip = ctl->private_data;
446 struct dg *data = chip->model_data;
447
448 value->value.enumerated.item[0] =
449 !!(data->cs4245_regs[CS4245_ADC_CTRL] & CS4245_HPF_FREEZE);
450 return 0;
451}
452
453static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
454{
455 struct oxygen *chip = ctl->private_data;
456 struct dg *data = chip->model_data;
457 u8 reg;
458 int changed;
459
460 mutex_lock(&chip->mutex);
461 reg = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_HPF_FREEZE;
462 if (value->value.enumerated.item[0])
463 reg |= CS4245_HPF_FREEZE;
464 changed = reg != data->cs4245_regs[CS4245_ADC_CTRL];
465 if (changed)
466 cs4245_write(chip, CS4245_ADC_CTRL, reg);
467 mutex_unlock(&chip->mutex);
468 return changed;
469}
470
471#define INPUT_VOLUME(xname, index) { \
472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
473 .name = xname, \
474 .info = input_vol_info, \
475 .get = input_vol_get, \
476 .put = input_vol_put, \
477 .tlv = { .p = cs4245_pga_db_scale }, \
478 .private_value = index, \
479}
480static const struct snd_kcontrol_new dg_controls[] = {
481 {
482 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
483 .name = "Analog Output Playback Enum",
484 .info = output_switch_info,
485 .get = output_switch_get,
486 .put = output_switch_put,
487 },
488 {
489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
490 .name = "Headphones Impedance Playback Enum",
491 .info = hp_volume_offset_info,
492 .get = hp_volume_offset_get,
493 .put = hp_volume_offset_put,
494 },
495 INPUT_VOLUME("Mic Capture Volume", 0),
496 INPUT_VOLUME("Aux Capture Volume", 1),
497 INPUT_VOLUME("Front Mic Capture Volume", 2),
498 INPUT_VOLUME("Line Capture Volume", 3),
499 {
500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
501 .name = "Capture Source",
502 .info = input_sel_info,
503 .get = input_sel_get,
504 .put = input_sel_put,
505 },
506 {
507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
508 .name = "ADC High-pass Filter Capture Enum",
509 .info = hpf_info,
510 .get = hpf_get,
511 .put = hpf_put,
512 },
513};
514
515static int dg_control_filter(struct snd_kcontrol_new *template)
516{
517 if (!strncmp(template->name, "Master Playback ", 16))
518 return 1;
519 return 0;
520}
521
522static int dg_mixer_init(struct oxygen *chip)
523{
524 unsigned int i;
525 int err;
526
527 for (i = 0; i < ARRAY_SIZE(dg_controls); ++i) {
528 err = snd_ctl_add(chip->card,
529 snd_ctl_new1(&dg_controls[i], chip));
530 if (err < 0)
531 return err;
532 }
533 return 0;
534}
535
536static void dump_cs4245_registers(struct oxygen *chip,
537 struct snd_info_buffer *buffer)
538{
539 struct dg *data = chip->model_data;
540 unsigned int i;
541
542 snd_iprintf(buffer, "\nCS4245:");
543 for (i = 1; i <= 0x10; ++i)
544 snd_iprintf(buffer, " %02x", data->cs4245_regs[i]);
545 snd_iprintf(buffer, "\n");
546}
547
548struct oxygen_model model_xonar_dg = {
549 .shortname = "Xonar DG",
550 .longname = "C-Media Oxygen HD Audio",
551 .chip = "CMI8786",
552 .init = dg_init,
553 .control_filter = dg_control_filter,
554 .mixer_init = dg_mixer_init,
555 .cleanup = dg_cleanup,
556 .suspend = dg_suspend,
557 .resume = dg_resume,
558 .set_dac_params = set_cs4245_dac_params,
559 .set_adc_params = set_cs4245_adc_params,
560 .dump_registers = dump_cs4245_registers,
561 .model_data_size = sizeof(struct dg),
562 .device_config = PLAYBACK_0_TO_I2S |
563 PLAYBACK_1_TO_SPDIF |
564 CAPTURE_0_FROM_I2S_2,
565 .dac_channels_pcm = 6,
566 .dac_channels_mixer = 0,
567 .function_flags = OXYGEN_FUNCTION_SPI,
568 .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
569 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
570 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
571 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
572};
diff --git a/sound/pci/oxygen/xonar_dg.h b/sound/pci/oxygen/xonar_dg.h
new file mode 100644
index 000000000000..5688d78609a9
--- /dev/null
+++ b/sound/pci/oxygen/xonar_dg.h
@@ -0,0 +1,8 @@
1#ifndef XONAR_DG_H_INCLUDED
2#define XONAR_DG_H_INCLUDED
3
4#include "oxygen.h"
5
6extern struct oxygen_model model_xonar_dg;
7
8#endif
diff --git a/sound/pci/oxygen/xonar_hdmi.c b/sound/pci/oxygen/xonar_hdmi.c
index b12db1f1cea9..136dac6a3964 100644
--- a/sound/pci/oxygen/xonar_hdmi.c
+++ b/sound/pci/oxygen/xonar_hdmi.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * helper functions for HDMI models (Xonar HDAV1.3) 2 * helper functions for HDMI models (Xonar HDAV1.3/HDAV1.3 Slim)
3 * 3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * 5 *
diff --git a/sound/pci/oxygen/xonar_lib.c b/sound/pci/oxygen/xonar_lib.c
index b3ff71316653..0ebe7f5916f9 100644
--- a/sound/pci/oxygen/xonar_lib.c
+++ b/sound/pci/oxygen/xonar_lib.c
@@ -104,9 +104,10 @@ int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
104{ 104{
105 struct oxygen *chip = ctl->private_data; 105 struct oxygen *chip = ctl->private_data;
106 u16 bit = ctl->private_value; 106 u16 bit = ctl->private_value;
107 bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
107 108
108 value->value.integer.value[0] = 109 value->value.integer.value[0] =
109 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit); 110 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit) ^ invert;
110 return 0; 111 return 0;
111} 112}
112 113
@@ -115,12 +116,13 @@ int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
115{ 116{
116 struct oxygen *chip = ctl->private_data; 117 struct oxygen *chip = ctl->private_data;
117 u16 bit = ctl->private_value; 118 u16 bit = ctl->private_value;
119 bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
118 u16 old_bits, new_bits; 120 u16 old_bits, new_bits;
119 int changed; 121 int changed;
120 122
121 spin_lock_irq(&chip->reg_lock); 123 spin_lock_irq(&chip->reg_lock);
122 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 124 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
123 if (value->value.integer.value[0]) 125 if (!!value->value.integer.value[0] ^ invert)
124 new_bits = old_bits | bit; 126 new_bits = old_bits | bit;
125 else 127 else
126 new_bits = old_bits & ~bit; 128 new_bits = old_bits & ~bit;
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index d491fd6c0be2..54cad38ec30a 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -22,20 +22,26 @@
22 * 22 *
23 * CMI8788: 23 * CMI8788:
24 * 24 *
25 * SPI 0 -> 1st PCM1796 (front) 25 * SPI 0 -> 1st PCM1796 (front)
26 * SPI 1 -> 2nd PCM1796 (surround) 26 * SPI 1 -> 2nd PCM1796 (surround)
27 * SPI 2 -> 3rd PCM1796 (center/LFE) 27 * SPI 2 -> 3rd PCM1796 (center/LFE)
28 * SPI 4 -> 4th PCM1796 (back) 28 * SPI 4 -> 4th PCM1796 (back)
29 * 29 *
30 * GPIO 2 -> M0 of CS5381 30 * GPIO 2 -> M0 of CS5381
31 * GPIO 3 -> M1 of CS5381 31 * GPIO 3 -> M1 of CS5381
32 * GPIO 5 <- external power present (D2X only) 32 * GPIO 5 <- external power present (D2X only)
33 * GPIO 7 -> ALT 33 * GPIO 7 -> ALT
34 * GPIO 8 -> enable output to speakers 34 * GPIO 8 -> enable output to speakers
35 * 35 *
36 * CM9780: 36 * CM9780:
37 * 37 *
38 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input 38 * LINE_OUT -> input of ADC
39 *
40 * AUX_IN <- aux
41 * VIDEO_IN <- CD
42 * FMIC_IN <- mic
43 *
44 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
39 */ 45 */
40 46
41/* 47/*
@@ -44,52 +50,53 @@
44 * 50 *
45 * CMI8788: 51 * CMI8788:
46 * 52 *
47 * I²C <-> PCM1796 (front) 53 * I²C <-> PCM1796 (addr 1001100) (front)
48 * 54 *
49 * GPI 0 <- external power present 55 * GPI 0 <- external power present
50 * 56 *
51 * GPIO 0 -> enable output to speakers 57 * GPIO 0 -> enable HDMI (0) or speaker (1) output
52 * GPIO 2 -> M0 of CS5381 58 * GPIO 2 -> M0 of CS5381
53 * GPIO 3 -> M1 of CS5381 59 * GPIO 3 -> M1 of CS5381
54 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) 60 * GPIO 4 <- daughterboard detection
61 * GPIO 5 <- daughterboard detection
62 * GPIO 6 -> ?
63 * GPIO 7 -> ?
64 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
55 * 65 *
56 * TXD -> HDMI controller 66 * UART <-> HDMI controller
57 * RXD <- HDMI controller
58 *
59 * PCM1796 front: AD1,0 <- 0,0
60 * 67 *
61 * CM9780: 68 * CM9780:
62 * 69 *
63 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input 70 * LINE_OUT -> input of ADC
71 *
72 * AUX_IN <- aux
73 * CD_IN <- CD
74 * MIC_IN <- mic
75 *
76 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
64 * 77 *
65 * no daughterboard 78 * no daughterboard
66 * ---------------- 79 * ----------------
67 * 80 *
68 * GPIO 4 <- 1 81 * GPIO 4 <- 1
69 * 82 *
70 * H6 daughterboard 83 * H6 daughterboard
71 * ---------------- 84 * ----------------
72 * 85 *
73 * GPIO 4 <- 0 86 * GPIO 4 <- 0
74 * GPIO 5 <- 0 87 * GPIO 5 <- 0
75 *
76 * I²C <-> PCM1796 (surround)
77 * <-> PCM1796 (center/LFE)
78 * <-> PCM1796 (back)
79 * 88 *
80 * PCM1796 surround: AD1,0 <- 0,1 89 * I²C <-> PCM1796 (addr 1001101) (surround)
81 * PCM1796 center/LFE: AD1,0 <- 1,0 90 * <-> PCM1796 (addr 1001110) (center/LFE)
82 * PCM1796 back: AD1,0 <- 1,1 91 * <-> PCM1796 (addr 1001111) (back)
83 * 92 *
84 * unknown daughterboard 93 * unknown daughterboard
85 * --------------------- 94 * ---------------------
86 * 95 *
87 * GPIO 4 <- 0 96 * GPIO 4 <- 0
88 * GPIO 5 <- 1 97 * GPIO 5 <- 1
89 *
90 * I²C <-> CS4362A (surround, center/LFE, back)
91 * 98 *
92 * CS4362A: AD0 <- 0 99 * I²C <-> CS4362A (addr 0011000) (surround, center/LFE, back)
93 */ 100 */
94 101
95/* 102/*
@@ -98,32 +105,35 @@
98 * 105 *
99 * CMI8788: 106 * CMI8788:
100 * 107 *
101 * I²C <-> PCM1792A 108 * I²C <-> PCM1792A (addr 1001100)
102 * <-> CS2000 (ST only) 109 * <-> CS2000 (addr 1001110) (ST only)
103 * 110 *
104 * ADC1 MCLK -> REF_CLK of CS2000 (ST only) 111 * ADC1 MCLK -> REF_CLK of CS2000 (ST only)
105 * 112 *
106 * GPI 0 <- external power present (STX only) 113 * GPI 0 <- external power present (STX only)
107 * 114 *
108 * GPIO 0 -> enable output to speakers 115 * GPIO 0 -> enable output to speakers
109 * GPIO 1 -> route HP to front panel (0) or rear jack (1) 116 * GPIO 1 -> route HP to front panel (0) or rear jack (1)
110 * GPIO 2 -> M0 of CS5381 117 * GPIO 2 -> M0 of CS5381
111 * GPIO 3 -> M1 of CS5381 118 * GPIO 3 -> M1 of CS5381
112 * GPIO 7 -> route output to speaker jacks (0) or HP (1) 119 * GPIO 4 <- daughterboard detection
113 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) 120 * GPIO 5 <- daughterboard detection
121 * GPIO 6 -> ?
122 * GPIO 7 -> route output to speaker jacks (0) or HP (1)
123 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
114 * 124 *
115 * PCM1792A: 125 * PCM1792A:
116 * 126 *
117 * AD1,0 <- 0,0 127 * SCK <- CLK_OUT of CS2000 (ST only)
118 * SCK <- CLK_OUT of CS2000 (ST only)
119 * 128 *
120 * CS2000: 129 * CM9780:
121 * 130 *
122 * AD0 <- 0 131 * LINE_OUT -> input of ADC
123 * 132 *
124 * CM9780: 133 * AUX_IN <- aux
134 * MIC_IN <- mic
125 * 135 *
126 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input 136 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
127 * 137 *
128 * H6 daughterboard 138 * H6 daughterboard
129 * ---------------- 139 * ----------------
@@ -133,15 +143,39 @@
133 */ 143 */
134 144
135/* 145/*
136 * Xonar HDAV1.3 Slim 146 * Xonar Xense
137 * ------------------ 147 * -----------
138 * 148 *
139 * CMI8788: 149 * CMI8788:
140 * 150 *
141 * GPIO 1 -> enable output 151 * I²C <-> PCM1796 (addr 1001100) (front)
152 * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
153 * <-> CS2000 (addr 1001110)
154 *
155 * ADC1 MCLK -> REF_CLK of CS2000
156 *
157 * GPI 0 <- external power present
158 *
159 * GPIO 0 -> enable output
160 * GPIO 1 -> route HP to front panel (0) or rear jack (1)
161 * GPIO 2 -> M0 of CS5381
162 * GPIO 3 -> M1 of CS5381
163 * GPIO 4 -> enable output
164 * GPIO 5 -> enable output
165 * GPIO 6 -> ?
166 * GPIO 7 -> route output to HP (0) or speaker (1)
167 * GPIO 8 -> route input jack to mic-in (0) or line-in (1)
142 * 168 *
143 * TXD -> HDMI controller 169 * CM9780:
144 * RXD <- HDMI controller 170 *
171 * LINE_OUT -> input of ADC
172 *
173 * AUX_IN <- aux
174 * VIDEO_IN <- ?
175 * FMIC_IN <- mic
176 *
177 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
178 * GPO 1 -> route mic-in from input jack (0) or front panel header (1)
145 */ 179 */
146 180
147#include <linux/pci.h> 181#include <linux/pci.h>
@@ -150,6 +184,7 @@
150#include <sound/ac97_codec.h> 184#include <sound/ac97_codec.h>
151#include <sound/control.h> 185#include <sound/control.h>
152#include <sound/core.h> 186#include <sound/core.h>
187#include <sound/info.h>
153#include <sound/pcm.h> 188#include <sound/pcm.h>
154#include <sound/pcm_params.h> 189#include <sound/pcm_params.h>
155#include <sound/tlv.h> 190#include <sound/tlv.h>
@@ -167,12 +202,14 @@
167#define GPIO_INPUT_ROUTE 0x0100 202#define GPIO_INPUT_ROUTE 0x0100
168 203
169#define GPIO_HDAV_OUTPUT_ENABLE 0x0001 204#define GPIO_HDAV_OUTPUT_ENABLE 0x0001
205#define GPIO_HDAV_MAGIC 0x00c0
170 206
171#define GPIO_DB_MASK 0x0030 207#define GPIO_DB_MASK 0x0030
172#define GPIO_DB_H6 0x0000 208#define GPIO_DB_H6 0x0000
173 209
174#define GPIO_ST_OUTPUT_ENABLE 0x0001 210#define GPIO_ST_OUTPUT_ENABLE 0x0001
175#define GPIO_ST_HP_REAR 0x0002 211#define GPIO_ST_HP_REAR 0x0002
212#define GPIO_ST_MAGIC 0x0040
176#define GPIO_ST_HP 0x0080 213#define GPIO_ST_HP 0x0080
177 214
178#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */ 215#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */
@@ -186,11 +223,12 @@ struct xonar_pcm179x {
186 unsigned int dacs; 223 unsigned int dacs;
187 u8 pcm1796_regs[4][5]; 224 u8 pcm1796_regs[4][5];
188 unsigned int current_rate; 225 unsigned int current_rate;
189 bool os_128; 226 bool h6;
190 bool hp_active; 227 bool hp_active;
191 s8 hp_gain_offset; 228 s8 hp_gain_offset;
192 bool has_cs2000; 229 bool has_cs2000;
193 u8 cs2000_fun_cfg_1; 230 u8 cs2000_regs[0x1f];
231 bool broken_i2c;
194}; 232};
195 233
196struct xonar_hdav { 234struct xonar_hdav {
@@ -249,16 +287,14 @@ static void cs2000_write(struct oxygen *chip, u8 reg, u8 value)
249 struct xonar_pcm179x *data = chip->model_data; 287 struct xonar_pcm179x *data = chip->model_data;
250 288
251 oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value); 289 oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value);
252 if (reg == CS2000_FUN_CFG_1) 290 data->cs2000_regs[reg] = value;
253 data->cs2000_fun_cfg_1 = value;
254} 291}
255 292
256static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value) 293static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value)
257{ 294{
258 struct xonar_pcm179x *data = chip->model_data; 295 struct xonar_pcm179x *data = chip->model_data;
259 296
260 if (reg != CS2000_FUN_CFG_1 || 297 if (value != data->cs2000_regs[reg])
261 value != data->cs2000_fun_cfg_1)
262 cs2000_write(chip, reg, value); 298 cs2000_write(chip, reg, value);
263} 299}
264 300
@@ -268,6 +304,7 @@ static void pcm1796_registers_init(struct oxygen *chip)
268 unsigned int i; 304 unsigned int i;
269 s8 gain_offset; 305 s8 gain_offset;
270 306
307 msleep(1);
271 gain_offset = data->hp_active ? data->hp_gain_offset : 0; 308 gain_offset = data->hp_active ? data->hp_gain_offset : 0;
272 for (i = 0; i < data->dacs; ++i) { 309 for (i = 0; i < data->dacs; ++i) {
273 /* set ATLD before ATL/ATR */ 310 /* set ATLD before ATL/ATR */
@@ -282,6 +319,7 @@ static void pcm1796_registers_init(struct oxygen *chip)
282 pcm1796_write(chip, i, 20, 319 pcm1796_write(chip, i, 20,
283 data->pcm1796_regs[0][20 - PCM1796_REG_BASE]); 320 data->pcm1796_regs[0][20 - PCM1796_REG_BASE]);
284 pcm1796_write(chip, i, 21, 0); 321 pcm1796_write(chip, i, 21, 0);
322 gain_offset = 0;
285 } 323 }
286} 324}
287 325
@@ -290,10 +328,11 @@ static void pcm1796_init(struct oxygen *chip)
290 struct xonar_pcm179x *data = chip->model_data; 328 struct xonar_pcm179x *data = chip->model_data;
291 329
292 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE | 330 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE |
293 PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; 331 PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
294 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = 332 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
295 PCM1796_FLT_SHARP | PCM1796_ATS_1; 333 PCM1796_FLT_SHARP | PCM1796_ATS_1;
296 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = PCM1796_OS_64; 334 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] =
335 data->h6 ? PCM1796_OS_64 : PCM1796_OS_128;
297 pcm1796_registers_init(chip); 336 pcm1796_registers_init(chip);
298 data->current_rate = 48000; 337 data->current_rate = 48000;
299} 338}
@@ -339,18 +378,20 @@ static void xonar_hdav_init(struct oxygen *chip)
339 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 378 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
340 OXYGEN_2WIRE_LENGTH_8 | 379 OXYGEN_2WIRE_LENGTH_8 |
341 OXYGEN_2WIRE_INTERRUPT_MASK | 380 OXYGEN_2WIRE_INTERRUPT_MASK |
342 OXYGEN_2WIRE_SPEED_FAST); 381 OXYGEN_2WIRE_SPEED_STANDARD);
343 382
344 data->pcm179x.generic.anti_pop_delay = 100; 383 data->pcm179x.generic.anti_pop_delay = 100;
345 data->pcm179x.generic.output_enable_bit = GPIO_HDAV_OUTPUT_ENABLE; 384 data->pcm179x.generic.output_enable_bit = GPIO_HDAV_OUTPUT_ENABLE;
346 data->pcm179x.generic.ext_power_reg = OXYGEN_GPI_DATA; 385 data->pcm179x.generic.ext_power_reg = OXYGEN_GPI_DATA;
347 data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 386 data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
348 data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER; 387 data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER;
349 data->pcm179x.dacs = chip->model.private_data ? 4 : 1; 388 data->pcm179x.dacs = chip->model.dac_channels_mixer / 2;
389 data->pcm179x.h6 = chip->model.dac_channels_mixer > 2;
350 390
351 pcm1796_init(chip); 391 pcm1796_init(chip);
352 392
353 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_INPUT_ROUTE); 393 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
394 GPIO_HDAV_MAGIC | GPIO_INPUT_ROUTE);
354 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE); 395 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE);
355 396
356 xonar_init_cs53x1(chip); 397 xonar_init_cs53x1(chip);
@@ -367,7 +408,7 @@ static void xonar_st_init_i2c(struct oxygen *chip)
367 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 408 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
368 OXYGEN_2WIRE_LENGTH_8 | 409 OXYGEN_2WIRE_LENGTH_8 |
369 OXYGEN_2WIRE_INTERRUPT_MASK | 410 OXYGEN_2WIRE_INTERRUPT_MASK |
370 OXYGEN_2WIRE_SPEED_FAST); 411 OXYGEN_2WIRE_SPEED_STANDARD);
371} 412}
372 413
373static void xonar_st_init_common(struct oxygen *chip) 414static void xonar_st_init_common(struct oxygen *chip)
@@ -375,13 +416,14 @@ static void xonar_st_init_common(struct oxygen *chip)
375 struct xonar_pcm179x *data = chip->model_data; 416 struct xonar_pcm179x *data = chip->model_data;
376 417
377 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE; 418 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE;
378 data->dacs = chip->model.private_data ? 4 : 1; 419 data->dacs = chip->model.dac_channels_mixer / 2;
379 data->hp_gain_offset = 2*-18; 420 data->hp_gain_offset = 2*-18;
380 421
381 pcm1796_init(chip); 422 pcm1796_init(chip);
382 423
383 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 424 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
384 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); 425 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
426 GPIO_ST_MAGIC | GPIO_ST_HP);
385 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 427 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
386 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); 428 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
387 429
@@ -410,9 +452,11 @@ static void cs2000_registers_init(struct oxygen *chip)
410 cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10); 452 cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10);
411 cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00); 453 cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00);
412 cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00); 454 cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00);
413 cs2000_write(chip, CS2000_FUN_CFG_1, data->cs2000_fun_cfg_1); 455 cs2000_write(chip, CS2000_FUN_CFG_1,
456 data->cs2000_regs[CS2000_FUN_CFG_1]);
414 cs2000_write(chip, CS2000_FUN_CFG_2, 0); 457 cs2000_write(chip, CS2000_FUN_CFG_2, 0);
415 cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2); 458 cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2);
459 msleep(3); /* PLL lock delay */
416} 460}
417 461
418static void xonar_st_init(struct oxygen *chip) 462static void xonar_st_init(struct oxygen *chip)
@@ -420,13 +464,18 @@ static void xonar_st_init(struct oxygen *chip)
420 struct xonar_pcm179x *data = chip->model_data; 464 struct xonar_pcm179x *data = chip->model_data;
421 465
422 data->generic.anti_pop_delay = 100; 466 data->generic.anti_pop_delay = 100;
467 data->h6 = chip->model.dac_channels_mixer > 2;
423 data->has_cs2000 = 1; 468 data->has_cs2000 = 1;
424 data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1; 469 data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1;
470 data->broken_i2c = true;
425 471
426 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 472 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
427 OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | 473 OXYGEN_RATE_48000 |
428 OXYGEN_I2S_MCLK_128 | OXYGEN_I2S_BITS_16 | 474 OXYGEN_I2S_FORMAT_I2S |
429 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 475 OXYGEN_I2S_MCLK(data->h6 ? MCLK_256 : MCLK_512) |
476 OXYGEN_I2S_BITS_16 |
477 OXYGEN_I2S_MASTER |
478 OXYGEN_I2S_BCLK_64);
430 479
431 xonar_st_init_i2c(chip); 480 xonar_st_init_i2c(chip);
432 cs2000_registers_init(chip); 481 cs2000_registers_init(chip);
@@ -507,44 +556,16 @@ static void xonar_st_resume(struct oxygen *chip)
507 xonar_stx_resume(chip); 556 xonar_stx_resume(chip);
508} 557}
509 558
510static unsigned int mclk_from_rate(struct oxygen *chip, unsigned int rate)
511{
512 struct xonar_pcm179x *data = chip->model_data;
513
514 if (rate <= 32000)
515 return OXYGEN_I2S_MCLK_512;
516 else if (rate <= 48000 && data->os_128)
517 return OXYGEN_I2S_MCLK_512;
518 else if (rate <= 96000)
519 return OXYGEN_I2S_MCLK_256;
520 else
521 return OXYGEN_I2S_MCLK_128;
522}
523
524static unsigned int get_pcm1796_i2s_mclk(struct oxygen *chip,
525 unsigned int channel,
526 struct snd_pcm_hw_params *params)
527{
528 if (channel == PCM_MULTICH)
529 return mclk_from_rate(chip, params_rate(params));
530 else
531 return oxygen_default_i2s_mclk(chip, channel, params);
532}
533
534static void update_pcm1796_oversampling(struct oxygen *chip) 559static void update_pcm1796_oversampling(struct oxygen *chip)
535{ 560{
536 struct xonar_pcm179x *data = chip->model_data; 561 struct xonar_pcm179x *data = chip->model_data;
537 unsigned int i; 562 unsigned int i;
538 u8 reg; 563 u8 reg;
539 564
540 if (data->current_rate <= 32000) 565 if (data->current_rate <= 48000 && !data->h6)
541 reg = PCM1796_OS_128; 566 reg = PCM1796_OS_128;
542 else if (data->current_rate <= 48000 && data->os_128)
543 reg = PCM1796_OS_128;
544 else if (data->current_rate <= 96000 || data->os_128)
545 reg = PCM1796_OS_64;
546 else 567 else
547 reg = PCM1796_OS_32; 568 reg = PCM1796_OS_64;
548 for (i = 0; i < data->dacs; ++i) 569 for (i = 0; i < data->dacs; ++i)
549 pcm1796_write_cached(chip, i, 20, reg); 570 pcm1796_write_cached(chip, i, 20, reg);
550} 571}
@@ -554,6 +575,7 @@ static void set_pcm1796_params(struct oxygen *chip,
554{ 575{
555 struct xonar_pcm179x *data = chip->model_data; 576 struct xonar_pcm179x *data = chip->model_data;
556 577
578 msleep(1);
557 data->current_rate = params_rate(params); 579 data->current_rate = params_rate(params);
558 update_pcm1796_oversampling(chip); 580 update_pcm1796_oversampling(chip);
559} 581}
@@ -570,6 +592,7 @@ static void update_pcm1796_volume(struct oxygen *chip)
570 + gain_offset); 592 + gain_offset);
571 pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1] 593 pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1]
572 + gain_offset); 594 + gain_offset);
595 gain_offset = 0;
573 } 596 }
574} 597}
575 598
@@ -579,7 +602,7 @@ static void update_pcm1796_mute(struct oxygen *chip)
579 unsigned int i; 602 unsigned int i;
580 u8 value; 603 u8 value;
581 604
582 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; 605 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
583 if (chip->dac_mute) 606 if (chip->dac_mute)
584 value |= PCM1796_MUTE; 607 value |= PCM1796_MUTE;
585 for (i = 0; i < data->dacs; ++i) 608 for (i = 0; i < data->dacs; ++i)
@@ -592,45 +615,35 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate)
592 u8 rate_mclk, reg; 615 u8 rate_mclk, reg;
593 616
594 switch (rate) { 617 switch (rate) {
595 /* XXX Why is the I2S A MCLK half the actual I2S MCLK? */
596 case 32000: 618 case 32000:
597 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256;
598 break;
599 case 44100:
600 if (data->os_128)
601 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
602 else
603 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_128;
604 break;
605 default: /* 48000 */
606 if (data->os_128)
607 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
608 else
609 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_128;
610 break;
611 case 64000: 619 case 64000:
612 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; 620 rate_mclk = OXYGEN_RATE_32000;
613 break; 621 break;
622 case 44100:
614 case 88200: 623 case 88200:
615 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
616 break;
617 case 96000:
618 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
619 break;
620 case 176400: 624 case 176400:
621 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; 625 rate_mclk = OXYGEN_RATE_44100;
622 break; 626 break;
627 default:
628 case 48000:
629 case 96000:
623 case 192000: 630 case 192000:
624 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; 631 rate_mclk = OXYGEN_RATE_48000;
625 break; 632 break;
626 } 633 }
627 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk, 634
628 OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK); 635 if (rate <= 96000 && (rate > 48000 || data->h6)) {
629 if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_128) 636 rate_mclk |= OXYGEN_I2S_MCLK(MCLK_256);
630 reg = CS2000_REF_CLK_DIV_1; 637 reg = CS2000_REF_CLK_DIV_1;
631 else 638 } else {
639 rate_mclk |= OXYGEN_I2S_MCLK(MCLK_512);
632 reg = CS2000_REF_CLK_DIV_2; 640 reg = CS2000_REF_CLK_DIV_2;
641 }
642
643 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk,
644 OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK);
633 cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg); 645 cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg);
646 msleep(3); /* PLL lock delay */
634} 647}
635 648
636static void set_st_params(struct oxygen *chip, 649static void set_st_params(struct oxygen *chip,
@@ -665,13 +678,7 @@ static int rolloff_info(struct snd_kcontrol *ctl,
665 "Sharp Roll-off", "Slow Roll-off" 678 "Sharp Roll-off", "Slow Roll-off"
666 }; 679 };
667 680
668 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 681 return snd_ctl_enum_info(info, 1, 2, names);
669 info->count = 1;
670 info->value.enumerated.items = 2;
671 if (info->value.enumerated.item >= 2)
672 info->value.enumerated.item = 1;
673 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
674 return 0;
675} 682}
676 683
677static int rolloff_get(struct snd_kcontrol *ctl, 684static int rolloff_get(struct snd_kcontrol *ctl,
@@ -719,57 +726,13 @@ static const struct snd_kcontrol_new rolloff_control = {
719 .put = rolloff_put, 726 .put = rolloff_put,
720}; 727};
721 728
722static int os_128_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 729static const struct snd_kcontrol_new hdav_hdmi_control = {
723{
724 static const char *const names[2] = { "64x", "128x" };
725
726 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
727 info->count = 1;
728 info->value.enumerated.items = 2;
729 if (info->value.enumerated.item >= 2)
730 info->value.enumerated.item = 1;
731 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
732 return 0;
733}
734
735static int os_128_get(struct snd_kcontrol *ctl,
736 struct snd_ctl_elem_value *value)
737{
738 struct oxygen *chip = ctl->private_data;
739 struct xonar_pcm179x *data = chip->model_data;
740
741 value->value.enumerated.item[0] = data->os_128;
742 return 0;
743}
744
745static int os_128_put(struct snd_kcontrol *ctl,
746 struct snd_ctl_elem_value *value)
747{
748 struct oxygen *chip = ctl->private_data;
749 struct xonar_pcm179x *data = chip->model_data;
750 int changed;
751
752 mutex_lock(&chip->mutex);
753 changed = value->value.enumerated.item[0] != data->os_128;
754 if (changed) {
755 data->os_128 = value->value.enumerated.item[0];
756 if (data->has_cs2000)
757 update_cs2000_rate(chip, data->current_rate);
758 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
759 mclk_from_rate(chip, data->current_rate),
760 OXYGEN_I2S_MCLK_MASK);
761 update_pcm1796_oversampling(chip);
762 }
763 mutex_unlock(&chip->mutex);
764 return changed;
765}
766
767static const struct snd_kcontrol_new os_128_control = {
768 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 730 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
769 .name = "DAC Oversampling Playback Enum", 731 .name = "HDMI Playback Switch",
770 .info = os_128_info, 732 .info = snd_ctl_boolean_mono_info,
771 .get = os_128_get, 733 .get = xonar_gpio_bit_switch_get,
772 .put = os_128_put, 734 .put = xonar_gpio_bit_switch_put,
735 .private_value = GPIO_HDAV_OUTPUT_ENABLE | XONAR_GPIO_BIT_INVERT,
773}; 736};
774 737
775static int st_output_switch_info(struct snd_kcontrol *ctl, 738static int st_output_switch_info(struct snd_kcontrol *ctl,
@@ -779,13 +742,7 @@ static int st_output_switch_info(struct snd_kcontrol *ctl,
779 "Speakers", "Headphones", "FP Headphones" 742 "Speakers", "Headphones", "FP Headphones"
780 }; 743 };
781 744
782 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 745 return snd_ctl_enum_info(info, 1, 3, names);
783 info->count = 1;
784 info->value.enumerated.items = 3;
785 if (info->value.enumerated.item >= 3)
786 info->value.enumerated.item = 2;
787 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
788 return 0;
789} 746}
790 747
791static int st_output_switch_get(struct snd_kcontrol *ctl, 748static int st_output_switch_get(struct snd_kcontrol *ctl,
@@ -840,13 +797,7 @@ static int st_hp_volume_offset_info(struct snd_kcontrol *ctl,
840 "< 64 ohms", "64-300 ohms", "300-600 ohms" 797 "< 64 ohms", "64-300 ohms", "300-600 ohms"
841 }; 798 };
842 799
843 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 800 return snd_ctl_enum_info(info, 1, 3, names);
844 info->count = 1;
845 info->value.enumerated.items = 3;
846 if (info->value.enumerated.item > 2)
847 info->value.enumerated.item = 2;
848 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
849 return 0;
850} 801}
851 802
852static int st_hp_volume_offset_get(struct snd_kcontrol *ctl, 803static int st_hp_volume_offset_get(struct snd_kcontrol *ctl,
@@ -928,16 +879,25 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
928 return 0; 879 return 0;
929} 880}
930 881
882static int xonar_st_h6_control_filter(struct snd_kcontrol_new *template)
883{
884 if (!strncmp(template->name, "Master Playback ", 16))
885 /* no volume/mute, as I²C to the third DAC does not work */
886 return 1;
887 return 0;
888}
889
931static int add_pcm1796_controls(struct oxygen *chip) 890static int add_pcm1796_controls(struct oxygen *chip)
932{ 891{
892 struct xonar_pcm179x *data = chip->model_data;
933 int err; 893 int err;
934 894
935 err = snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); 895 if (!data->broken_i2c) {
936 if (err < 0) 896 err = snd_ctl_add(chip->card,
937 return err; 897 snd_ctl_new1(&rolloff_control, chip));
938 err = snd_ctl_add(chip->card, snd_ctl_new1(&os_128_control, chip)); 898 if (err < 0)
939 if (err < 0) 899 return err;
940 return err; 900 }
941 return 0; 901 return 0;
942} 902}
943 903
@@ -956,7 +916,15 @@ static int xonar_d2_mixer_init(struct oxygen *chip)
956 916
957static int xonar_hdav_mixer_init(struct oxygen *chip) 917static int xonar_hdav_mixer_init(struct oxygen *chip)
958{ 918{
959 return add_pcm1796_controls(chip); 919 int err;
920
921 err = snd_ctl_add(chip->card, snd_ctl_new1(&hdav_hdmi_control, chip));
922 if (err < 0)
923 return err;
924 err = add_pcm1796_controls(chip);
925 if (err < 0)
926 return err;
927 return 0;
960} 928}
961 929
962static int xonar_st_mixer_init(struct oxygen *chip) 930static int xonar_st_mixer_init(struct oxygen *chip)
@@ -976,6 +944,45 @@ static int xonar_st_mixer_init(struct oxygen *chip)
976 return 0; 944 return 0;
977} 945}
978 946
947static void dump_pcm1796_registers(struct oxygen *chip,
948 struct snd_info_buffer *buffer)
949{
950 struct xonar_pcm179x *data = chip->model_data;
951 unsigned int dac, i;
952
953 for (dac = 0; dac < data->dacs; ++dac) {
954 snd_iprintf(buffer, "\nPCM1796 %u:", dac + 1);
955 for (i = 0; i < 5; ++i)
956 snd_iprintf(buffer, " %02x",
957 data->pcm1796_regs[dac][i]);
958 }
959 snd_iprintf(buffer, "\n");
960}
961
962static void dump_cs2000_registers(struct oxygen *chip,
963 struct snd_info_buffer *buffer)
964{
965 struct xonar_pcm179x *data = chip->model_data;
966 unsigned int i;
967
968 if (data->has_cs2000) {
969 snd_iprintf(buffer, "\nCS2000:\n00: ");
970 for (i = 1; i < 0x10; ++i)
971 snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
972 snd_iprintf(buffer, "\n10:");
973 for (i = 0x10; i < 0x1f; ++i)
974 snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
975 snd_iprintf(buffer, "\n");
976 }
977}
978
979static void dump_st_registers(struct oxygen *chip,
980 struct snd_info_buffer *buffer)
981{
982 dump_pcm1796_registers(chip, buffer);
983 dump_cs2000_registers(chip, buffer);
984}
985
979static const struct oxygen_model model_xonar_d2 = { 986static const struct oxygen_model model_xonar_d2 = {
980 .longname = "Asus Virtuoso 200", 987 .longname = "Asus Virtuoso 200",
981 .chip = "AV200", 988 .chip = "AV200",
@@ -985,11 +992,11 @@ static const struct oxygen_model model_xonar_d2 = {
985 .cleanup = xonar_d2_cleanup, 992 .cleanup = xonar_d2_cleanup,
986 .suspend = xonar_d2_suspend, 993 .suspend = xonar_d2_suspend,
987 .resume = xonar_d2_resume, 994 .resume = xonar_d2_resume,
988 .get_i2s_mclk = get_pcm1796_i2s_mclk,
989 .set_dac_params = set_pcm1796_params, 995 .set_dac_params = set_pcm1796_params,
990 .set_adc_params = xonar_set_cs53x1_params, 996 .set_adc_params = xonar_set_cs53x1_params,
991 .update_dac_volume = update_pcm1796_volume, 997 .update_dac_volume = update_pcm1796_volume,
992 .update_dac_mute = update_pcm1796_mute, 998 .update_dac_mute = update_pcm1796_mute,
999 .dump_registers = dump_pcm1796_registers,
993 .dac_tlv = pcm1796_db_scale, 1000 .dac_tlv = pcm1796_db_scale,
994 .model_data_size = sizeof(struct xonar_pcm179x), 1001 .model_data_size = sizeof(struct xonar_pcm179x),
995 .device_config = PLAYBACK_0_TO_I2S | 1002 .device_config = PLAYBACK_0_TO_I2S |
@@ -999,13 +1006,16 @@ static const struct oxygen_model model_xonar_d2 = {
999 MIDI_OUTPUT | 1006 MIDI_OUTPUT |
1000 MIDI_INPUT | 1007 MIDI_INPUT |
1001 AC97_CD_INPUT, 1008 AC97_CD_INPUT,
1002 .dac_channels = 8, 1009 .dac_channels_pcm = 8,
1010 .dac_channels_mixer = 8,
1003 .dac_volume_min = 255 - 2*60, 1011 .dac_volume_min = 255 - 2*60,
1004 .dac_volume_max = 255, 1012 .dac_volume_max = 255,
1005 .misc_flags = OXYGEN_MISC_MIDI, 1013 .misc_flags = OXYGEN_MISC_MIDI,
1006 .function_flags = OXYGEN_FUNCTION_SPI | 1014 .function_flags = OXYGEN_FUNCTION_SPI |
1007 OXYGEN_FUNCTION_ENABLE_SPI_4_5, 1015 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
1008 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1016 .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
1017 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
1018 .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
1009 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1019 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1010}; 1020};
1011 1021
@@ -1018,25 +1028,28 @@ static const struct oxygen_model model_xonar_hdav = {
1018 .suspend = xonar_hdav_suspend, 1028 .suspend = xonar_hdav_suspend,
1019 .resume = xonar_hdav_resume, 1029 .resume = xonar_hdav_resume,
1020 .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter, 1030 .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter,
1021 .get_i2s_mclk = get_pcm1796_i2s_mclk,
1022 .set_dac_params = set_hdav_params, 1031 .set_dac_params = set_hdav_params,
1023 .set_adc_params = xonar_set_cs53x1_params, 1032 .set_adc_params = xonar_set_cs53x1_params,
1024 .update_dac_volume = update_pcm1796_volume, 1033 .update_dac_volume = update_pcm1796_volume,
1025 .update_dac_mute = update_pcm1796_mute, 1034 .update_dac_mute = update_pcm1796_mute,
1026 .uart_input = xonar_hdmi_uart_input, 1035 .uart_input = xonar_hdmi_uart_input,
1027 .ac97_switch = xonar_line_mic_ac97_switch, 1036 .ac97_switch = xonar_line_mic_ac97_switch,
1037 .dump_registers = dump_pcm1796_registers,
1028 .dac_tlv = pcm1796_db_scale, 1038 .dac_tlv = pcm1796_db_scale,
1029 .model_data_size = sizeof(struct xonar_hdav), 1039 .model_data_size = sizeof(struct xonar_hdav),
1030 .device_config = PLAYBACK_0_TO_I2S | 1040 .device_config = PLAYBACK_0_TO_I2S |
1031 PLAYBACK_1_TO_SPDIF | 1041 PLAYBACK_1_TO_SPDIF |
1032 CAPTURE_0_FROM_I2S_2 | 1042 CAPTURE_0_FROM_I2S_2 |
1033 CAPTURE_1_FROM_SPDIF, 1043 CAPTURE_1_FROM_SPDIF,
1034 .dac_channels = 8, 1044 .dac_channels_pcm = 8,
1045 .dac_channels_mixer = 2,
1035 .dac_volume_min = 255 - 2*60, 1046 .dac_volume_min = 255 - 2*60,
1036 .dac_volume_max = 255, 1047 .dac_volume_max = 255,
1037 .misc_flags = OXYGEN_MISC_MIDI, 1048 .misc_flags = OXYGEN_MISC_MIDI,
1038 .function_flags = OXYGEN_FUNCTION_2WIRE, 1049 .function_flags = OXYGEN_FUNCTION_2WIRE,
1039 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1050 .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
1051 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
1052 .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
1040 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1053 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1041}; 1054};
1042 1055
@@ -1048,22 +1061,26 @@ static const struct oxygen_model model_xonar_st = {
1048 .cleanup = xonar_st_cleanup, 1061 .cleanup = xonar_st_cleanup,
1049 .suspend = xonar_st_suspend, 1062 .suspend = xonar_st_suspend,
1050 .resume = xonar_st_resume, 1063 .resume = xonar_st_resume,
1051 .get_i2s_mclk = get_pcm1796_i2s_mclk,
1052 .set_dac_params = set_st_params, 1064 .set_dac_params = set_st_params,
1053 .set_adc_params = xonar_set_cs53x1_params, 1065 .set_adc_params = xonar_set_cs53x1_params,
1054 .update_dac_volume = update_pcm1796_volume, 1066 .update_dac_volume = update_pcm1796_volume,
1055 .update_dac_mute = update_pcm1796_mute, 1067 .update_dac_mute = update_pcm1796_mute,
1056 .ac97_switch = xonar_line_mic_ac97_switch, 1068 .ac97_switch = xonar_line_mic_ac97_switch,
1069 .dump_registers = dump_st_registers,
1057 .dac_tlv = pcm1796_db_scale, 1070 .dac_tlv = pcm1796_db_scale,
1058 .model_data_size = sizeof(struct xonar_pcm179x), 1071 .model_data_size = sizeof(struct xonar_pcm179x),
1059 .device_config = PLAYBACK_0_TO_I2S | 1072 .device_config = PLAYBACK_0_TO_I2S |
1060 PLAYBACK_1_TO_SPDIF | 1073 PLAYBACK_1_TO_SPDIF |
1061 CAPTURE_0_FROM_I2S_2, 1074 CAPTURE_0_FROM_I2S_2 |
1062 .dac_channels = 2, 1075 AC97_FMIC_SWITCH,
1076 .dac_channels_pcm = 2,
1077 .dac_channels_mixer = 2,
1063 .dac_volume_min = 255 - 2*60, 1078 .dac_volume_min = 255 - 2*60,
1064 .dac_volume_max = 255, 1079 .dac_volume_max = 255,
1065 .function_flags = OXYGEN_FUNCTION_2WIRE, 1080 .function_flags = OXYGEN_FUNCTION_2WIRE,
1066 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1081 .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
1082 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
1083 .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
1067 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1084 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1068}; 1085};
1069 1086
@@ -1089,7 +1106,8 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1089 break; 1106 break;
1090 case GPIO_DB_H6: 1107 case GPIO_DB_H6:
1091 chip->model.shortname = "Xonar HDAV1.3+H6"; 1108 chip->model.shortname = "Xonar HDAV1.3+H6";
1092 chip->model.private_data = 1; 1109 chip->model.dac_channels_mixer = 8;
1110 chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
1093 break; 1111 break;
1094 } 1112 }
1095 break; 1113 break;
@@ -1102,8 +1120,10 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1102 break; 1120 break;
1103 case GPIO_DB_H6: 1121 case GPIO_DB_H6:
1104 chip->model.shortname = "Xonar ST+H6"; 1122 chip->model.shortname = "Xonar ST+H6";
1105 chip->model.dac_channels = 8; 1123 chip->model.control_filter = xonar_st_h6_control_filter;
1106 chip->model.private_data = 1; 1124 chip->model.dac_channels_pcm = 8;
1125 chip->model.dac_channels_mixer = 8;
1126 chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
1107 break; 1127 break;
1108 } 1128 }
1109 break; 1129 break;
@@ -1114,9 +1134,6 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1114 chip->model.resume = xonar_stx_resume; 1134 chip->model.resume = xonar_stx_resume;
1115 chip->model.set_dac_params = set_pcm1796_params; 1135 chip->model.set_dac_params = set_pcm1796_params;
1116 break; 1136 break;
1117 case 0x835e:
1118 snd_printk(KERN_ERR "the HDAV1.3 Slim is not supported\n");
1119 return -ENODEV;
1120 default: 1137 default:
1121 return -EINVAL; 1138 return -EINVAL;
1122 } 1139 }
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 200f7601276f..42d1ab136217 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * card driver for models with WM8776/WM8766 DACs (Xonar DS) 2 * card driver for models with WM8776/WM8766 DACs (Xonar DS/HDAV1.3 Slim)
3 * 3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * 5 *
@@ -22,26 +22,48 @@
22 * 22 *
23 * CMI8788: 23 * CMI8788:
24 * 24 *
25 * SPI 0 -> WM8766 (surround, center/LFE, back) 25 * SPI 0 -> WM8766 (surround, center/LFE, back)
26 * SPI 1 -> WM8776 (front, input) 26 * SPI 1 -> WM8776 (front, input)
27 * 27 *
28 * GPIO 4 <- headphone detect, 0 = plugged 28 * GPIO 4 <- headphone detect, 0 = plugged
29 * GPIO 6 -> route input jack to mic-in (0) or line-in (1) 29 * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
30 * GPIO 7 -> enable output to front L/R speaker channels 30 * GPIO 7 -> enable output to front L/R speaker channels
31 * GPIO 8 -> enable output to other speaker channels and front panel headphone 31 * GPIO 8 -> enable output to other speaker channels and front panel headphone
32 * 32 *
33 * WM8766: 33 * WM8776:
34 * 34 *
35 * input 1 <- line 35 * input 1 <- line
36 * input 2 <- mic 36 * input 2 <- mic
37 * input 3 <- front mic 37 * input 3 <- front mic
38 * input 4 <- aux 38 * input 4 <- aux
39 */
40
41/*
42 * Xonar HDAV1.3 Slim
43 * ------------------
44 *
45 * CMI8788:
46 *
47 * I²C <-> WM8776 (addr 0011010)
48 *
49 * GPIO 0 -> disable HDMI output
50 * GPIO 1 -> enable HP output
51 * GPIO 6 -> firmware EEPROM I²C clock
52 * GPIO 7 <-> firmware EEPROM I²C data
53 *
54 * UART <-> HDMI controller
55 *
56 * WM8776:
57 *
58 * input 1 <- mic
59 * input 2 <- aux
39 */ 60 */
40 61
41#include <linux/pci.h> 62#include <linux/pci.h>
42#include <linux/delay.h> 63#include <linux/delay.h>
43#include <sound/control.h> 64#include <sound/control.h>
44#include <sound/core.h> 65#include <sound/core.h>
66#include <sound/info.h>
45#include <sound/jack.h> 67#include <sound/jack.h>
46#include <sound/pcm.h> 68#include <sound/pcm.h>
47#include <sound/pcm_params.h> 69#include <sound/pcm_params.h>
@@ -55,6 +77,13 @@
55#define GPIO_DS_OUTPUT_FRONTLR 0x0080 77#define GPIO_DS_OUTPUT_FRONTLR 0x0080
56#define GPIO_DS_OUTPUT_ENABLE 0x0100 78#define GPIO_DS_OUTPUT_ENABLE 0x0100
57 79
80#define GPIO_SLIM_HDMI_DISABLE 0x0001
81#define GPIO_SLIM_OUTPUT_ENABLE 0x0002
82#define GPIO_SLIM_FIRMWARE_CLK 0x0040
83#define GPIO_SLIM_FIRMWARE_DATA 0x0080
84
85#define I2C_DEVICE_WM8776 0x34 /* 001101, 0, /W=0 */
86
58#define LC_CONTROL_LIMITER 0x40000000 87#define LC_CONTROL_LIMITER 0x40000000
59#define LC_CONTROL_ALC 0x20000000 88#define LC_CONTROL_ALC 0x20000000
60 89
@@ -66,19 +95,37 @@ struct xonar_wm87x6 {
66 struct snd_kcontrol *mic_adcmux_control; 95 struct snd_kcontrol *mic_adcmux_control;
67 struct snd_kcontrol *lc_controls[13]; 96 struct snd_kcontrol *lc_controls[13];
68 struct snd_jack *hp_jack; 97 struct snd_jack *hp_jack;
98 struct xonar_hdmi hdmi;
69}; 99};
70 100
71static void wm8776_write(struct oxygen *chip, 101static void wm8776_write_spi(struct oxygen *chip,
72 unsigned int reg, unsigned int value) 102 unsigned int reg, unsigned int value)
73{ 103{
74 struct xonar_wm87x6 *data = chip->model_data;
75
76 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 104 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
77 OXYGEN_SPI_DATA_LENGTH_2 | 105 OXYGEN_SPI_DATA_LENGTH_2 |
78 OXYGEN_SPI_CLOCK_160 | 106 OXYGEN_SPI_CLOCK_160 |
79 (1 << OXYGEN_SPI_CODEC_SHIFT) | 107 (1 << OXYGEN_SPI_CODEC_SHIFT) |
80 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 108 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
81 (reg << 9) | value); 109 (reg << 9) | value);
110}
111
112static void wm8776_write_i2c(struct oxygen *chip,
113 unsigned int reg, unsigned int value)
114{
115 oxygen_write_i2c(chip, I2C_DEVICE_WM8776,
116 (reg << 1) | (value >> 8), value);
117}
118
119static void wm8776_write(struct oxygen *chip,
120 unsigned int reg, unsigned int value)
121{
122 struct xonar_wm87x6 *data = chip->model_data;
123
124 if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
125 OXYGEN_FUNCTION_SPI)
126 wm8776_write_spi(chip, reg, value);
127 else
128 wm8776_write_i2c(chip, reg, value);
82 if (reg < ARRAY_SIZE(data->wm8776_regs)) { 129 if (reg < ARRAY_SIZE(data->wm8776_regs)) {
83 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER) 130 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER)
84 value &= ~WM8776_UPDATE; 131 value &= ~WM8776_UPDATE;
@@ -245,17 +292,50 @@ static void xonar_ds_init(struct oxygen *chip)
245 snd_component_add(chip->card, "WM8766"); 292 snd_component_add(chip->card, "WM8766");
246} 293}
247 294
295static void xonar_hdav_slim_init(struct oxygen *chip)
296{
297 struct xonar_wm87x6 *data = chip->model_data;
298
299 data->generic.anti_pop_delay = 300;
300 data->generic.output_enable_bit = GPIO_SLIM_OUTPUT_ENABLE;
301
302 wm8776_init(chip);
303
304 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
305 GPIO_SLIM_HDMI_DISABLE |
306 GPIO_SLIM_FIRMWARE_CLK |
307 GPIO_SLIM_FIRMWARE_DATA);
308
309 xonar_hdmi_init(chip, &data->hdmi);
310 xonar_enable_output(chip);
311
312 snd_component_add(chip->card, "WM8776");
313}
314
248static void xonar_ds_cleanup(struct oxygen *chip) 315static void xonar_ds_cleanup(struct oxygen *chip)
249{ 316{
250 xonar_disable_output(chip); 317 xonar_disable_output(chip);
251 wm8776_write(chip, WM8776_RESET, 0); 318 wm8776_write(chip, WM8776_RESET, 0);
252} 319}
253 320
321static void xonar_hdav_slim_cleanup(struct oxygen *chip)
322{
323 xonar_hdmi_cleanup(chip);
324 xonar_disable_output(chip);
325 wm8776_write(chip, WM8776_RESET, 0);
326 msleep(2);
327}
328
254static void xonar_ds_suspend(struct oxygen *chip) 329static void xonar_ds_suspend(struct oxygen *chip)
255{ 330{
256 xonar_ds_cleanup(chip); 331 xonar_ds_cleanup(chip);
257} 332}
258 333
334static void xonar_hdav_slim_suspend(struct oxygen *chip)
335{
336 xonar_hdav_slim_cleanup(chip);
337}
338
259static void xonar_ds_resume(struct oxygen *chip) 339static void xonar_ds_resume(struct oxygen *chip)
260{ 340{
261 wm8776_registers_init(chip); 341 wm8776_registers_init(chip);
@@ -264,6 +344,15 @@ static void xonar_ds_resume(struct oxygen *chip)
264 xonar_ds_handle_hp_jack(chip); 344 xonar_ds_handle_hp_jack(chip);
265} 345}
266 346
347static void xonar_hdav_slim_resume(struct oxygen *chip)
348{
349 struct xonar_wm87x6 *data = chip->model_data;
350
351 wm8776_registers_init(chip);
352 xonar_hdmi_resume(chip, &data->hdmi);
353 xonar_enable_output(chip);
354}
355
267static void wm8776_adc_hardware_filter(unsigned int channel, 356static void wm8776_adc_hardware_filter(unsigned int channel,
268 struct snd_pcm_hardware *hardware) 357 struct snd_pcm_hardware *hardware)
269{ 358{
@@ -278,6 +367,13 @@ static void wm8776_adc_hardware_filter(unsigned int channel,
278 } 367 }
279} 368}
280 369
370static void xonar_hdav_slim_hardware_filter(unsigned int channel,
371 struct snd_pcm_hardware *hardware)
372{
373 wm8776_adc_hardware_filter(channel, hardware);
374 xonar_hdmi_pcm_hardware_filter(channel, hardware);
375}
376
281static void set_wm87x6_dac_params(struct oxygen *chip, 377static void set_wm87x6_dac_params(struct oxygen *chip,
282 struct snd_pcm_hw_params *params) 378 struct snd_pcm_hw_params *params)
283{ 379{
@@ -294,6 +390,14 @@ static void set_wm8776_adc_params(struct oxygen *chip,
294 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg); 390 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg);
295} 391}
296 392
393static void set_hdav_slim_dac_params(struct oxygen *chip,
394 struct snd_pcm_hw_params *params)
395{
396 struct xonar_wm87x6 *data = chip->model_data;
397
398 xonar_set_hdmi_params(chip, &data->hdmi, params);
399}
400
297static void update_wm8776_volume(struct oxygen *chip) 401static void update_wm8776_volume(struct oxygen *chip)
298{ 402{
299 struct xonar_wm87x6 *data = chip->model_data; 403 struct xonar_wm87x6 *data = chip->model_data;
@@ -473,11 +577,6 @@ static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
473 const char *const *names; 577 const char *const *names;
474 578
475 max = (ctl->private_value >> 12) & 0xf; 579 max = (ctl->private_value >> 12) & 0xf;
476 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
477 info->count = 1;
478 info->value.enumerated.items = max + 1;
479 if (info->value.enumerated.item > max)
480 info->value.enumerated.item = max;
481 switch ((ctl->private_value >> 24) & 0x1f) { 580 switch ((ctl->private_value >> 24) & 0x1f) {
482 case WM8776_ALCCTRL2: 581 case WM8776_ALCCTRL2:
483 names = hld; 582 names = hld;
@@ -501,8 +600,7 @@ static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
501 default: 600 default:
502 return -ENXIO; 601 return -ENXIO;
503 } 602 }
504 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); 603 return snd_ctl_enum_info(info, 1, max + 1, names);
505 return 0;
506} 604}
507 605
508static int wm8776_field_volume_info(struct snd_kcontrol *ctl, 606static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
@@ -759,13 +857,8 @@ static int wm8776_level_control_info(struct snd_kcontrol *ctl,
759 static const char *const names[3] = { 857 static const char *const names[3] = {
760 "None", "Peak Limiter", "Automatic Level Control" 858 "None", "Peak Limiter", "Automatic Level Control"
761 }; 859 };
762 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 860
763 info->count = 1; 861 return snd_ctl_enum_info(info, 1, 3, names);
764 info->value.enumerated.items = 3;
765 if (info->value.enumerated.item >= 3)
766 info->value.enumerated.item = 2;
767 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
768 return 0;
769} 862}
770 863
771static int wm8776_level_control_get(struct snd_kcontrol *ctl, 864static int wm8776_level_control_get(struct snd_kcontrol *ctl,
@@ -851,13 +944,7 @@ static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
851 "None", "High-pass Filter" 944 "None", "High-pass Filter"
852 }; 945 };
853 946
854 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 947 return snd_ctl_enum_info(info, 1, 2, names);
855 info->count = 1;
856 info->value.enumerated.items = 2;
857 if (info->value.enumerated.item >= 2)
858 info->value.enumerated.item = 1;
859 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
860 return 0;
861} 948}
862 949
863static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 950static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
@@ -985,6 +1072,53 @@ static const struct snd_kcontrol_new ds_controls[] = {
985 .private_value = 0, 1072 .private_value = 0,
986 }, 1073 },
987}; 1074};
1075static const struct snd_kcontrol_new hdav_slim_controls[] = {
1076 {
1077 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1078 .name = "HDMI Playback Switch",
1079 .info = snd_ctl_boolean_mono_info,
1080 .get = xonar_gpio_bit_switch_get,
1081 .put = xonar_gpio_bit_switch_put,
1082 .private_value = GPIO_SLIM_HDMI_DISABLE | XONAR_GPIO_BIT_INVERT,
1083 },
1084 {
1085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1086 .name = "Headphone Playback Volume",
1087 .info = wm8776_hp_vol_info,
1088 .get = wm8776_hp_vol_get,
1089 .put = wm8776_hp_vol_put,
1090 .tlv = { .p = wm8776_hp_db_scale },
1091 },
1092 WM8776_BIT_SWITCH("Headphone Playback Switch",
1093 WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
1094 {
1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1096 .name = "Input Capture Volume",
1097 .info = wm8776_input_vol_info,
1098 .get = wm8776_input_vol_get,
1099 .put = wm8776_input_vol_put,
1100 .tlv = { .p = wm8776_adc_db_scale },
1101 },
1102 WM8776_BIT_SWITCH("Mic Capture Switch",
1103 WM8776_ADCMUX, 1 << 0, 0, 0),
1104 WM8776_BIT_SWITCH("Aux Capture Switch",
1105 WM8776_ADCMUX, 1 << 1, 0, 0),
1106 {
1107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1108 .name = "ADC Filter Capture Enum",
1109 .info = hpf_info,
1110 .get = hpf_get,
1111 .put = hpf_put,
1112 },
1113 {
1114 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1115 .name = "Level Control Capture Enum",
1116 .info = wm8776_level_control_info,
1117 .get = wm8776_level_control_get,
1118 .put = wm8776_level_control_put,
1119 .private_value = 0,
1120 },
1121};
988static const struct snd_kcontrol_new lc_controls[] = { 1122static const struct snd_kcontrol_new lc_controls[] = {
989 WM8776_FIELD_CTL_VOLUME("Limiter Threshold", 1123 WM8776_FIELD_CTL_VOLUME("Limiter Threshold",
990 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, 1124 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
@@ -1028,6 +1162,26 @@ static const struct snd_kcontrol_new lc_controls[] = {
1028 LC_CONTROL_ALC, wm8776_ngth_db_scale), 1162 LC_CONTROL_ALC, wm8776_ngth_db_scale),
1029}; 1163};
1030 1164
1165static int add_lc_controls(struct oxygen *chip)
1166{
1167 struct xonar_wm87x6 *data = chip->model_data;
1168 unsigned int i;
1169 struct snd_kcontrol *ctl;
1170 int err;
1171
1172 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
1173 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
1174 ctl = snd_ctl_new1(&lc_controls[i], chip);
1175 if (!ctl)
1176 return -ENOMEM;
1177 err = snd_ctl_add(chip->card, ctl);
1178 if (err < 0)
1179 return err;
1180 data->lc_controls[i] = ctl;
1181 }
1182 return 0;
1183}
1184
1031static int xonar_ds_mixer_init(struct oxygen *chip) 1185static int xonar_ds_mixer_init(struct oxygen *chip)
1032{ 1186{
1033 struct xonar_wm87x6 *data = chip->model_data; 1187 struct xonar_wm87x6 *data = chip->model_data;
@@ -1049,17 +1203,54 @@ static int xonar_ds_mixer_init(struct oxygen *chip)
1049 } 1203 }
1050 if (!data->line_adcmux_control || !data->mic_adcmux_control) 1204 if (!data->line_adcmux_control || !data->mic_adcmux_control)
1051 return -ENXIO; 1205 return -ENXIO;
1052 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); 1206
1053 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { 1207 return add_lc_controls(chip);
1054 ctl = snd_ctl_new1(&lc_controls[i], chip); 1208}
1209
1210static int xonar_hdav_slim_mixer_init(struct oxygen *chip)
1211{
1212 unsigned int i;
1213 struct snd_kcontrol *ctl;
1214 int err;
1215
1216 for (i = 0; i < ARRAY_SIZE(hdav_slim_controls); ++i) {
1217 ctl = snd_ctl_new1(&hdav_slim_controls[i], chip);
1055 if (!ctl) 1218 if (!ctl)
1056 return -ENOMEM; 1219 return -ENOMEM;
1057 err = snd_ctl_add(chip->card, ctl); 1220 err = snd_ctl_add(chip->card, ctl);
1058 if (err < 0) 1221 if (err < 0)
1059 return err; 1222 return err;
1060 data->lc_controls[i] = ctl;
1061 } 1223 }
1062 return 0; 1224
1225 return add_lc_controls(chip);
1226}
1227
1228static void dump_wm8776_registers(struct oxygen *chip,
1229 struct snd_info_buffer *buffer)
1230{
1231 struct xonar_wm87x6 *data = chip->model_data;
1232 unsigned int i;
1233
1234 snd_iprintf(buffer, "\nWM8776:\n00:");
1235 for (i = 0; i < 0x10; ++i)
1236 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1237 snd_iprintf(buffer, "\n10:");
1238 for (i = 0x10; i < 0x17; ++i)
1239 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1240 snd_iprintf(buffer, "\n");
1241}
1242
1243static void dump_wm87x6_registers(struct oxygen *chip,
1244 struct snd_info_buffer *buffer)
1245{
1246 struct xonar_wm87x6 *data = chip->model_data;
1247 unsigned int i;
1248
1249 dump_wm8776_registers(chip, buffer);
1250 snd_iprintf(buffer, "\nWM8766:\n00:");
1251 for (i = 0; i < 0x10; ++i)
1252 snd_iprintf(buffer, " %03x", data->wm8766_regs[i]);
1253 snd_iprintf(buffer, "\n");
1063} 1254}
1064 1255
1065static const struct oxygen_model model_xonar_ds = { 1256static const struct oxygen_model model_xonar_ds = {
@@ -1072,22 +1263,57 @@ static const struct oxygen_model model_xonar_ds = {
1072 .suspend = xonar_ds_suspend, 1263 .suspend = xonar_ds_suspend,
1073 .resume = xonar_ds_resume, 1264 .resume = xonar_ds_resume,
1074 .pcm_hardware_filter = wm8776_adc_hardware_filter, 1265 .pcm_hardware_filter = wm8776_adc_hardware_filter,
1075 .get_i2s_mclk = oxygen_default_i2s_mclk,
1076 .set_dac_params = set_wm87x6_dac_params, 1266 .set_dac_params = set_wm87x6_dac_params,
1077 .set_adc_params = set_wm8776_adc_params, 1267 .set_adc_params = set_wm8776_adc_params,
1078 .update_dac_volume = update_wm87x6_volume, 1268 .update_dac_volume = update_wm87x6_volume,
1079 .update_dac_mute = update_wm87x6_mute, 1269 .update_dac_mute = update_wm87x6_mute,
1080 .update_center_lfe_mix = update_wm8766_center_lfe_mix, 1270 .update_center_lfe_mix = update_wm8766_center_lfe_mix,
1081 .gpio_changed = xonar_ds_gpio_changed, 1271 .gpio_changed = xonar_ds_gpio_changed,
1272 .dump_registers = dump_wm87x6_registers,
1082 .dac_tlv = wm87x6_dac_db_scale, 1273 .dac_tlv = wm87x6_dac_db_scale,
1083 .model_data_size = sizeof(struct xonar_wm87x6), 1274 .model_data_size = sizeof(struct xonar_wm87x6),
1084 .device_config = PLAYBACK_0_TO_I2S | 1275 .device_config = PLAYBACK_0_TO_I2S |
1085 PLAYBACK_1_TO_SPDIF | 1276 PLAYBACK_1_TO_SPDIF |
1086 CAPTURE_0_FROM_I2S_1, 1277 CAPTURE_0_FROM_I2S_1,
1087 .dac_channels = 8, 1278 .dac_channels_pcm = 8,
1279 .dac_channels_mixer = 8,
1088 .dac_volume_min = 255 - 2*60, 1280 .dac_volume_min = 255 - 2*60,
1089 .dac_volume_max = 255, 1281 .dac_volume_max = 255,
1090 .function_flags = OXYGEN_FUNCTION_SPI, 1282 .function_flags = OXYGEN_FUNCTION_SPI,
1283 .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
1284 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
1285 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1286 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1287};
1288
1289static const struct oxygen_model model_xonar_hdav_slim = {
1290 .shortname = "Xonar HDAV1.3 Slim",
1291 .longname = "Asus Virtuoso 200",
1292 .chip = "AV200",
1293 .init = xonar_hdav_slim_init,
1294 .mixer_init = xonar_hdav_slim_mixer_init,
1295 .cleanup = xonar_hdav_slim_cleanup,
1296 .suspend = xonar_hdav_slim_suspend,
1297 .resume = xonar_hdav_slim_resume,
1298 .pcm_hardware_filter = xonar_hdav_slim_hardware_filter,
1299 .set_dac_params = set_hdav_slim_dac_params,
1300 .set_adc_params = set_wm8776_adc_params,
1301 .update_dac_volume = update_wm8776_volume,
1302 .update_dac_mute = update_wm8776_mute,
1303 .uart_input = xonar_hdmi_uart_input,
1304 .dump_registers = dump_wm8776_registers,
1305 .dac_tlv = wm87x6_dac_db_scale,
1306 .model_data_size = sizeof(struct xonar_wm87x6),
1307 .device_config = PLAYBACK_0_TO_I2S |
1308 PLAYBACK_1_TO_SPDIF |
1309 CAPTURE_0_FROM_I2S_1,
1310 .dac_channels_pcm = 8,
1311 .dac_channels_mixer = 2,
1312 .dac_volume_min = 255 - 2*60,
1313 .dac_volume_max = 255,
1314 .function_flags = OXYGEN_FUNCTION_2WIRE,
1315 .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
1316 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
1091 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1317 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1092 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1318 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1093}; 1319};
@@ -1099,6 +1325,9 @@ int __devinit get_xonar_wm87x6_model(struct oxygen *chip,
1099 case 0x838e: 1325 case 0x838e:
1100 chip->model = model_xonar_ds; 1326 chip->model = model_xonar_ds;
1101 break; 1327 break;
1328 case 0x835e:
1329 chip->model = model_xonar_hdav_slim;
1330 break;
1102 default: 1331 default:
1103 return -EINVAL; 1332 return -EINVAL;
1104 } 1333 }
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 0b720cf7783e..2d8332416c83 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -60,6 +60,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
60 "{RME HDSP-9652}," 60 "{RME HDSP-9652},"
61 "{RME HDSP-9632}}"); 61 "{RME HDSP-9632}}");
62#ifdef HDSP_FW_LOADER 62#ifdef HDSP_FW_LOADER
63MODULE_FIRMWARE("rpm_firmware.bin");
63MODULE_FIRMWARE("multiface_firmware.bin"); 64MODULE_FIRMWARE("multiface_firmware.bin");
64MODULE_FIRMWARE("multiface_firmware_rev11.bin"); 65MODULE_FIRMWARE("multiface_firmware_rev11.bin");
65MODULE_FIRMWARE("digiface_firmware.bin"); 66MODULE_FIRMWARE("digiface_firmware.bin");
@@ -81,6 +82,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
81#define H9632_SS_CHANNELS 12 82#define H9632_SS_CHANNELS 12
82#define H9632_DS_CHANNELS 8 83#define H9632_DS_CHANNELS 8
83#define H9632_QS_CHANNELS 4 84#define H9632_QS_CHANNELS 4
85#define RPM_CHANNELS 6
84 86
85/* Write registers. These are defined as byte-offsets from the iobase value. 87/* Write registers. These are defined as byte-offsets from the iobase value.
86 */ 88 */
@@ -191,6 +193,25 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
191#define HDSP_PhoneGain1 (1<<30) 193#define HDSP_PhoneGain1 (1<<30)
192#define HDSP_QuadSpeed (1<<31) 194#define HDSP_QuadSpeed (1<<31)
193 195
196/* RPM uses some of the registers for special purposes */
197#define HDSP_RPM_Inp12 0x04A00
198#define HDSP_RPM_Inp12_Phon_6dB 0x00800 /* Dolby */
199#define HDSP_RPM_Inp12_Phon_0dB 0x00000 /* .. */
200#define HDSP_RPM_Inp12_Phon_n6dB 0x04000 /* inp_0 */
201#define HDSP_RPM_Inp12_Line_0dB 0x04200 /* Dolby+PRO */
202#define HDSP_RPM_Inp12_Line_n6dB 0x00200 /* PRO */
203
204#define HDSP_RPM_Inp34 0x32000
205#define HDSP_RPM_Inp34_Phon_6dB 0x20000 /* SyncRef1 */
206#define HDSP_RPM_Inp34_Phon_0dB 0x00000 /* .. */
207#define HDSP_RPM_Inp34_Phon_n6dB 0x02000 /* SyncRef2 */
208#define HDSP_RPM_Inp34_Line_0dB 0x30000 /* SyncRef1+SyncRef0 */
209#define HDSP_RPM_Inp34_Line_n6dB 0x10000 /* SyncRef0 */
210
211#define HDSP_RPM_Bypass 0x01000
212
213#define HDSP_RPM_Disconnect 0x00001
214
194#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1) 215#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1)
195#define HDSP_ADGainMinus10dBV HDSP_ADGainMask 216#define HDSP_ADGainMinus10dBV HDSP_ADGainMask
196#define HDSP_ADGainPlus4dBu (HDSP_ADGain0) 217#define HDSP_ADGainPlus4dBu (HDSP_ADGain0)
@@ -450,7 +471,7 @@ struct hdsp {
450 u32 creg_spdif; 471 u32 creg_spdif;
451 u32 creg_spdif_stream; 472 u32 creg_spdif_stream;
452 int clock_source_locked; 473 int clock_source_locked;
453 char *card_name; /* digiface/multiface */ 474 char *card_name; /* digiface/multiface/rpm */
454 enum HDSP_IO_Type io_type; /* ditto, but for code use */ 475 enum HDSP_IO_Type io_type; /* ditto, but for code use */
455 unsigned short firmware_rev; 476 unsigned short firmware_rev;
456 unsigned short state; /* stores state bits */ 477 unsigned short state; /* stores state bits */
@@ -612,6 +633,7 @@ static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out)
612 switch (hdsp->io_type) { 633 switch (hdsp->io_type) {
613 case Multiface: 634 case Multiface:
614 case Digiface: 635 case Digiface:
636 case RPM:
615 default: 637 default:
616 if (hdsp->firmware_rev == 0xa) 638 if (hdsp->firmware_rev == 0xa)
617 return (64 * out) + (32 + (in)); 639 return (64 * out) + (32 + (in));
@@ -629,6 +651,7 @@ static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out)
629 switch (hdsp->io_type) { 651 switch (hdsp->io_type) {
630 case Multiface: 652 case Multiface:
631 case Digiface: 653 case Digiface:
654 case RPM:
632 default: 655 default:
633 if (hdsp->firmware_rev == 0xa) 656 if (hdsp->firmware_rev == 0xa)
634 return (64 * out) + in; 657 return (64 * out) + in;
@@ -655,7 +678,7 @@ static int hdsp_check_for_iobox (struct hdsp *hdsp)
655{ 678{
656 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; 679 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
657 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) { 680 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
658 snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n"); 681 snd_printk("Hammerfall-DSP: no IO box connected!\n");
659 hdsp->state &= ~HDSP_FirmwareLoaded; 682 hdsp->state &= ~HDSP_FirmwareLoaded;
660 return -EIO; 683 return -EIO;
661 } 684 }
@@ -680,7 +703,7 @@ static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
680 } 703 }
681 } 704 }
682 705
683 snd_printk("Hammerfall-DSP: no Digiface or Multiface connected!\n"); 706 snd_printk("Hammerfall-DSP: no IO box connected!\n");
684 hdsp->state &= ~HDSP_FirmwareLoaded; 707 hdsp->state &= ~HDSP_FirmwareLoaded;
685 return -EIO; 708 return -EIO;
686} 709}
@@ -752,17 +775,21 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
752 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); 775 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
753 hdsp_write (hdsp, HDSP_fifoData, 0); 776 hdsp_write (hdsp, HDSP_fifoData, 0);
754 777
755 if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) { 778 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) {
756 hdsp->io_type = Multiface; 779 hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
757 hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); 780 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
758 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); 781 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT))
759 hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT); 782 hdsp->io_type = RPM;
783 else
784 hdsp->io_type = Multiface;
760 } else { 785 } else {
761 hdsp->io_type = Digiface; 786 hdsp->io_type = Digiface;
762 } 787 }
763 } else { 788 } else {
764 /* firmware was already loaded, get iobox type */ 789 /* firmware was already loaded, get iobox type */
765 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) 790 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
791 hdsp->io_type = RPM;
792 else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
766 hdsp->io_type = Multiface; 793 hdsp->io_type = Multiface;
767 else 794 else
768 hdsp->io_type = Digiface; 795 hdsp->io_type = Digiface;
@@ -1184,6 +1211,7 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
1184 hdsp->channel_map = channel_map_ds; 1211 hdsp->channel_map = channel_map_ds;
1185 } else { 1212 } else {
1186 switch (hdsp->io_type) { 1213 switch (hdsp->io_type) {
1214 case RPM:
1187 case Multiface: 1215 case Multiface:
1188 hdsp->channel_map = channel_map_mf_ss; 1216 hdsp->channel_map = channel_map_mf_ss;
1189 break; 1217 break;
@@ -3231,6 +3259,318 @@ HDSP_PRECISE_POINTER("Precise Pointer", 0),
3231HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), 3259HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0),
3232}; 3260};
3233 3261
3262
3263static int hdsp_rpm_input12(struct hdsp *hdsp)
3264{
3265 switch (hdsp->control_register & HDSP_RPM_Inp12) {
3266 case HDSP_RPM_Inp12_Phon_6dB:
3267 return 0;
3268 case HDSP_RPM_Inp12_Phon_n6dB:
3269 return 2;
3270 case HDSP_RPM_Inp12_Line_0dB:
3271 return 3;
3272 case HDSP_RPM_Inp12_Line_n6dB:
3273 return 4;
3274 }
3275 return 1;
3276}
3277
3278
3279static int snd_hdsp_get_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3280{
3281 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3282
3283 ucontrol->value.enumerated.item[0] = hdsp_rpm_input12(hdsp);
3284 return 0;
3285}
3286
3287
3288static int hdsp_set_rpm_input12(struct hdsp *hdsp, int mode)
3289{
3290 hdsp->control_register &= ~HDSP_RPM_Inp12;
3291 switch (mode) {
3292 case 0:
3293 hdsp->control_register |= HDSP_RPM_Inp12_Phon_6dB;
3294 break;
3295 case 1:
3296 break;
3297 case 2:
3298 hdsp->control_register |= HDSP_RPM_Inp12_Phon_n6dB;
3299 break;
3300 case 3:
3301 hdsp->control_register |= HDSP_RPM_Inp12_Line_0dB;
3302 break;
3303 case 4:
3304 hdsp->control_register |= HDSP_RPM_Inp12_Line_n6dB;
3305 break;
3306 default:
3307 return -1;
3308 }
3309
3310 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3311 return 0;
3312}
3313
3314
3315static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3316{
3317 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3318 int change;
3319 int val;
3320
3321 if (!snd_hdsp_use_is_exclusive(hdsp))
3322 return -EBUSY;
3323 val = ucontrol->value.enumerated.item[0];
3324 if (val < 0)
3325 val = 0;
3326 if (val > 4)
3327 val = 4;
3328 spin_lock_irq(&hdsp->lock);
3329 if (val != hdsp_rpm_input12(hdsp))
3330 change = (hdsp_set_rpm_input12(hdsp, val) == 0) ? 1 : 0;
3331 else
3332 change = 0;
3333 spin_unlock_irq(&hdsp->lock);
3334 return change;
3335}
3336
3337
3338static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3339{
3340 static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"};
3341
3342 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3343 uinfo->count = 1;
3344 uinfo->value.enumerated.items = 5;
3345 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3346 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3347 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3348 return 0;
3349}
3350
3351
3352static int hdsp_rpm_input34(struct hdsp *hdsp)
3353{
3354 switch (hdsp->control_register & HDSP_RPM_Inp34) {
3355 case HDSP_RPM_Inp34_Phon_6dB:
3356 return 0;
3357 case HDSP_RPM_Inp34_Phon_n6dB:
3358 return 2;
3359 case HDSP_RPM_Inp34_Line_0dB:
3360 return 3;
3361 case HDSP_RPM_Inp34_Line_n6dB:
3362 return 4;
3363 }
3364 return 1;
3365}
3366
3367
3368static int snd_hdsp_get_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3369{
3370 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3371
3372 ucontrol->value.enumerated.item[0] = hdsp_rpm_input34(hdsp);
3373 return 0;
3374}
3375
3376
3377static int hdsp_set_rpm_input34(struct hdsp *hdsp, int mode)
3378{
3379 hdsp->control_register &= ~HDSP_RPM_Inp34;
3380 switch (mode) {
3381 case 0:
3382 hdsp->control_register |= HDSP_RPM_Inp34_Phon_6dB;
3383 break;
3384 case 1:
3385 break;
3386 case 2:
3387 hdsp->control_register |= HDSP_RPM_Inp34_Phon_n6dB;
3388 break;
3389 case 3:
3390 hdsp->control_register |= HDSP_RPM_Inp34_Line_0dB;
3391 break;
3392 case 4:
3393 hdsp->control_register |= HDSP_RPM_Inp34_Line_n6dB;
3394 break;
3395 default:
3396 return -1;
3397 }
3398
3399 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3400 return 0;
3401}
3402
3403
3404static int snd_hdsp_put_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3405{
3406 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3407 int change;
3408 int val;
3409
3410 if (!snd_hdsp_use_is_exclusive(hdsp))
3411 return -EBUSY;
3412 val = ucontrol->value.enumerated.item[0];
3413 if (val < 0)
3414 val = 0;
3415 if (val > 4)
3416 val = 4;
3417 spin_lock_irq(&hdsp->lock);
3418 if (val != hdsp_rpm_input34(hdsp))
3419 change = (hdsp_set_rpm_input34(hdsp, val) == 0) ? 1 : 0;
3420 else
3421 change = 0;
3422 spin_unlock_irq(&hdsp->lock);
3423 return change;
3424}
3425
3426
3427/* RPM Bypass switch */
3428static int hdsp_rpm_bypass(struct hdsp *hdsp)
3429{
3430 return (hdsp->control_register & HDSP_RPM_Bypass) ? 1 : 0;
3431}
3432
3433
3434static int snd_hdsp_get_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3435{
3436 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3437
3438 ucontrol->value.integer.value[0] = hdsp_rpm_bypass(hdsp);
3439 return 0;
3440}
3441
3442
3443static int hdsp_set_rpm_bypass(struct hdsp *hdsp, int on)
3444{
3445 if (on)
3446 hdsp->control_register |= HDSP_RPM_Bypass;
3447 else
3448 hdsp->control_register &= ~HDSP_RPM_Bypass;
3449 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3450 return 0;
3451}
3452
3453
3454static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3455{
3456 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3457 int change;
3458 unsigned int val;
3459
3460 if (!snd_hdsp_use_is_exclusive(hdsp))
3461 return -EBUSY;
3462 val = ucontrol->value.integer.value[0] & 1;
3463 spin_lock_irq(&hdsp->lock);
3464 change = (int)val != hdsp_rpm_bypass(hdsp);
3465 hdsp_set_rpm_bypass(hdsp, val);
3466 spin_unlock_irq(&hdsp->lock);
3467 return change;
3468}
3469
3470
3471static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3472{
3473 static char *texts[] = {"On", "Off"};
3474
3475 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3476 uinfo->count = 1;
3477 uinfo->value.enumerated.items = 2;
3478 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3479 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3480 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3481 return 0;
3482}
3483
3484
3485/* RPM Disconnect switch */
3486static int hdsp_rpm_disconnect(struct hdsp *hdsp)
3487{
3488 return (hdsp->control_register & HDSP_RPM_Disconnect) ? 1 : 0;
3489}
3490
3491
3492static int snd_hdsp_get_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3493{
3494 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3495
3496 ucontrol->value.integer.value[0] = hdsp_rpm_disconnect(hdsp);
3497 return 0;
3498}
3499
3500
3501static int hdsp_set_rpm_disconnect(struct hdsp *hdsp, int on)
3502{
3503 if (on)
3504 hdsp->control_register |= HDSP_RPM_Disconnect;
3505 else
3506 hdsp->control_register &= ~HDSP_RPM_Disconnect;
3507 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3508 return 0;
3509}
3510
3511
3512static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3513{
3514 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3515 int change;
3516 unsigned int val;
3517
3518 if (!snd_hdsp_use_is_exclusive(hdsp))
3519 return -EBUSY;
3520 val = ucontrol->value.integer.value[0] & 1;
3521 spin_lock_irq(&hdsp->lock);
3522 change = (int)val != hdsp_rpm_disconnect(hdsp);
3523 hdsp_set_rpm_disconnect(hdsp, val);
3524 spin_unlock_irq(&hdsp->lock);
3525 return change;
3526}
3527
3528static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3529{
3530 static char *texts[] = {"On", "Off"};
3531
3532 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3533 uinfo->count = 1;
3534 uinfo->value.enumerated.items = 2;
3535 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3536 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3537 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3538 return 0;
3539}
3540
3541static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = {
3542 {
3543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3544 .name = "RPM Bypass",
3545 .get = snd_hdsp_get_rpm_bypass,
3546 .put = snd_hdsp_put_rpm_bypass,
3547 .info = snd_hdsp_info_rpm_bypass
3548 },
3549 {
3550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3551 .name = "RPM Disconnect",
3552 .get = snd_hdsp_get_rpm_disconnect,
3553 .put = snd_hdsp_put_rpm_disconnect,
3554 .info = snd_hdsp_info_rpm_disconnect
3555 },
3556 {
3557 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3558 .name = "Input 1/2",
3559 .get = snd_hdsp_get_rpm_input12,
3560 .put = snd_hdsp_put_rpm_input12,
3561 .info = snd_hdsp_info_rpm_input
3562 },
3563 {
3564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3565 .name = "Input 3/4",
3566 .get = snd_hdsp_get_rpm_input34,
3567 .put = snd_hdsp_put_rpm_input34,
3568 .info = snd_hdsp_info_rpm_input
3569 },
3570 HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
3571 HDSP_MIXER("Mixer", 0)
3572};
3573
3234static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); 3574static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
3235static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; 3575static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
3236 3576
@@ -3240,6 +3580,16 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
3240 int err; 3580 int err;
3241 struct snd_kcontrol *kctl; 3581 struct snd_kcontrol *kctl;
3242 3582
3583 if (hdsp->io_type == RPM) {
3584 /* RPM Bypass, Disconnect and Input switches */
3585 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_rpm_controls); idx++) {
3586 err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp));
3587 if (err < 0)
3588 return err;
3589 }
3590 return 0;
3591 }
3592
3243 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) { 3593 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
3244 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) 3594 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
3245 return err; 3595 return err;
@@ -3459,48 +3809,102 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3459 3809
3460 snd_iprintf(buffer, "\n"); 3810 snd_iprintf(buffer, "\n");
3461 3811
3462 switch (hdsp_spdif_in(hdsp)) { 3812 if (hdsp->io_type != RPM) {
3463 case HDSP_SPDIFIN_OPTICAL: 3813 switch (hdsp_spdif_in(hdsp)) {
3464 snd_iprintf(buffer, "IEC958 input: Optical\n"); 3814 case HDSP_SPDIFIN_OPTICAL:
3465 break; 3815 snd_iprintf(buffer, "IEC958 input: Optical\n");
3466 case HDSP_SPDIFIN_COAXIAL: 3816 break;
3467 snd_iprintf(buffer, "IEC958 input: Coaxial\n"); 3817 case HDSP_SPDIFIN_COAXIAL:
3468 break; 3818 snd_iprintf(buffer, "IEC958 input: Coaxial\n");
3469 case HDSP_SPDIFIN_INTERNAL: 3819 break;
3470 snd_iprintf(buffer, "IEC958 input: Internal\n"); 3820 case HDSP_SPDIFIN_INTERNAL:
3471 break; 3821 snd_iprintf(buffer, "IEC958 input: Internal\n");
3472 case HDSP_SPDIFIN_AES: 3822 break;
3473 snd_iprintf(buffer, "IEC958 input: AES\n"); 3823 case HDSP_SPDIFIN_AES:
3474 break; 3824 snd_iprintf(buffer, "IEC958 input: AES\n");
3475 default: 3825 break;
3476 snd_iprintf(buffer, "IEC958 input: ???\n"); 3826 default:
3477 break; 3827 snd_iprintf(buffer, "IEC958 input: ???\n");
3828 break;
3829 }
3478 } 3830 }
3479 3831
3480 if (hdsp->control_register & HDSP_SPDIFOpticalOut) 3832 if (RPM == hdsp->io_type) {
3481 snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n"); 3833 if (hdsp->control_register & HDSP_RPM_Bypass)
3482 else 3834 snd_iprintf(buffer, "RPM Bypass: disabled\n");
3483 snd_iprintf(buffer, "IEC958 output: Coaxial only\n"); 3835 else
3836 snd_iprintf(buffer, "RPM Bypass: enabled\n");
3837 if (hdsp->control_register & HDSP_RPM_Disconnect)
3838 snd_iprintf(buffer, "RPM disconnected\n");
3839 else
3840 snd_iprintf(buffer, "RPM connected\n");
3484 3841
3485 if (hdsp->control_register & HDSP_SPDIFProfessional) 3842 switch (hdsp->control_register & HDSP_RPM_Inp12) {
3486 snd_iprintf(buffer, "IEC958 quality: Professional\n"); 3843 case HDSP_RPM_Inp12_Phon_6dB:
3487 else 3844 snd_iprintf(buffer, "Input 1/2: Phono, 6dB\n");
3488 snd_iprintf(buffer, "IEC958 quality: Consumer\n"); 3845 break;
3846 case HDSP_RPM_Inp12_Phon_0dB:
3847 snd_iprintf(buffer, "Input 1/2: Phono, 0dB\n");
3848 break;
3849 case HDSP_RPM_Inp12_Phon_n6dB:
3850 snd_iprintf(buffer, "Input 1/2: Phono, -6dB\n");
3851 break;
3852 case HDSP_RPM_Inp12_Line_0dB:
3853 snd_iprintf(buffer, "Input 1/2: Line, 0dB\n");
3854 break;
3855 case HDSP_RPM_Inp12_Line_n6dB:
3856 snd_iprintf(buffer, "Input 1/2: Line, -6dB\n");
3857 break;
3858 default:
3859 snd_iprintf(buffer, "Input 1/2: ???\n");
3860 }
3489 3861
3490 if (hdsp->control_register & HDSP_SPDIFEmphasis) 3862 switch (hdsp->control_register & HDSP_RPM_Inp34) {
3491 snd_iprintf(buffer, "IEC958 emphasis: on\n"); 3863 case HDSP_RPM_Inp34_Phon_6dB:
3492 else 3864 snd_iprintf(buffer, "Input 3/4: Phono, 6dB\n");
3493 snd_iprintf(buffer, "IEC958 emphasis: off\n"); 3865 break;
3866 case HDSP_RPM_Inp34_Phon_0dB:
3867 snd_iprintf(buffer, "Input 3/4: Phono, 0dB\n");
3868 break;
3869 case HDSP_RPM_Inp34_Phon_n6dB:
3870 snd_iprintf(buffer, "Input 3/4: Phono, -6dB\n");
3871 break;
3872 case HDSP_RPM_Inp34_Line_0dB:
3873 snd_iprintf(buffer, "Input 3/4: Line, 0dB\n");
3874 break;
3875 case HDSP_RPM_Inp34_Line_n6dB:
3876 snd_iprintf(buffer, "Input 3/4: Line, -6dB\n");
3877 break;
3878 default:
3879 snd_iprintf(buffer, "Input 3/4: ???\n");
3880 }
3494 3881
3495 if (hdsp->control_register & HDSP_SPDIFNonAudio) 3882 } else {
3496 snd_iprintf(buffer, "IEC958 NonAudio: on\n"); 3883 if (hdsp->control_register & HDSP_SPDIFOpticalOut)
3497 else 3884 snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
3498 snd_iprintf(buffer, "IEC958 NonAudio: off\n"); 3885 else
3499 if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) 3886 snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
3500 snd_iprintf (buffer, "IEC958 sample rate: %d\n", x); 3887
3501 else 3888 if (hdsp->control_register & HDSP_SPDIFProfessional)
3502 snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n"); 3889 snd_iprintf(buffer, "IEC958 quality: Professional\n");
3890 else
3891 snd_iprintf(buffer, "IEC958 quality: Consumer\n");
3892
3893 if (hdsp->control_register & HDSP_SPDIFEmphasis)
3894 snd_iprintf(buffer, "IEC958 emphasis: on\n");
3895 else
3896 snd_iprintf(buffer, "IEC958 emphasis: off\n");
3503 3897
3898 if (hdsp->control_register & HDSP_SPDIFNonAudio)
3899 snd_iprintf(buffer, "IEC958 NonAudio: on\n");
3900 else
3901 snd_iprintf(buffer, "IEC958 NonAudio: off\n");
3902 x = hdsp_spdif_sample_rate(hdsp);
3903 if (x != 0)
3904 snd_iprintf(buffer, "IEC958 sample rate: %d\n", x);
3905 else
3906 snd_iprintf(buffer, "IEC958 sample rate: Error flag set\n");
3907 }
3504 snd_iprintf(buffer, "\n"); 3908 snd_iprintf(buffer, "\n");
3505 3909
3506 /* Sync Check */ 3910 /* Sync Check */
@@ -3765,7 +4169,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id)
3765 snd_hdsp_midi_input_read (&hdsp->midi[0]); 4169 snd_hdsp_midi_input_read (&hdsp->midi[0]);
3766 } 4170 }
3767 } 4171 }
3768 if (hdsp->io_type != Multiface && hdsp->io_type != H9632 && midi1 && midi1status) { 4172 if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) {
3769 if (hdsp->use_midi_tasklet) { 4173 if (hdsp->use_midi_tasklet) {
3770 /* we disable interrupts for this input until processing is done */ 4174 /* we disable interrupts for this input until processing is done */
3771 hdsp->control_register &= ~HDSP_Midi1InterruptEnable; 4175 hdsp->control_register &= ~HDSP_Midi1InterruptEnable;
@@ -4093,7 +4497,7 @@ static struct snd_pcm_hardware snd_hdsp_playback_subinfo =
4093 SNDRV_PCM_RATE_96000), 4497 SNDRV_PCM_RATE_96000),
4094 .rate_min = 32000, 4498 .rate_min = 32000,
4095 .rate_max = 96000, 4499 .rate_max = 96000,
4096 .channels_min = 14, 4500 .channels_min = 6,
4097 .channels_max = HDSP_MAX_CHANNELS, 4501 .channels_max = HDSP_MAX_CHANNELS,
4098 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, 4502 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
4099 .period_bytes_min = (64 * 4) * 10, 4503 .period_bytes_min = (64 * 4) * 10,
@@ -4122,7 +4526,7 @@ static struct snd_pcm_hardware snd_hdsp_capture_subinfo =
4122 SNDRV_PCM_RATE_96000), 4526 SNDRV_PCM_RATE_96000),
4123 .rate_min = 32000, 4527 .rate_min = 32000,
4124 .rate_max = 96000, 4528 .rate_max = 96000,
4125 .channels_min = 14, 4529 .channels_min = 5,
4126 .channels_max = HDSP_MAX_CHANNELS, 4530 .channels_max = HDSP_MAX_CHANNELS,
4127 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, 4531 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
4128 .period_bytes_min = (64 * 4) * 10, 4532 .period_bytes_min = (64 * 4) * 10,
@@ -4357,10 +4761,12 @@ static int snd_hdsp_playback_open(struct snd_pcm_substream *substream)
4357 snd_hdsp_hw_rule_rate_out_channels, hdsp, 4761 snd_hdsp_hw_rule_rate_out_channels, hdsp,
4358 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 4762 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4359 4763
4360 hdsp->creg_spdif_stream = hdsp->creg_spdif; 4764 if (RPM != hdsp->io_type) {
4361 hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 4765 hdsp->creg_spdif_stream = hdsp->creg_spdif;
4362 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | 4766 hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
4363 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); 4767 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
4768 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
4769 }
4364 return 0; 4770 return 0;
4365} 4771}
4366 4772
@@ -4375,9 +4781,11 @@ static int snd_hdsp_playback_release(struct snd_pcm_substream *substream)
4375 4781
4376 spin_unlock_irq(&hdsp->lock); 4782 spin_unlock_irq(&hdsp->lock);
4377 4783
4378 hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 4784 if (RPM != hdsp->io_type) {
4379 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | 4785 hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
4380 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); 4786 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
4787 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
4788 }
4381 return 0; 4789 return 0;
4382} 4790}
4383 4791
@@ -4616,7 +5024,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
4616 if (hdsp->io_type != H9632) 5024 if (hdsp->io_type != H9632)
4617 info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp); 5025 info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
4618 info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp); 5026 info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
4619 for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) 5027 for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i)
4620 info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); 5028 info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
4621 info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); 5029 info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
4622 info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp); 5030 info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
@@ -4636,6 +5044,9 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
4636 info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); 5044 info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
4637 info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp); 5045 info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
4638 5046
5047 } else if (hdsp->io_type == RPM) {
5048 info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp);
5049 info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp);
4639 } 5050 }
4640 if (hdsp->io_type == H9632 || hdsp->io_type == H9652) 5051 if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
4641 info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp); 5052 info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
@@ -4844,6 +5255,14 @@ static void snd_hdsp_initialize_channels(struct hdsp *hdsp)
4844 hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS; 5255 hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS;
4845 break; 5256 break;
4846 5257
5258 case RPM:
5259 hdsp->card_name = "RME Hammerfall DSP + RPM";
5260 hdsp->ss_in_channels = RPM_CHANNELS-1;
5261 hdsp->ss_out_channels = RPM_CHANNELS;
5262 hdsp->ds_in_channels = RPM_CHANNELS-1;
5263 hdsp->ds_out_channels = RPM_CHANNELS;
5264 break;
5265
4847 default: 5266 default:
4848 /* should never get here */ 5267 /* should never get here */
4849 break; 5268 break;
@@ -4930,6 +5349,9 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
4930 5349
4931 /* caution: max length of firmware filename is 30! */ 5350 /* caution: max length of firmware filename is 30! */
4932 switch (hdsp->io_type) { 5351 switch (hdsp->io_type) {
5352 case RPM:
5353 fwfile = "rpm_firmware.bin";
5354 break;
4933 case Multiface: 5355 case Multiface:
4934 if (hdsp->firmware_rev == 0xa) 5356 if (hdsp->firmware_rev == 0xa)
4935 fwfile = "multiface_firmware.bin"; 5357 fwfile = "multiface_firmware.bin";
@@ -5100,7 +5522,9 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
5100 return 0; 5522 return 0;
5101 } else { 5523 } else {
5102 snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n"); 5524 snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");
5103 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) 5525 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
5526 hdsp->io_type = RPM;
5527 else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
5104 hdsp->io_type = Multiface; 5528 hdsp->io_type = Multiface;
5105 else 5529 else
5106 hdsp->io_type = Digiface; 5530 hdsp->io_type = Digiface;
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 5518371db13f..c94c051ad0c8 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1389,15 +1389,9 @@ static struct snd_kcontrol_new snd_ymfpci_spdif_stream __devinitdata =
1389 1389
1390static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info) 1390static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info)
1391{ 1391{
1392 static char *texts[3] = {"AC'97", "IEC958", "ZV Port"}; 1392 static const char *const texts[3] = {"AC'97", "IEC958", "ZV Port"};
1393 1393
1394 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1394 return snd_ctl_enum_info(info, 1, 3, texts);
1395 info->count = 1;
1396 info->value.enumerated.items = 3;
1397 if (info->value.enumerated.item > 2)
1398 info->value.enumerated.item = 2;
1399 strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
1400 return 0;
1401} 1395}
1402 1396
1403static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) 1397static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value)
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 3e598e756e54..a3efc52a34da 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -20,6 +20,21 @@ menuconfig SND_SOC
20 20
21if SND_SOC 21if SND_SOC
22 22
23config SND_SOC_CACHE_LZO
24 bool "Support LZO compression for register caches"
25 select LZO_COMPRESS
26 select LZO_DECOMPRESS
27 ---help---
28 Select this to enable LZO compression for register caches.
29 This will allow machine or CODEC drivers to compress register
30 caches in memory, reducing the memory consumption at the
31 expense of performance. If this is not present and is used
32 the system will fall back to uncompressed caches.
33
34 Usually it is safe to disable this option, where cache
35 compression in used the rbtree option will typically perform
36 better.
37
23config SND_SOC_AC97_BUS 38config SND_SOC_AC97_BUS
24 bool 39 bool
25 40
@@ -36,7 +51,7 @@ source "sound/soc/nuc900/Kconfig"
36source "sound/soc/omap/Kconfig" 51source "sound/soc/omap/Kconfig"
37source "sound/soc/kirkwood/Kconfig" 52source "sound/soc/kirkwood/Kconfig"
38source "sound/soc/pxa/Kconfig" 53source "sound/soc/pxa/Kconfig"
39source "sound/soc/s3c24xx/Kconfig" 54source "sound/soc/samsung/Kconfig"
40source "sound/soc/s6000/Kconfig" 55source "sound/soc/s6000/Kconfig"
41source "sound/soc/sh/Kconfig" 56source "sound/soc/sh/Kconfig"
42source "sound/soc/txx9/Kconfig" 57source "sound/soc/txx9/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index eb183443eee4..ce913bf5213c 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -14,7 +14,7 @@ obj-$(CONFIG_SND_SOC) += nuc900/
14obj-$(CONFIG_SND_SOC) += omap/ 14obj-$(CONFIG_SND_SOC) += omap/
15obj-$(CONFIG_SND_SOC) += kirkwood/ 15obj-$(CONFIG_SND_SOC) += kirkwood/
16obj-$(CONFIG_SND_SOC) += pxa/ 16obj-$(CONFIG_SND_SOC) += pxa/
17obj-$(CONFIG_SND_SOC) += s3c24xx/ 17obj-$(CONFIG_SND_SOC) += samsung/
18obj-$(CONFIG_SND_SOC) += s6000/ 18obj-$(CONFIG_SND_SOC) += s6000/
19obj-$(CONFIG_SND_SOC) += sh/ 19obj-$(CONFIG_SND_SOC) += sh/
20obj-$(CONFIG_SND_SOC) += txx9/ 20obj-$(CONFIG_SND_SOC) += txx9/
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c
index 5f4e59f4461c..1aac2f4dbcf6 100644
--- a/sound/soc/atmel/playpaq_wm8510.c
+++ b/sound/soc/atmel/playpaq_wm8510.c
@@ -33,7 +33,6 @@
33#include <sound/pcm.h> 33#include <sound/pcm.h>
34#include <sound/pcm_params.h> 34#include <sound/pcm_params.h>
35#include <sound/soc.h> 35#include <sound/soc.h>
36#include <sound/soc-dapm.h>
37 36
38#include <mach/at32ap700x.h> 37#include <mach/at32ap700x.h>
39#include <mach/portmux.h> 38#include <mach/portmux.h>
@@ -318,27 +317,28 @@ static const struct snd_soc_dapm_route intercon[] = {
318static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd) 317static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd)
319{ 318{
320 struct snd_soc_codec *codec = rtd->codec; 319 struct snd_soc_codec *codec = rtd->codec;
320 struct snd_soc_dapm_context *dapm = &codec->dapm;
321 int i; 321 int i;
322 322
323 /* 323 /*
324 * Add DAPM widgets 324 * Add DAPM widgets
325 */ 325 */
326 for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++) 326 for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++)
327 snd_soc_dapm_new_control(codec, &playpaq_dapm_widgets[i]); 327 snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]);
328 328
329 329
330 330
331 /* 331 /*
332 * Setup audio path interconnects 332 * Setup audio path interconnects
333 */ 333 */
334 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 334 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
335 335
336 336
337 337
338 /* always connected pins */ 338 /* always connected pins */
339 snd_soc_dapm_enable_pin(codec, "Int Mic"); 339 snd_soc_dapm_enable_pin(dapm, "Int Mic");
340 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 340 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
341 snd_soc_dapm_sync(codec); 341 snd_soc_dapm_sync(dapm);
342 342
343 343
344 344
diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c
index e521ada80542..af3c73053ee4 100644
--- a/sound/soc/atmel/sam9g20_wm8731.c
+++ b/sound/soc/atmel/sam9g20_wm8731.c
@@ -44,7 +44,6 @@
44#include <sound/pcm.h> 44#include <sound/pcm.h>
45#include <sound/pcm_params.h> 45#include <sound/pcm_params.h>
46#include <sound/soc.h> 46#include <sound/soc.h>
47#include <sound/soc-dapm.h>
48 47
49#include <asm/mach-types.h> 48#include <asm/mach-types.h>
50#include <mach/hardware.h> 49#include <mach/hardware.h>
@@ -140,6 +139,7 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
140{ 139{
141 struct snd_soc_codec *codec = rtd->codec; 140 struct snd_soc_codec *codec = rtd->codec;
142 struct snd_soc_dai *codec_dai = rtd->codec_dai; 141 struct snd_soc_dai *codec_dai = rtd->codec_dai;
142 struct snd_soc_dapm_context *dapm = &codec->dapm;
143 int ret; 143 int ret;
144 144
145 printk(KERN_DEBUG 145 printk(KERN_DEBUG
@@ -154,25 +154,25 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd)
154 } 154 }
155 155
156 /* Add specific widgets */ 156 /* Add specific widgets */
157 snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets, 157 snd_soc_dapm_new_controls(dapm, at91sam9g20ek_dapm_widgets,
158 ARRAY_SIZE(at91sam9g20ek_dapm_widgets)); 158 ARRAY_SIZE(at91sam9g20ek_dapm_widgets));
159 /* Set up specific audio path interconnects */ 159 /* Set up specific audio path interconnects */
160 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 160 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
161 161
162 /* not connected */ 162 /* not connected */
163 snd_soc_dapm_nc_pin(codec, "RLINEIN"); 163 snd_soc_dapm_nc_pin(dapm, "RLINEIN");
164 snd_soc_dapm_nc_pin(codec, "LLINEIN"); 164 snd_soc_dapm_nc_pin(dapm, "LLINEIN");
165 165
166#ifdef ENABLE_MIC_INPUT 166#ifdef ENABLE_MIC_INPUT
167 snd_soc_dapm_enable_pin(codec, "Int Mic"); 167 snd_soc_dapm_enable_pin(dapm, "Int Mic");
168#else 168#else
169 snd_soc_dapm_nc_pin(codec, "Int Mic"); 169 snd_soc_dapm_nc_pin(dapm, "Int Mic");
170#endif 170#endif
171 171
172 /* always connected */ 172 /* always connected */
173 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 173 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
174 174
175 snd_soc_dapm_sync(codec); 175 snd_soc_dapm_sync(dapm);
176 176
177 return 0; 177 return 0;
178} 178}
diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c
index 86e0f8586dc3..da2208e06b0d 100644
--- a/sound/soc/atmel/snd-soc-afeb9260.c
+++ b/sound/soc/atmel/snd-soc-afeb9260.c
@@ -30,7 +30,6 @@
30#include <sound/pcm.h> 30#include <sound/pcm.h>
31#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34 33
35#include <asm/mach-types.h> 34#include <asm/mach-types.h>
36#include <mach/hardware.h> 35#include <mach/hardware.h>
@@ -105,19 +104,20 @@ static const struct snd_soc_dapm_route audio_map[] = {
105static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) 104static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
106{ 105{
107 struct snd_soc_codec *codec = rtd->codec; 106 struct snd_soc_codec *codec = rtd->codec;
107 struct snd_soc_dapm_context *dapm = &codec->dapm;
108 108
109 /* Add afeb9260 specific widgets */ 109 /* Add afeb9260 specific widgets */
110 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 110 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
111 ARRAY_SIZE(tlv320aic23_dapm_widgets)); 111 ARRAY_SIZE(tlv320aic23_dapm_widgets));
112 112
113 /* Set up afeb9260 specific audio path audio_map */ 113 /* Set up afeb9260 specific audio path audio_map */
114 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 114 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
115 115
116 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 116 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
117 snd_soc_dapm_enable_pin(codec, "Line In"); 117 snd_soc_dapm_enable_pin(dapm, "Line In");
118 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 118 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
119 119
120 snd_soc_dapm_sync(codec); 120 snd_soc_dapm_sync(dapm);
121 121
122 return 0; 122 return 0;
123} 123}
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index b62fcd33e586..cb99f04abe88 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -13,7 +13,6 @@
13#include <sound/core.h> 13#include <sound/core.h>
14#include <sound/pcm.h> 14#include <sound/pcm.h>
15#include <sound/soc.h> 15#include <sound/soc.h>
16#include <sound/soc-dapm.h>
17#include <asm/mach-au1x00/au1000.h> 16#include <asm/mach-au1x00/au1000.h>
18#include <asm/mach-au1x00/au1xxx_psc.h> 17#include <asm/mach-au1x00/au1xxx_psc.h>
19#include <asm/mach-au1x00/au1xxx_dbdma.h> 18#include <asm/mach-au1x00/au1xxx_dbdma.h>
diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c
index 2394bff2b655..83012da9dfc2 100644
--- a/sound/soc/blackfin/bf5xx-ad1836.c
+++ b/sound/soc/blackfin/bf5xx-ad1836.c
@@ -20,7 +20,6 @@
20#include <sound/core.h> 20#include <sound/core.h>
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
25 24
26#include <asm/blackfin.h> 25#include <asm/blackfin.h>
diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c
index e4a625317a1a..d3ccb926b5e4 100644
--- a/sound/soc/blackfin/bf5xx-ad193x.c
+++ b/sound/soc/blackfin/bf5xx-ad193x.c
@@ -29,7 +29,6 @@
29#include <sound/core.h> 29#include <sound/core.h>
30#include <sound/pcm.h> 30#include <sound/pcm.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/pcm_params.h> 32#include <sound/pcm_params.h>
34 33
35#include <asm/blackfin.h> 34#include <asm/blackfin.h>
diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c
index 900ced54ac79..732fb8bad076 100644
--- a/sound/soc/blackfin/bf5xx-ad73311.c
+++ b/sound/soc/blackfin/bf5xx-ad73311.c
@@ -35,7 +35,6 @@
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/pcm.h> 36#include <sound/pcm.h>
37#include <sound/soc.h> 37#include <sound/soc.h>
38#include <sound/soc-dapm.h>
39#include <sound/pcm_params.h> 38#include <sound/pcm_params.h>
40 39
41#include <asm/blackfin.h> 40#include <asm/blackfin.h>
diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c
index 36f2769eb912..e902b24c1856 100644
--- a/sound/soc/blackfin/bf5xx-ssm2602.c
+++ b/sound/soc/blackfin/bf5xx-ssm2602.c
@@ -33,7 +33,6 @@
33#include <sound/core.h> 33#include <sound/core.h>
34#include <sound/pcm.h> 34#include <sound/pcm.h>
35#include <sound/soc.h> 35#include <sound/soc.h>
36#include <sound/soc-dapm.h>
37#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
38 37
39#include <asm/dma.h> 38#include <asm/dma.h>
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 01d19e9f53f9..06b6981b8d6d 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -19,10 +19,10 @@
19#include <sound/pcm.h> 19#include <sound/pcm.h>
20#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23#include <sound/tlv.h> 22#include <sound/tlv.h>
24#include <sound/initval.h> 23#include <sound/initval.h>
25#include <sound/jack.h> 24#include <sound/jack.h>
25#include <trace/events/asoc.h>
26 26
27#include "88pm860x-codec.h" 27#include "88pm860x-codec.h"
28 28
@@ -146,7 +146,6 @@ struct pm860x_priv {
146 146
147 int irq[4]; 147 int irq[4];
148 unsigned char name[4][MAX_NAME_LEN]; 148 unsigned char name[4][MAX_NAME_LEN];
149 unsigned char reg_cache[REG_CACHE_SIZE];
150}; 149};
151 150
152/* -9450dB to 0dB in 150dB steps ( mute instead of -9450dB) */ 151/* -9450dB to 0dB in 150dB steps ( mute instead of -9450dB) */
@@ -1172,7 +1171,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
1172 break; 1171 break;
1173 1172
1174 case SND_SOC_BIAS_STANDBY: 1173 case SND_SOC_BIAS_STANDBY:
1175 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1174 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1176 /* Enable Audio PLL & Audio section */ 1175 /* Enable Audio PLL & Audio section */
1177 data = AUDIO_PLL | AUDIO_SECTION_RESET 1176 data = AUDIO_PLL | AUDIO_SECTION_RESET
1178 | AUDIO_SECTION_ON; 1177 | AUDIO_SECTION_ON;
@@ -1185,7 +1184,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
1185 pm860x_set_bits(codec->control_data, REG_MISC2, data, 0); 1184 pm860x_set_bits(codec->control_data, REG_MISC2, data, 0);
1186 break; 1185 break;
1187 } 1186 }
1188 codec->bias_level = level; 1187 codec->dapm.bias_level = level;
1189 return 0; 1188 return 0;
1190} 1189}
1191 1190
@@ -1263,6 +1262,12 @@ static irqreturn_t pm860x_codec_handler(int irq, void *data)
1263 mask = pm860x->det.hs_shrt | pm860x->det.hook_det | pm860x->det.lo_shrt 1262 mask = pm860x->det.hs_shrt | pm860x->det.hook_det | pm860x->det.lo_shrt
1264 | pm860x->det.hp_det; 1263 | pm860x->det.hp_det;
1265 1264
1265#ifndef CONFIG_SND_SOC_88PM860X_MODULE
1266 if (status & (HEADSET_STATUS | MIC_STATUS | SHORT_HS1 | SHORT_HS2 |
1267 SHORT_LO1 | SHORT_LO2))
1268 trace_snd_soc_jack_irq(dev_name(pm860x->codec->dev));
1269#endif
1270
1266 if ((pm860x->det.hp_det & SND_JACK_HEADPHONE) 1271 if ((pm860x->det.hp_det & SND_JACK_HEADPHONE)
1267 && (status & HEADSET_STATUS)) 1272 && (status & HEADSET_STATUS))
1268 report |= SND_JACK_HEADPHONE; 1273 report |= SND_JACK_HEADPHONE;
@@ -1346,6 +1351,7 @@ EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect);
1346static int pm860x_probe(struct snd_soc_codec *codec) 1351static int pm860x_probe(struct snd_soc_codec *codec)
1347{ 1352{
1348 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec); 1353 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1354 struct snd_soc_dapm_context *dapm = &codec->dapm;
1349 int i, ret; 1355 int i, ret;
1350 1356
1351 pm860x->codec = codec; 1357 pm860x->codec = codec;
@@ -1358,7 +1364,7 @@ static int pm860x_probe(struct snd_soc_codec *codec)
1358 pm860x->name[i], pm860x); 1364 pm860x->name[i], pm860x);
1359 if (ret < 0) { 1365 if (ret < 0) {
1360 dev_err(codec->dev, "Failed to request IRQ!\n"); 1366 dev_err(codec->dev, "Failed to request IRQ!\n");
1361 goto out_irq; 1367 goto out;
1362 } 1368 }
1363 } 1369 }
1364 1370
@@ -1369,22 +1375,20 @@ static int pm860x_probe(struct snd_soc_codec *codec)
1369 if (ret < 0) { 1375 if (ret < 0) {
1370 dev_err(codec->dev, "Failed to fill register cache: %d\n", 1376 dev_err(codec->dev, "Failed to fill register cache: %d\n",
1371 ret); 1377 ret);
1372 goto out_codec; 1378 goto out;
1373 } 1379 }
1374 1380
1375 snd_soc_add_controls(codec, pm860x_snd_controls, 1381 snd_soc_add_controls(codec, pm860x_snd_controls,
1376 ARRAY_SIZE(pm860x_snd_controls)); 1382 ARRAY_SIZE(pm860x_snd_controls));
1377 snd_soc_dapm_new_controls(codec, pm860x_dapm_widgets, 1383 snd_soc_dapm_new_controls(dapm, pm860x_dapm_widgets,
1378 ARRAY_SIZE(pm860x_dapm_widgets)); 1384 ARRAY_SIZE(pm860x_dapm_widgets));
1379 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 1385 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
1380 return 0; 1386 return 0;
1381 1387
1382out_codec: 1388out:
1383 i = 3; 1389 while (--i >= 0)
1384out_irq:
1385 for (; i >= 0; i--)
1386 free_irq(pm860x->irq[i], pm860x); 1390 free_irq(pm860x->irq[i], pm860x);
1387 return -EINVAL; 1391 return ret;
1388} 1392}
1389 1393
1390static int pm860x_remove(struct snd_soc_codec *codec) 1394static int pm860x_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 3b5690d28b8b..883a312bb293 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -22,6 +22,7 @@ config SND_SOC_ALL_CODECS
22 select SND_SOC_AK4535 if I2C 22 select SND_SOC_AK4535 if I2C
23 select SND_SOC_AK4642 if I2C 23 select SND_SOC_AK4642 if I2C
24 select SND_SOC_AK4671 if I2C 24 select SND_SOC_AK4671 if I2C
25 select SND_SOC_ALC5623 if I2C
25 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC 26 select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
26 select SND_SOC_CS42L51 if I2C 27 select SND_SOC_CS42L51 if I2C
27 select SND_SOC_CS4270 if I2C 28 select SND_SOC_CS4270 if I2C
@@ -54,9 +55,11 @@ config SND_SOC_ALL_CODECS
54 select SND_SOC_WM8727 55 select SND_SOC_WM8727
55 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI 56 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI
56 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI 57 select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI
58 select SND_SOC_WM8737 if SND_SOC_I2C_AND_SPI
57 select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI 59 select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI
58 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI 60 select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI
59 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI 61 select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI
62 select SND_SOC_WM8770 if SPI_MASTER
60 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI 63 select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI
61 select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI 64 select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI
62 select SND_SOC_WM8900 if I2C 65 select SND_SOC_WM8900 if I2C
@@ -75,6 +78,7 @@ config SND_SOC_ALL_CODECS
75 select SND_SOC_WM8990 if I2C 78 select SND_SOC_WM8990 if I2C
76 select SND_SOC_WM8993 if I2C 79 select SND_SOC_WM8993 if I2C
77 select SND_SOC_WM8994 if MFD_WM8994 80 select SND_SOC_WM8994 if MFD_WM8994
81 select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI
78 select SND_SOC_WM9081 if I2C 82 select SND_SOC_WM9081 if I2C
79 select SND_SOC_WM9090 if I2C 83 select SND_SOC_WM9090 if I2C
80 select SND_SOC_WM9705 if SND_SOC_AC97_BUS 84 select SND_SOC_WM9705 if SND_SOC_AC97_BUS
@@ -130,6 +134,9 @@ config SND_SOC_AK4642
130config SND_SOC_AK4671 134config SND_SOC_AK4671
131 tristate 135 tristate
132 136
137config SND_SOC_ALC5623
138 tristate
139
133config SND_SOC_CQ0093VC 140config SND_SOC_CQ0093VC
134 tristate 141 tristate
135 142
@@ -160,6 +167,9 @@ config SND_SOC_L3
160config SND_SOC_DA7210 167config SND_SOC_DA7210
161 tristate 168 tristate
162 169
170config SND_SOC_DMIC
171 tristate
172
163config SND_SOC_MAX98088 173config SND_SOC_MAX98088
164 tristate 174 tristate
165 175
@@ -231,6 +241,9 @@ config SND_SOC_WM8728
231config SND_SOC_WM8731 241config SND_SOC_WM8731
232 tristate 242 tristate
233 243
244config SND_SOC_WM8737
245 tristate
246
234config SND_SOC_WM8741 247config SND_SOC_WM8741
235 tristate 248 tristate
236 249
@@ -240,6 +253,9 @@ config SND_SOC_WM8750
240config SND_SOC_WM8753 253config SND_SOC_WM8753
241 tristate 254 tristate
242 255
256config SND_SOC_WM8770
257 tristate
258
243config SND_SOC_WM8776 259config SND_SOC_WM8776
244 tristate 260 tristate
245 261
@@ -294,6 +310,9 @@ config SND_SOC_WM8993
294config SND_SOC_WM8994 310config SND_SOC_WM8994
295 tristate 311 tristate
296 312
313config SND_SOC_WM8995
314 tristate
315
297config SND_SOC_WM9081 316config SND_SOC_WM9081
298 tristate 317 tristate
299 318
@@ -318,3 +337,4 @@ config SND_SOC_WM2000
318 337
319config SND_SOC_WM9090 338config SND_SOC_WM9090
320 tristate 339 tristate
340
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f67a2d6f7a46..579af9c4f128 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -14,9 +14,11 @@ snd-soc-cs42l51-objs := cs42l51.o
14snd-soc-cs4270-objs := cs4270.o 14snd-soc-cs4270-objs := cs4270.o
15snd-soc-cx20442-objs := cx20442.o 15snd-soc-cx20442-objs := cx20442.o
16snd-soc-da7210-objs := da7210.o 16snd-soc-da7210-objs := da7210.o
17snd-soc-dmic-objs := dmic.o
17snd-soc-l3-objs := l3.o 18snd-soc-l3-objs := l3.o
18snd-soc-max98088-objs := max98088.o 19snd-soc-max98088-objs := max98088.o
19snd-soc-pcm3008-objs := pcm3008.o 20snd-soc-pcm3008-objs := pcm3008.o
21snd-soc-alc5623-objs := alc5623.o
20snd-soc-spdif-objs := spdif_transciever.o 22snd-soc-spdif-objs := spdif_transciever.o
21snd-soc-ssm2602-objs := ssm2602.o 23snd-soc-ssm2602-objs := ssm2602.o
22snd-soc-stac9766-objs := stac9766.o 24snd-soc-stac9766-objs := stac9766.o
@@ -38,9 +40,11 @@ snd-soc-wm8711-objs := wm8711.o
38snd-soc-wm8727-objs := wm8727.o 40snd-soc-wm8727-objs := wm8727.o
39snd-soc-wm8728-objs := wm8728.o 41snd-soc-wm8728-objs := wm8728.o
40snd-soc-wm8731-objs := wm8731.o 42snd-soc-wm8731-objs := wm8731.o
43snd-soc-wm8737-objs := wm8737.o
41snd-soc-wm8741-objs := wm8741.o 44snd-soc-wm8741-objs := wm8741.o
42snd-soc-wm8750-objs := wm8750.o 45snd-soc-wm8750-objs := wm8750.o
43snd-soc-wm8753-objs := wm8753.o 46snd-soc-wm8753-objs := wm8753.o
47snd-soc-wm8770-objs := wm8770.o
44snd-soc-wm8776-objs := wm8776.o 48snd-soc-wm8776-objs := wm8776.o
45snd-soc-wm8804-objs := wm8804.o 49snd-soc-wm8804-objs := wm8804.o
46snd-soc-wm8900-objs := wm8900.o 50snd-soc-wm8900-objs := wm8900.o
@@ -58,7 +62,8 @@ snd-soc-wm8985-objs := wm8985.o
58snd-soc-wm8988-objs := wm8988.o 62snd-soc-wm8988-objs := wm8988.o
59snd-soc-wm8990-objs := wm8990.o 63snd-soc-wm8990-objs := wm8990.o
60snd-soc-wm8993-objs := wm8993.o 64snd-soc-wm8993-objs := wm8993.o
61snd-soc-wm8994-objs := wm8994.o 65snd-soc-wm8994-objs := wm8994.o wm8994-tables.o
66snd-soc-wm8995-objs := wm8995.o
62snd-soc-wm9081-objs := wm9081.o 67snd-soc-wm9081-objs := wm9081.o
63snd-soc-wm9705-objs := wm9705.o 68snd-soc-wm9705-objs := wm9705.o
64snd-soc-wm9712-objs := wm9712.o 69snd-soc-wm9712-objs := wm9712.o
@@ -88,10 +93,12 @@ obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
88obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o 93obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
89obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 94obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
90obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 95obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
96obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
91obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 97obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
92obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 98obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
93obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o 99obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o
94obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 100obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
101obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
95obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 102obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o
96obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 103obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
97obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 104obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
@@ -113,9 +120,11 @@ obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o
113obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o 120obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o
114obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o 121obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o
115obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o 122obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o
123obj-$(CONFIG_SND_SOC_WM8737) += snd-soc-wm8737.o
116obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o 124obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o
117obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o 125obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o
118obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o 126obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o
127obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o
119obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o 128obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o
120obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o 129obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o
121obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o 130obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o
@@ -134,6 +143,7 @@ obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o
134obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o 143obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o
135obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o 144obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o
136obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o 145obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o
146obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o
137obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o 147obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o
138obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o 148obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
139obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o 149obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c
index d272534c8f84..ab63d52e36e1 100644
--- a/sound/soc/codecs/ad1836.c
+++ b/sound/soc/codecs/ad1836.c
@@ -27,7 +27,6 @@
27#include <sound/initval.h> 27#include <sound/initval.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/tlv.h> 29#include <sound/tlv.h>
30#include <sound/soc-dapm.h>
31#include <linux/spi/spi.h> 30#include <linux/spi/spi.h>
32#include "ad1836.h" 31#include "ad1836.h"
33 32
@@ -220,6 +219,7 @@ static struct snd_soc_dai_driver ad1836_dai = {
220static int ad1836_probe(struct snd_soc_codec *codec) 219static int ad1836_probe(struct snd_soc_codec *codec)
221{ 220{
222 struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec); 221 struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec);
222 struct snd_soc_dapm_context *dapm = &codec->dapm;
223 int ret = 0; 223 int ret = 0;
224 224
225 codec->control_data = ad1836->control_data; 225 codec->control_data = ad1836->control_data;
@@ -227,7 +227,6 @@ static int ad1836_probe(struct snd_soc_codec *codec)
227 if (ret < 0) { 227 if (ret < 0) {
228 dev_err(codec->dev, "failed to set cache I/O: %d\n", 228 dev_err(codec->dev, "failed to set cache I/O: %d\n",
229 ret); 229 ret);
230 kfree(ad1836);
231 return ret; 230 return ret;
232 } 231 }
233 232
@@ -252,9 +251,9 @@ static int ad1836_probe(struct snd_soc_codec *codec)
252 251
253 snd_soc_add_controls(codec, ad1836_snd_controls, 252 snd_soc_add_controls(codec, ad1836_snd_controls,
254 ARRAY_SIZE(ad1836_snd_controls)); 253 ARRAY_SIZE(ad1836_snd_controls));
255 snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets, 254 snd_soc_dapm_new_controls(dapm, ad1836_dapm_widgets,
256 ARRAY_SIZE(ad1836_dapm_widgets)); 255 ARRAY_SIZE(ad1836_dapm_widgets));
257 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 256 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
258 257
259 return ret; 258 return ret;
260} 259}
diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c
index fa2834c91b9f..da46479bfcfa 100644
--- a/sound/soc/codecs/ad193x.c
+++ b/sound/soc/codecs/ad193x.c
@@ -19,12 +19,10 @@
19#include <sound/initval.h> 19#include <sound/initval.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/tlv.h> 21#include <sound/tlv.h>
22#include <sound/soc-dapm.h>
23#include "ad193x.h" 22#include "ad193x.h"
24 23
25/* codec private data */ 24/* codec private data */
26struct ad193x_priv { 25struct ad193x_priv {
27 u8 reg_cache[AD193X_NUM_REGS];
28 enum snd_soc_control_type bus_type; 26 enum snd_soc_control_type bus_type;
29 void *control_data; 27 void *control_data;
30 int sysclk; 28 int sysclk;
@@ -353,6 +351,7 @@ static struct snd_soc_dai_driver ad193x_dai = {
353static int ad193x_probe(struct snd_soc_codec *codec) 351static int ad193x_probe(struct snd_soc_codec *codec)
354{ 352{
355 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); 353 struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec);
354 struct snd_soc_dapm_context *dapm = &codec->dapm;
356 int ret; 355 int ret;
357 356
358 codec->control_data = ad193x->control_data; 357 codec->control_data = ad193x->control_data;
@@ -363,7 +362,6 @@ static int ad193x_probe(struct snd_soc_codec *codec)
363 if (ret < 0) { 362 if (ret < 0) {
364 dev_err(codec->dev, "failed to set cache I/O: %d\n", 363 dev_err(codec->dev, "failed to set cache I/O: %d\n",
365 ret); 364 ret);
366 kfree(ad193x);
367 return ret; 365 return ret;
368 } 366 }
369 367
@@ -385,9 +383,9 @@ static int ad193x_probe(struct snd_soc_codec *codec)
385 383
386 snd_soc_add_controls(codec, ad193x_snd_controls, 384 snd_soc_add_controls(codec, ad193x_snd_controls,
387 ARRAY_SIZE(ad193x_snd_controls)); 385 ARRAY_SIZE(ad193x_snd_controls));
388 snd_soc_dapm_new_controls(codec, ad193x_dapm_widgets, 386 snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets,
389 ARRAY_SIZE(ad193x_dapm_widgets)); 387 ARRAY_SIZE(ad193x_dapm_widgets));
390 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 388 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
391 389
392 return ret; 390 return ret;
393} 391}
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c
index 410ccd5d41cd..34cb51ef2156 100644
--- a/sound/soc/codecs/ad1980.c
+++ b/sound/soc/codecs/ad1980.c
@@ -29,7 +29,6 @@
29#include <sound/ac97_codec.h> 29#include <sound/ac97_codec.h>
30#include <sound/initval.h> 30#include <sound/initval.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33 32
34#include "ad1980.h" 33#include "ad1980.h"
35 34
diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c
index cd88c8f32a38..8b38739c88f8 100644
--- a/sound/soc/codecs/ak4535.c
+++ b/sound/soc/codecs/ak4535.c
@@ -24,7 +24,6 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29 28
30#include "ak4535.h" 29#include "ak4535.h"
@@ -290,10 +289,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
290 289
291static int ak4535_add_widgets(struct snd_soc_codec *codec) 290static int ak4535_add_widgets(struct snd_soc_codec *codec)
292{ 291{
293 snd_soc_dapm_new_controls(codec, ak4535_dapm_widgets, 292 struct snd_soc_dapm_context *dapm = &codec->dapm;
294 ARRAY_SIZE(ak4535_dapm_widgets));
295 293
296 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 294 snd_soc_dapm_new_controls(dapm, ak4535_dapm_widgets,
295 ARRAY_SIZE(ak4535_dapm_widgets));
296 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
297 297
298 return 0; 298 return 0;
299} 299}
@@ -366,9 +366,9 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai,
366static int ak4535_mute(struct snd_soc_dai *dai, int mute) 366static int ak4535_mute(struct snd_soc_dai *dai, int mute)
367{ 367{
368 struct snd_soc_codec *codec = dai->codec; 368 struct snd_soc_codec *codec = dai->codec;
369 u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf; 369 u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
370 if (!mute) 370 if (!mute)
371 ak4535_write(codec, AK4535_DAC, mute_reg); 371 ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20);
372 else 372 else
373 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); 373 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
374 return 0; 374 return 0;
@@ -381,11 +381,11 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
381 381
382 switch (level) { 382 switch (level) {
383 case SND_SOC_BIAS_ON: 383 case SND_SOC_BIAS_ON:
384 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf; 384 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
385 ak4535_write(codec, AK4535_DAC, mute_reg); 385 ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20);
386 break; 386 break;
387 case SND_SOC_BIAS_PREPARE: 387 case SND_SOC_BIAS_PREPARE:
388 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf; 388 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC);
389 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); 389 ak4535_write(codec, AK4535_DAC, mute_reg | 0x20);
390 break; 390 break;
391 case SND_SOC_BIAS_STANDBY: 391 case SND_SOC_BIAS_STANDBY:
@@ -399,7 +399,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec,
399 ak4535_write(codec, AK4535_PM1, i & (~0x80)); 399 ak4535_write(codec, AK4535_PM1, i & (~0x80));
400 break; 400 break;
401 } 401 }
402 codec->bias_level = level; 402 codec->dapm.bias_level = level;
403 return 0; 403 return 0;
404} 404}
405 405
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 90c90b7f4a2e..f00eba313dfd 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -26,7 +26,7 @@
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <sound/soc-dapm.h> 29#include <sound/soc.h>
30#include <sound/initval.h> 30#include <sound/initval.h>
31#include <sound/tlv.h> 31#include <sound/tlv.h>
32 32
diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c
index 24f5f49bb9d2..2ec75abfa3e9 100644
--- a/sound/soc/codecs/ak4671.c
+++ b/sound/soc/codecs/ak4671.c
@@ -17,7 +17,6 @@
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <sound/initval.h> 20#include <sound/initval.h>
22#include <sound/tlv.h> 21#include <sound/tlv.h>
23 22
@@ -28,7 +27,6 @@
28struct ak4671_priv { 27struct ak4671_priv {
29 enum snd_soc_control_type control_type; 28 enum snd_soc_control_type control_type;
30 void *control_data; 29 void *control_data;
31 u8 reg_cache[AK4671_CACHEREGNUM];
32}; 30};
33 31
34/* ak4671 register cache & default register settings */ 32/* ak4671 register cache & default register settings */
@@ -437,10 +435,11 @@ static const struct snd_soc_dapm_route intercon[] = {
437 435
438static int ak4671_add_widgets(struct snd_soc_codec *codec) 436static int ak4671_add_widgets(struct snd_soc_codec *codec)
439{ 437{
440 snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets, 438 struct snd_soc_dapm_context *dapm = &codec->dapm;
441 ARRAY_SIZE(ak4671_dapm_widgets));
442 439
443 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 440 snd_soc_dapm_new_controls(dapm, ak4671_dapm_widgets,
441 ARRAY_SIZE(ak4671_dapm_widgets));
442 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
444 443
445 return 0; 444 return 0;
446} 445}
@@ -602,7 +601,7 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec,
602 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00); 601 snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00);
603 break; 602 break;
604 } 603 }
605 codec->bias_level = level; 604 codec->dapm.bias_level = level;
606 return 0; 605 return 0;
607} 606}
608 607
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
new file mode 100644
index 000000000000..4f377c9e868d
--- /dev/null
+++ b/sound/soc/codecs/alc5623.c
@@ -0,0 +1,1117 @@
1/*
2 * alc5623.c -- alc562[123] ALSA Soc Audio driver
3 *
4 * Copyright 2008 Realtek Microelectronics
5 * Author: flove <flove@realtek.com> Ethan <eku@marvell.com>
6 *
7 * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
8 *
9 *
10 * Based on WM8753.c
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
18#include <linux/module.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/delay.h>
22#include <linux/pm.h>
23#include <linux/i2c.h>
24#include <linux/slab.h>
25#include <linux/platform_device.h>
26#include <sound/core.h>
27#include <sound/pcm.h>
28#include <sound/pcm_params.h>
29#include <sound/tlv.h>
30#include <sound/soc.h>
31#include <sound/initval.h>
32#include <sound/alc5623.h>
33
34#include "alc5623.h"
35
36static int caps_charge = 2000;
37module_param(caps_charge, int, 0);
38MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)");
39
40/* codec private data */
41struct alc5623_priv {
42 enum snd_soc_control_type control_type;
43 void *control_data;
44 struct mutex mutex;
45 u8 id;
46 unsigned int sysclk;
47 u16 reg_cache[ALC5623_VENDOR_ID2+2];
48 unsigned int add_ctrl;
49 unsigned int jack_det_ctrl;
50};
51
52static void alc5623_fill_cache(struct snd_soc_codec *codec)
53{
54 int i, step = codec->driver->reg_cache_step;
55 u16 *cache = codec->reg_cache;
56
57 /* not really efficient ... */
58 for (i = 0 ; i < codec->driver->reg_cache_size ; i += step)
59 cache[i] = codec->hw_read(codec, i);
60}
61
62static inline int alc5623_reset(struct snd_soc_codec *codec)
63{
64 return snd_soc_write(codec, ALC5623_RESET, 0);
65}
66
67static int amp_mixer_event(struct snd_soc_dapm_widget *w,
68 struct snd_kcontrol *kcontrol, int event)
69{
70 /* to power-on/off class-d amp generators/speaker */
71 /* need to write to 'index-46h' register : */
72 /* so write index num (here 0x46) to reg 0x6a */
73 /* and then 0xffff/0 to reg 0x6c */
74 snd_soc_write(w->codec, ALC5623_HID_CTRL_INDEX, 0x46);
75
76 switch (event) {
77 case SND_SOC_DAPM_PRE_PMU:
78 snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0xFFFF);
79 break;
80 case SND_SOC_DAPM_POST_PMD:
81 snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0);
82 break;
83 }
84
85 return 0;
86}
87
88/*
89 * ALC5623 Controls
90 */
91
92static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0);
93static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0);
94static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0);
95static const unsigned int boost_tlv[] = {
96 TLV_DB_RANGE_HEAD(3),
97 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
98 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
99 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0),
100};
101static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0);
102
103static const struct snd_kcontrol_new rt5621_vol_snd_controls[] = {
104 SOC_DOUBLE_TLV("Speaker Playback Volume",
105 ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
106 SOC_DOUBLE("Speaker Playback Switch",
107 ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
108 SOC_DOUBLE_TLV("Headphone Playback Volume",
109 ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
110 SOC_DOUBLE("Headphone Playback Switch",
111 ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
112};
113
114static const struct snd_kcontrol_new rt5622_vol_snd_controls[] = {
115 SOC_DOUBLE_TLV("Speaker Playback Volume",
116 ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
117 SOC_DOUBLE("Speaker Playback Switch",
118 ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
119 SOC_DOUBLE_TLV("Line Playback Volume",
120 ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
121 SOC_DOUBLE("Line Playback Switch",
122 ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
123};
124
125static const struct snd_kcontrol_new alc5623_vol_snd_controls[] = {
126 SOC_DOUBLE_TLV("Line Playback Volume",
127 ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv),
128 SOC_DOUBLE("Line Playback Switch",
129 ALC5623_SPK_OUT_VOL, 15, 7, 1, 1),
130 SOC_DOUBLE_TLV("Headphone Playback Volume",
131 ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv),
132 SOC_DOUBLE("Headphone Playback Switch",
133 ALC5623_HP_OUT_VOL, 15, 7, 1, 1),
134};
135
136static const struct snd_kcontrol_new alc5623_snd_controls[] = {
137 SOC_DOUBLE_TLV("Auxout Playback Volume",
138 ALC5623_MONO_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv),
139 SOC_DOUBLE("Auxout Playback Switch",
140 ALC5623_MONO_AUX_OUT_VOL, 15, 7, 1, 1),
141 SOC_DOUBLE_TLV("PCM Playback Volume",
142 ALC5623_STEREO_DAC_VOL, 8, 0, 31, 1, vol_tlv),
143 SOC_DOUBLE_TLV("AuxI Capture Volume",
144 ALC5623_AUXIN_VOL, 8, 0, 31, 1, vol_tlv),
145 SOC_DOUBLE_TLV("LineIn Capture Volume",
146 ALC5623_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv),
147 SOC_SINGLE_TLV("Mic1 Capture Volume",
148 ALC5623_MIC_VOL, 8, 31, 1, vol_tlv),
149 SOC_SINGLE_TLV("Mic2 Capture Volume",
150 ALC5623_MIC_VOL, 0, 31, 1, vol_tlv),
151 SOC_DOUBLE_TLV("Rec Capture Volume",
152 ALC5623_ADC_REC_GAIN, 7, 0, 31, 0, adc_rec_tlv),
153 SOC_SINGLE_TLV("Mic 1 Boost Volume",
154 ALC5623_MIC_CTRL, 10, 2, 0, boost_tlv),
155 SOC_SINGLE_TLV("Mic 2 Boost Volume",
156 ALC5623_MIC_CTRL, 8, 2, 0, boost_tlv),
157 SOC_SINGLE_TLV("Digital Boost Volume",
158 ALC5623_ADD_CTRL_REG, 4, 3, 0, dig_tlv),
159};
160
161/*
162 * DAPM Controls
163 */
164static const struct snd_kcontrol_new alc5623_hp_mixer_controls[] = {
165SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5623_LINE_IN_VOL, 15, 1, 1),
166SOC_DAPM_SINGLE("AUXI2HP Playback Switch", ALC5623_AUXIN_VOL, 15, 1, 1),
167SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 15, 1, 1),
168SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 7, 1, 1),
169SOC_DAPM_SINGLE("DAC2HP Playback Switch", ALC5623_STEREO_DAC_VOL, 15, 1, 1),
170};
171
172static const struct snd_kcontrol_new alc5623_hpl_mixer_controls[] = {
173SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5623_ADC_REC_GAIN, 15, 1, 1),
174};
175
176static const struct snd_kcontrol_new alc5623_hpr_mixer_controls[] = {
177SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5623_ADC_REC_GAIN, 14, 1, 1),
178};
179
180static const struct snd_kcontrol_new alc5623_mono_mixer_controls[] = {
181SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5623_ADC_REC_GAIN, 13, 1, 1),
182SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5623_ADC_REC_GAIN, 12, 1, 1),
183SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5623_LINE_IN_VOL, 13, 1, 1),
184SOC_DAPM_SINGLE("AUXI2MONO Playback Switch", ALC5623_AUXIN_VOL, 13, 1, 1),
185SOC_DAPM_SINGLE("MIC12MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 13, 1, 1),
186SOC_DAPM_SINGLE("MIC22MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 5, 1, 1),
187SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5623_STEREO_DAC_VOL, 13, 1, 1),
188};
189
190static const struct snd_kcontrol_new alc5623_speaker_mixer_controls[] = {
191SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5623_LINE_IN_VOL, 14, 1, 1),
192SOC_DAPM_SINGLE("AUXI2SPK Playback Switch", ALC5623_AUXIN_VOL, 14, 1, 1),
193SOC_DAPM_SINGLE("MIC12SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 14, 1, 1),
194SOC_DAPM_SINGLE("MIC22SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 6, 1, 1),
195SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5623_STEREO_DAC_VOL, 14, 1, 1),
196};
197
198/* Left Record Mixer */
199static const struct snd_kcontrol_new alc5623_captureL_mixer_controls[] = {
200SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 14, 1, 1),
201SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 13, 1, 1),
202SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5623_ADC_REC_MIXER, 12, 1, 1),
203SOC_DAPM_SINGLE("Left AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 11, 1, 1),
204SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5623_ADC_REC_MIXER, 10, 1, 1),
205SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 9, 1, 1),
206SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 8, 1, 1),
207};
208
209/* Right Record Mixer */
210static const struct snd_kcontrol_new alc5623_captureR_mixer_controls[] = {
211SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 6, 1, 1),
212SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 5, 1, 1),
213SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5623_ADC_REC_MIXER, 4, 1, 1),
214SOC_DAPM_SINGLE("Right AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 3, 1, 1),
215SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5623_ADC_REC_MIXER, 2, 1, 1),
216SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 1, 1, 1),
217SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 0, 1, 1),
218};
219
220static const char *alc5623_spk_n_sour_sel[] = {
221 "RN/-R", "RP/+R", "LN/-R", "Vmid" };
222static const char *alc5623_hpl_out_input_sel[] = {
223 "Vmid", "HP Left Mix"};
224static const char *alc5623_hpr_out_input_sel[] = {
225 "Vmid", "HP Right Mix"};
226static const char *alc5623_spkout_input_sel[] = {
227 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
228static const char *alc5623_aux_out_input_sel[] = {
229 "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"};
230
231/* auxout output mux */
232static const struct soc_enum alc5623_aux_out_input_enum =
233SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel);
234static const struct snd_kcontrol_new alc5623_auxout_mux_controls =
235SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum);
236
237/* speaker output mux */
238static const struct soc_enum alc5623_spkout_input_enum =
239SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel);
240static const struct snd_kcontrol_new alc5623_spkout_mux_controls =
241SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum);
242
243/* headphone left output mux */
244static const struct soc_enum alc5623_hpl_out_input_enum =
245SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel);
246static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls =
247SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum);
248
249/* headphone right output mux */
250static const struct soc_enum alc5623_hpr_out_input_enum =
251SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel);
252static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls =
253SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum);
254
255/* speaker output N select */
256static const struct soc_enum alc5623_spk_n_sour_enum =
257SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel);
258static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls =
259SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum);
260
261static const struct snd_soc_dapm_widget alc5623_dapm_widgets[] = {
262/* Muxes */
263SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0,
264 &alc5623_auxout_mux_controls),
265SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0,
266 &alc5623_spkout_mux_controls),
267SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0,
268 &alc5623_hpl_out_mux_controls),
269SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0,
270 &alc5623_hpr_out_mux_controls),
271SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0,
272 &alc5623_spkoutn_mux_controls),
273
274/* output mixers */
275SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0,
276 &alc5623_hp_mixer_controls[0],
277 ARRAY_SIZE(alc5623_hp_mixer_controls)),
278SND_SOC_DAPM_MIXER("HPR Mix", ALC5623_PWR_MANAG_ADD2, 4, 0,
279 &alc5623_hpr_mixer_controls[0],
280 ARRAY_SIZE(alc5623_hpr_mixer_controls)),
281SND_SOC_DAPM_MIXER("HPL Mix", ALC5623_PWR_MANAG_ADD2, 5, 0,
282 &alc5623_hpl_mixer_controls[0],
283 ARRAY_SIZE(alc5623_hpl_mixer_controls)),
284SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
285SND_SOC_DAPM_MIXER("Mono Mix", ALC5623_PWR_MANAG_ADD2, 2, 0,
286 &alc5623_mono_mixer_controls[0],
287 ARRAY_SIZE(alc5623_mono_mixer_controls)),
288SND_SOC_DAPM_MIXER("Speaker Mix", ALC5623_PWR_MANAG_ADD2, 3, 0,
289 &alc5623_speaker_mixer_controls[0],
290 ARRAY_SIZE(alc5623_speaker_mixer_controls)),
291
292/* input mixers */
293SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5623_PWR_MANAG_ADD2, 1, 0,
294 &alc5623_captureL_mixer_controls[0],
295 ARRAY_SIZE(alc5623_captureL_mixer_controls)),
296SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5623_PWR_MANAG_ADD2, 0, 0,
297 &alc5623_captureR_mixer_controls[0],
298 ARRAY_SIZE(alc5623_captureR_mixer_controls)),
299
300SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback",
301 ALC5623_PWR_MANAG_ADD2, 9, 0),
302SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback",
303 ALC5623_PWR_MANAG_ADD2, 8, 0),
304SND_SOC_DAPM_MIXER("I2S Mix", ALC5623_PWR_MANAG_ADD1, 15, 0, NULL, 0),
305SND_SOC_DAPM_MIXER("AuxI Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
306SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0),
307SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture",
308 ALC5623_PWR_MANAG_ADD2, 7, 0),
309SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture",
310 ALC5623_PWR_MANAG_ADD2, 6, 0),
311SND_SOC_DAPM_PGA("Left Headphone", ALC5623_PWR_MANAG_ADD3, 10, 0, NULL, 0),
312SND_SOC_DAPM_PGA("Right Headphone", ALC5623_PWR_MANAG_ADD3, 9, 0, NULL, 0),
313SND_SOC_DAPM_PGA("SpeakerOut", ALC5623_PWR_MANAG_ADD3, 12, 0, NULL, 0),
314SND_SOC_DAPM_PGA("Left AuxOut", ALC5623_PWR_MANAG_ADD3, 14, 0, NULL, 0),
315SND_SOC_DAPM_PGA("Right AuxOut", ALC5623_PWR_MANAG_ADD3, 13, 0, NULL, 0),
316SND_SOC_DAPM_PGA("Left LineIn", ALC5623_PWR_MANAG_ADD3, 7, 0, NULL, 0),
317SND_SOC_DAPM_PGA("Right LineIn", ALC5623_PWR_MANAG_ADD3, 6, 0, NULL, 0),
318SND_SOC_DAPM_PGA("Left AuxI", ALC5623_PWR_MANAG_ADD3, 5, 0, NULL, 0),
319SND_SOC_DAPM_PGA("Right AuxI", ALC5623_PWR_MANAG_ADD3, 4, 0, NULL, 0),
320SND_SOC_DAPM_PGA("MIC1 PGA", ALC5623_PWR_MANAG_ADD3, 3, 0, NULL, 0),
321SND_SOC_DAPM_PGA("MIC2 PGA", ALC5623_PWR_MANAG_ADD3, 2, 0, NULL, 0),
322SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5623_PWR_MANAG_ADD3, 1, 0, NULL, 0),
323SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5623_PWR_MANAG_ADD3, 0, 0, NULL, 0),
324SND_SOC_DAPM_MICBIAS("Mic Bias1", ALC5623_PWR_MANAG_ADD1, 11, 0),
325
326SND_SOC_DAPM_OUTPUT("AUXOUTL"),
327SND_SOC_DAPM_OUTPUT("AUXOUTR"),
328SND_SOC_DAPM_OUTPUT("HPL"),
329SND_SOC_DAPM_OUTPUT("HPR"),
330SND_SOC_DAPM_OUTPUT("SPKOUT"),
331SND_SOC_DAPM_OUTPUT("SPKOUTN"),
332SND_SOC_DAPM_INPUT("LINEINL"),
333SND_SOC_DAPM_INPUT("LINEINR"),
334SND_SOC_DAPM_INPUT("AUXINL"),
335SND_SOC_DAPM_INPUT("AUXINR"),
336SND_SOC_DAPM_INPUT("MIC1"),
337SND_SOC_DAPM_INPUT("MIC2"),
338SND_SOC_DAPM_VMID("Vmid"),
339};
340
341static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"};
342static const struct soc_enum alc5623_amp_enum =
343 SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names);
344static const struct snd_kcontrol_new alc5623_amp_mux_controls =
345 SOC_DAPM_ENUM("Route", alc5623_amp_enum);
346
347static const struct snd_soc_dapm_widget alc5623_dapm_amp_widgets[] = {
348SND_SOC_DAPM_PGA_E("D Amp", ALC5623_PWR_MANAG_ADD2, 14, 0, NULL, 0,
349 amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
350SND_SOC_DAPM_PGA("AB Amp", ALC5623_PWR_MANAG_ADD2, 15, 0, NULL, 0),
351SND_SOC_DAPM_MUX("AB-D Amp Mux", SND_SOC_NOPM, 0, 0,
352 &alc5623_amp_mux_controls),
353};
354
355static const struct snd_soc_dapm_route intercon[] = {
356 /* virtual mixer - mixes left & right channels */
357 {"I2S Mix", NULL, "Left DAC"},
358 {"I2S Mix", NULL, "Right DAC"},
359 {"Line Mix", NULL, "Right LineIn"},
360 {"Line Mix", NULL, "Left LineIn"},
361 {"AuxI Mix", NULL, "Left AuxI"},
362 {"AuxI Mix", NULL, "Right AuxI"},
363 {"AUXOUTL", NULL, "Left AuxOut"},
364 {"AUXOUTR", NULL, "Right AuxOut"},
365
366 /* HP mixer */
367 {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"},
368 {"HPL Mix", NULL, "HP Mix"},
369 {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"},
370 {"HPR Mix", NULL, "HP Mix"},
371 {"HP Mix", "LI2HP Playback Switch", "Line Mix"},
372 {"HP Mix", "AUXI2HP Playback Switch", "AuxI Mix"},
373 {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"},
374 {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"},
375 {"HP Mix", "DAC2HP Playback Switch", "I2S Mix"},
376
377 /* speaker mixer */
378 {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"},
379 {"Speaker Mix", "AUXI2SPK Playback Switch", "AuxI Mix"},
380 {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"},
381 {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"},
382 {"Speaker Mix", "DAC2SPK Playback Switch", "I2S Mix"},
383
384 /* mono mixer */
385 {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"},
386 {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"},
387 {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"},
388 {"Mono Mix", "AUXI2MONO Playback Switch", "AuxI Mix"},
389 {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"},
390 {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"},
391 {"Mono Mix", "DAC2MONO Playback Switch", "I2S Mix"},
392
393 /* Left record mixer */
394 {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"},
395 {"Left Capture Mix", "Left AuxI Capture Switch", "AUXINL"},
396 {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
397 {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
398 {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"},
399 {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
400 {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
401
402 /*Right record mixer */
403 {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"},
404 {"Right Capture Mix", "Right AuxI Capture Switch", "AUXINR"},
405 {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"},
406 {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"},
407 {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"},
408 {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"},
409 {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"},
410
411 /* headphone left mux */
412 {"Left Headphone Mux", "HP Left Mix", "HPL Mix"},
413 {"Left Headphone Mux", "Vmid", "Vmid"},
414
415 /* headphone right mux */
416 {"Right Headphone Mux", "HP Right Mix", "HPR Mix"},
417 {"Right Headphone Mux", "Vmid", "Vmid"},
418
419 /* speaker out mux */
420 {"SpeakerOut Mux", "Vmid", "Vmid"},
421 {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"},
422 {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"},
423 {"SpeakerOut Mux", "Mono Mix", "Mono Mix"},
424
425 /* Mono/Aux Out mux */
426 {"AuxOut Mux", "Vmid", "Vmid"},
427 {"AuxOut Mux", "HPOut Mix", "HPOut Mix"},
428 {"AuxOut Mux", "Speaker Mix", "Speaker Mix"},
429 {"AuxOut Mux", "Mono Mix", "Mono Mix"},
430
431 /* output pga */
432 {"HPL", NULL, "Left Headphone"},
433 {"Left Headphone", NULL, "Left Headphone Mux"},
434 {"HPR", NULL, "Right Headphone"},
435 {"Right Headphone", NULL, "Right Headphone Mux"},
436 {"Left AuxOut", NULL, "AuxOut Mux"},
437 {"Right AuxOut", NULL, "AuxOut Mux"},
438
439 /* input pga */
440 {"Left LineIn", NULL, "LINEINL"},
441 {"Right LineIn", NULL, "LINEINR"},
442 {"Left AuxI", NULL, "AUXINL"},
443 {"Right AuxI", NULL, "AUXINR"},
444 {"MIC1 Pre Amp", NULL, "MIC1"},
445 {"MIC2 Pre Amp", NULL, "MIC2"},
446 {"MIC1 PGA", NULL, "MIC1 Pre Amp"},
447 {"MIC2 PGA", NULL, "MIC2 Pre Amp"},
448
449 /* left ADC */
450 {"Left ADC", NULL, "Left Capture Mix"},
451
452 /* right ADC */
453 {"Right ADC", NULL, "Right Capture Mix"},
454
455 {"SpeakerOut N Mux", "RN/-R", "SpeakerOut"},
456 {"SpeakerOut N Mux", "RP/+R", "SpeakerOut"},
457 {"SpeakerOut N Mux", "LN/-R", "SpeakerOut"},
458 {"SpeakerOut N Mux", "Vmid", "Vmid"},
459
460 {"SPKOUT", NULL, "SpeakerOut"},
461 {"SPKOUTN", NULL, "SpeakerOut N Mux"},
462};
463
464static const struct snd_soc_dapm_route intercon_spk[] = {
465 {"SpeakerOut", NULL, "SpeakerOut Mux"},
466};
467
468static const struct snd_soc_dapm_route intercon_amp_spk[] = {
469 {"AB Amp", NULL, "SpeakerOut Mux"},
470 {"D Amp", NULL, "SpeakerOut Mux"},
471 {"AB-D Amp Mux", "AB Amp", "AB Amp"},
472 {"AB-D Amp Mux", "D Amp", "D Amp"},
473 {"SpeakerOut", NULL, "AB-D Amp Mux"},
474};
475
476/* PLL divisors */
477struct _pll_div {
478 u32 pll_in;
479 u32 pll_out;
480 u16 regvalue;
481};
482
483/* Note : pll code from original alc5623 driver. Not sure of how good it is */
484/* usefull only for master mode */
485static const struct _pll_div codec_master_pll_div[] = {
486
487 { 2048000, 8192000, 0x0ea0},
488 { 3686400, 8192000, 0x4e27},
489 { 12000000, 8192000, 0x456b},
490 { 13000000, 8192000, 0x495f},
491 { 13100000, 8192000, 0x0320},
492 { 2048000, 11289600, 0xf637},
493 { 3686400, 11289600, 0x2f22},
494 { 12000000, 11289600, 0x3e2f},
495 { 13000000, 11289600, 0x4d5b},
496 { 13100000, 11289600, 0x363b},
497 { 2048000, 16384000, 0x1ea0},
498 { 3686400, 16384000, 0x9e27},
499 { 12000000, 16384000, 0x452b},
500 { 13000000, 16384000, 0x542f},
501 { 13100000, 16384000, 0x03a0},
502 { 2048000, 16934400, 0xe625},
503 { 3686400, 16934400, 0x9126},
504 { 12000000, 16934400, 0x4d2c},
505 { 13000000, 16934400, 0x742f},
506 { 13100000, 16934400, 0x3c27},
507 { 2048000, 22579200, 0x2aa0},
508 { 3686400, 22579200, 0x2f20},
509 { 12000000, 22579200, 0x7e2f},
510 { 13000000, 22579200, 0x742f},
511 { 13100000, 22579200, 0x3c27},
512 { 2048000, 24576000, 0x2ea0},
513 { 3686400, 24576000, 0xee27},
514 { 12000000, 24576000, 0x2915},
515 { 13000000, 24576000, 0x772e},
516 { 13100000, 24576000, 0x0d20},
517};
518
519static const struct _pll_div codec_slave_pll_div[] = {
520
521 { 1024000, 16384000, 0x3ea0},
522 { 1411200, 22579200, 0x3ea0},
523 { 1536000, 24576000, 0x3ea0},
524 { 2048000, 16384000, 0x1ea0},
525 { 2822400, 22579200, 0x1ea0},
526 { 3072000, 24576000, 0x1ea0},
527
528};
529
530static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
531 int source, unsigned int freq_in, unsigned int freq_out)
532{
533 int i;
534 struct snd_soc_codec *codec = codec_dai->codec;
535 int gbl_clk = 0, pll_div = 0;
536 u16 reg;
537
538 if (pll_id < ALC5623_PLL_FR_MCLK || pll_id > ALC5623_PLL_FR_BCK)
539 return -ENODEV;
540
541 /* Disable PLL power */
542 snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
543 ALC5623_PWR_ADD2_PLL,
544 0);
545
546 /* pll is not used in slave mode */
547 reg = snd_soc_read(codec, ALC5623_DAI_CONTROL);
548 if (reg & ALC5623_DAI_SDP_SLAVE_MODE)
549 return 0;
550
551 if (!freq_in || !freq_out)
552 return 0;
553
554 switch (pll_id) {
555 case ALC5623_PLL_FR_MCLK:
556 for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) {
557 if (codec_master_pll_div[i].pll_in == freq_in
558 && codec_master_pll_div[i].pll_out == freq_out) {
559 /* PLL source from MCLK */
560 pll_div = codec_master_pll_div[i].regvalue;
561 break;
562 }
563 }
564 break;
565 case ALC5623_PLL_FR_BCK:
566 for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) {
567 if (codec_slave_pll_div[i].pll_in == freq_in
568 && codec_slave_pll_div[i].pll_out == freq_out) {
569 /* PLL source from Bitclk */
570 gbl_clk = ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK;
571 pll_div = codec_slave_pll_div[i].regvalue;
572 break;
573 }
574 }
575 break;
576 default:
577 return -EINVAL;
578 }
579
580 if (!pll_div)
581 return -EINVAL;
582
583 snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
584 snd_soc_write(codec, ALC5623_PLL_CTRL, pll_div);
585 snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2,
586 ALC5623_PWR_ADD2_PLL,
587 ALC5623_PWR_ADD2_PLL);
588 gbl_clk |= ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL;
589 snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk);
590
591 return 0;
592}
593
594struct _coeff_div {
595 u16 fs;
596 u16 regvalue;
597};
598
599/* codec hifi mclk (after PLL) clock divider coefficients */
600/* values inspired from column BCLK=32Fs of Appendix A table */
601static const struct _coeff_div coeff_div[] = {
602 {256*8, 0x3a69},
603 {384*8, 0x3c6b},
604 {256*4, 0x2a69},
605 {384*4, 0x2c6b},
606 {256*2, 0x1a69},
607 {384*2, 0x1c6b},
608 {256*1, 0x0a69},
609 {384*1, 0x0c6b},
610};
611
612static int get_coeff(struct snd_soc_codec *codec, int rate)
613{
614 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
615 int i;
616
617 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
618 if (coeff_div[i].fs * rate == alc5623->sysclk)
619 return i;
620 }
621 return -EINVAL;
622}
623
624/*
625 * Clock after PLL and dividers
626 */
627static int alc5623_set_dai_sysclk(struct snd_soc_dai *codec_dai,
628 int clk_id, unsigned int freq, int dir)
629{
630 struct snd_soc_codec *codec = codec_dai->codec;
631 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
632
633 switch (freq) {
634 case 8192000:
635 case 11289600:
636 case 12288000:
637 case 16384000:
638 case 16934400:
639 case 18432000:
640 case 22579200:
641 case 24576000:
642 alc5623->sysclk = freq;
643 return 0;
644 }
645 return -EINVAL;
646}
647
648static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai,
649 unsigned int fmt)
650{
651 struct snd_soc_codec *codec = codec_dai->codec;
652 u16 iface = 0;
653
654 /* set master/slave audio interface */
655 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
656 case SND_SOC_DAIFMT_CBM_CFM:
657 iface = ALC5623_DAI_SDP_MASTER_MODE;
658 break;
659 case SND_SOC_DAIFMT_CBS_CFS:
660 iface = ALC5623_DAI_SDP_SLAVE_MODE;
661 break;
662 default:
663 return -EINVAL;
664 }
665
666 /* interface format */
667 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
668 case SND_SOC_DAIFMT_I2S:
669 iface |= ALC5623_DAI_I2S_DF_I2S;
670 break;
671 case SND_SOC_DAIFMT_RIGHT_J:
672 iface |= ALC5623_DAI_I2S_DF_RIGHT;
673 break;
674 case SND_SOC_DAIFMT_LEFT_J:
675 iface |= ALC5623_DAI_I2S_DF_LEFT;
676 break;
677 case SND_SOC_DAIFMT_DSP_A:
678 iface |= ALC5623_DAI_I2S_DF_PCM;
679 break;
680 case SND_SOC_DAIFMT_DSP_B:
681 iface |= ALC5623_DAI_I2S_DF_PCM | ALC5623_DAI_I2S_PCM_MODE;
682 break;
683 default:
684 return -EINVAL;
685 }
686
687 /* clock inversion */
688 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
689 case SND_SOC_DAIFMT_NB_NF:
690 break;
691 case SND_SOC_DAIFMT_IB_IF:
692 iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL;
693 break;
694 case SND_SOC_DAIFMT_IB_NF:
695 iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL;
696 break;
697 case SND_SOC_DAIFMT_NB_IF:
698 break;
699 default:
700 return -EINVAL;
701 }
702
703 return snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
704}
705
706static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream,
707 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
708{
709 struct snd_soc_pcm_runtime *rtd = substream->private_data;
710 struct snd_soc_codec *codec = rtd->codec;
711 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
712 int coeff, rate;
713 u16 iface;
714
715 iface = snd_soc_read(codec, ALC5623_DAI_CONTROL);
716 iface &= ~ALC5623_DAI_I2S_DL_MASK;
717
718 /* bit size */
719 switch (params_format(params)) {
720 case SNDRV_PCM_FORMAT_S16_LE:
721 iface |= ALC5623_DAI_I2S_DL_16;
722 break;
723 case SNDRV_PCM_FORMAT_S20_3LE:
724 iface |= ALC5623_DAI_I2S_DL_20;
725 break;
726 case SNDRV_PCM_FORMAT_S24_LE:
727 iface |= ALC5623_DAI_I2S_DL_24;
728 break;
729 case SNDRV_PCM_FORMAT_S32_LE:
730 iface |= ALC5623_DAI_I2S_DL_32;
731 break;
732 default:
733 return -EINVAL;
734 }
735
736 /* set iface & srate */
737 snd_soc_write(codec, ALC5623_DAI_CONTROL, iface);
738 rate = params_rate(params);
739 coeff = get_coeff(codec, rate);
740 if (coeff < 0)
741 return -EINVAL;
742
743 coeff = coeff_div[coeff].regvalue;
744 dev_dbg(codec->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n",
745 __func__, alc5623->sysclk, rate, coeff);
746 snd_soc_write(codec, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff);
747
748 return 0;
749}
750
751static int alc5623_mute(struct snd_soc_dai *dai, int mute)
752{
753 struct snd_soc_codec *codec = dai->codec;
754 u16 hp_mute = ALC5623_MISC_M_DAC_L_INPUT | ALC5623_MISC_M_DAC_R_INPUT;
755 u16 mute_reg = snd_soc_read(codec, ALC5623_MISC_CTRL) & ~hp_mute;
756
757 if (mute)
758 mute_reg |= hp_mute;
759
760 return snd_soc_write(codec, ALC5623_MISC_CTRL, mute_reg);
761}
762
763#define ALC5623_ADD2_POWER_EN (ALC5623_PWR_ADD2_VREF \
764 | ALC5623_PWR_ADD2_DAC_REF_CIR)
765
766#define ALC5623_ADD3_POWER_EN (ALC5623_PWR_ADD3_MAIN_BIAS \
767 | ALC5623_PWR_ADD3_MIC1_BOOST_AD)
768
769#define ALC5623_ADD1_POWER_EN \
770 (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN | ALC5623_PWR_ADD1_SOFTGEN_EN \
771 | ALC5623_PWR_ADD1_DEPOP_BUF_HP | ALC5623_PWR_ADD1_HP_OUT_AMP \
772 | ALC5623_PWR_ADD1_HP_OUT_ENH_AMP)
773
774#define ALC5623_ADD1_POWER_EN_5622 \
775 (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN \
776 | ALC5623_PWR_ADD1_HP_OUT_AMP)
777
778static void enable_power_depop(struct snd_soc_codec *codec)
779{
780 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
781
782 snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD1,
783 ALC5623_PWR_ADD1_SOFTGEN_EN,
784 ALC5623_PWR_ADD1_SOFTGEN_EN);
785
786 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN);
787
788 snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
789 ALC5623_MISC_HP_DEPOP_MODE2_EN,
790 ALC5623_MISC_HP_DEPOP_MODE2_EN);
791
792 msleep(500);
793
794 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN);
795
796 /* avoid writing '1' into 5622 reserved bits */
797 if (alc5623->id == 0x22)
798 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
799 ALC5623_ADD1_POWER_EN_5622);
800 else
801 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1,
802 ALC5623_ADD1_POWER_EN);
803
804 /* disable HP Depop2 */
805 snd_soc_update_bits(codec, ALC5623_MISC_CTRL,
806 ALC5623_MISC_HP_DEPOP_MODE2_EN,
807 0);
808
809}
810
811static int alc5623_set_bias_level(struct snd_soc_codec *codec,
812 enum snd_soc_bias_level level)
813{
814 switch (level) {
815 case SND_SOC_BIAS_ON:
816 enable_power_depop(codec);
817 break;
818 case SND_SOC_BIAS_PREPARE:
819 break;
820 case SND_SOC_BIAS_STANDBY:
821 /* everything off except vref/vmid, */
822 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2,
823 ALC5623_PWR_ADD2_VREF);
824 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3,
825 ALC5623_PWR_ADD3_MAIN_BIAS);
826 break;
827 case SND_SOC_BIAS_OFF:
828 /* everything off, dac mute, inactive */
829 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 0);
830 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 0);
831 snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0);
832 break;
833 }
834 codec->dapm.bias_level = level;
835 return 0;
836}
837
838#define ALC5623_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \
839 | SNDRV_PCM_FMTBIT_S24_LE \
840 | SNDRV_PCM_FMTBIT_S32_LE)
841
842static struct snd_soc_dai_ops alc5623_dai_ops = {
843 .hw_params = alc5623_pcm_hw_params,
844 .digital_mute = alc5623_mute,
845 .set_fmt = alc5623_set_dai_fmt,
846 .set_sysclk = alc5623_set_dai_sysclk,
847 .set_pll = alc5623_set_dai_pll,
848};
849
850static struct snd_soc_dai_driver alc5623_dai = {
851 .name = "alc5623-hifi",
852 .playback = {
853 .stream_name = "Playback",
854 .channels_min = 1,
855 .channels_max = 2,
856 .rate_min = 8000,
857 .rate_max = 48000,
858 .rates = SNDRV_PCM_RATE_8000_48000,
859 .formats = ALC5623_FORMATS,},
860 .capture = {
861 .stream_name = "Capture",
862 .channels_min = 1,
863 .channels_max = 2,
864 .rate_min = 8000,
865 .rate_max = 48000,
866 .rates = SNDRV_PCM_RATE_8000_48000,
867 .formats = ALC5623_FORMATS,},
868
869 .ops = &alc5623_dai_ops,
870};
871
872static int alc5623_suspend(struct snd_soc_codec *codec, pm_message_t mesg)
873{
874 alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
875 return 0;
876}
877
878static int alc5623_resume(struct snd_soc_codec *codec)
879{
880 int i, step = codec->driver->reg_cache_step;
881 u16 *cache = codec->reg_cache;
882
883 /* Sync reg_cache with the hardware */
884 for (i = 2 ; i < codec->driver->reg_cache_size ; i += step)
885 snd_soc_write(codec, i, cache[i]);
886
887 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
888
889 /* charge alc5623 caps */
890 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
891 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
892 codec->dapm.bias_level = SND_SOC_BIAS_ON;
893 alc5623_set_bias_level(codec, codec->dapm.bias_level);
894 }
895
896 return 0;
897}
898
899static int alc5623_probe(struct snd_soc_codec *codec)
900{
901 struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec);
902 struct snd_soc_dapm_context *dapm = &codec->dapm;
903 int ret;
904
905 ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type);
906 if (ret < 0) {
907 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
908 return ret;
909 }
910
911 alc5623_reset(codec);
912 alc5623_fill_cache(codec);
913
914 /* power on device */
915 alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
916
917 if (alc5623->add_ctrl) {
918 snd_soc_write(codec, ALC5623_ADD_CTRL_REG,
919 alc5623->add_ctrl);
920 }
921
922 if (alc5623->jack_det_ctrl) {
923 snd_soc_write(codec, ALC5623_JACK_DET_CTRL,
924 alc5623->jack_det_ctrl);
925 }
926
927 switch (alc5623->id) {
928 case 0x21:
929 snd_soc_add_controls(codec, rt5621_vol_snd_controls,
930 ARRAY_SIZE(rt5621_vol_snd_controls));
931 break;
932 case 0x22:
933 snd_soc_add_controls(codec, rt5622_vol_snd_controls,
934 ARRAY_SIZE(rt5622_vol_snd_controls));
935 break;
936 case 0x23:
937 snd_soc_add_controls(codec, alc5623_vol_snd_controls,
938 ARRAY_SIZE(alc5623_vol_snd_controls));
939 break;
940 default:
941 return -EINVAL;
942 }
943
944 snd_soc_add_controls(codec, alc5623_snd_controls,
945 ARRAY_SIZE(alc5623_snd_controls));
946
947 snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets,
948 ARRAY_SIZE(alc5623_dapm_widgets));
949
950 /* set up audio path interconnects */
951 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
952
953 switch (alc5623->id) {
954 case 0x21:
955 case 0x22:
956 snd_soc_dapm_new_controls(dapm, alc5623_dapm_amp_widgets,
957 ARRAY_SIZE(alc5623_dapm_amp_widgets));
958 snd_soc_dapm_add_routes(dapm, intercon_amp_spk,
959 ARRAY_SIZE(intercon_amp_spk));
960 break;
961 case 0x23:
962 snd_soc_dapm_add_routes(dapm, intercon_spk,
963 ARRAY_SIZE(intercon_spk));
964 break;
965 default:
966 return -EINVAL;
967 }
968
969 return ret;
970}
971
972/* power down chip */
973static int alc5623_remove(struct snd_soc_codec *codec)
974{
975 alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF);
976 return 0;
977}
978
979static struct snd_soc_codec_driver soc_codec_device_alc5623 = {
980 .probe = alc5623_probe,
981 .remove = alc5623_remove,
982 .suspend = alc5623_suspend,
983 .resume = alc5623_resume,
984 .set_bias_level = alc5623_set_bias_level,
985 .reg_cache_size = ALC5623_VENDOR_ID2+2,
986 .reg_word_size = sizeof(u16),
987 .reg_cache_step = 2,
988};
989
990/*
991 * ALC5623 2 wire address is determined by A1 pin
992 * state during powerup.
993 * low = 0x1a
994 * high = 0x1b
995 */
996static int alc5623_i2c_probe(struct i2c_client *client,
997 const struct i2c_device_id *id)
998{
999 struct alc5623_platform_data *pdata;
1000 struct alc5623_priv *alc5623;
1001 int ret, vid1, vid2;
1002
1003 vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1);
1004 if (vid1 < 0) {
1005 dev_err(&client->dev, "failed to read I2C\n");
1006 return -EIO;
1007 }
1008 vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8);
1009
1010 vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2);
1011 if (vid2 < 0) {
1012 dev_err(&client->dev, "failed to read I2C\n");
1013 return -EIO;
1014 }
1015
1016 if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
1017 dev_err(&client->dev, "unknown or wrong codec\n");
1018 dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n",
1019 0x10ec, id->driver_data,
1020 vid1, vid2);
1021 return -ENODEV;
1022 }
1023
1024 dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2);
1025
1026 alc5623 = kzalloc(sizeof(struct alc5623_priv), GFP_KERNEL);
1027 if (alc5623 == NULL)
1028 return -ENOMEM;
1029
1030 pdata = client->dev.platform_data;
1031 if (pdata) {
1032 alc5623->add_ctrl = pdata->add_ctrl;
1033 alc5623->jack_det_ctrl = pdata->jack_det_ctrl;
1034 }
1035
1036 alc5623->id = vid2;
1037 switch (alc5623->id) {
1038 case 0x21:
1039 alc5623_dai.name = "alc5621-hifi";
1040 break;
1041 case 0x22:
1042 alc5623_dai.name = "alc5622-hifi";
1043 break;
1044 case 0x23:
1045 alc5623_dai.name = "alc5623-hifi";
1046 break;
1047 default:
1048 kfree(alc5623);
1049 return -EINVAL;
1050 }
1051
1052 i2c_set_clientdata(client, alc5623);
1053 alc5623->control_data = client;
1054 alc5623->control_type = SND_SOC_I2C;
1055 mutex_init(&alc5623->mutex);
1056
1057 ret = snd_soc_register_codec(&client->dev,
1058 &soc_codec_device_alc5623, &alc5623_dai, 1);
1059 if (ret != 0) {
1060 dev_err(&client->dev, "Failed to register codec: %d\n", ret);
1061 kfree(alc5623);
1062 }
1063
1064 return ret;
1065}
1066
1067static int alc5623_i2c_remove(struct i2c_client *client)
1068{
1069 struct alc5623_priv *alc5623 = i2c_get_clientdata(client);
1070
1071 snd_soc_unregister_codec(&client->dev);
1072 kfree(alc5623);
1073 return 0;
1074}
1075
1076static const struct i2c_device_id alc5623_i2c_table[] = {
1077 {"alc5621", 0x21},
1078 {"alc5622", 0x22},
1079 {"alc5623", 0x23},
1080 {}
1081};
1082MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table);
1083
1084/* i2c codec control layer */
1085static struct i2c_driver alc5623_i2c_driver = {
1086 .driver = {
1087 .name = "alc562x-codec",
1088 .owner = THIS_MODULE,
1089 },
1090 .probe = alc5623_i2c_probe,
1091 .remove = __devexit_p(alc5623_i2c_remove),
1092 .id_table = alc5623_i2c_table,
1093};
1094
1095static int __init alc5623_modinit(void)
1096{
1097 int ret;
1098
1099 ret = i2c_add_driver(&alc5623_i2c_driver);
1100 if (ret != 0) {
1101 printk(KERN_ERR "%s: can't add i2c driver", __func__);
1102 return ret;
1103 }
1104
1105 return ret;
1106}
1107module_init(alc5623_modinit);
1108
1109static void __exit alc5623_modexit(void)
1110{
1111 i2c_del_driver(&alc5623_i2c_driver);
1112}
1113module_exit(alc5623_modexit);
1114
1115MODULE_DESCRIPTION("ASoC alc5621/2/3 driver");
1116MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
1117MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/alc5623.h b/sound/soc/codecs/alc5623.h
new file mode 100644
index 000000000000..f3d68260d425
--- /dev/null
+++ b/sound/soc/codecs/alc5623.h
@@ -0,0 +1,161 @@
1/*
2 * alc5623.h -- alc562[123] ALSA Soc Audio driver
3 *
4 * Copyright 2008 Realtek Microelectronics
5 * Copyright 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
6 *
7 * Author: flove <flove@realtek.com>
8 * Arnaud Patard <arnaud.patard@rtp-net.org>
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#ifndef _ALC5623_H
17#define _ALC5623_H
18
19#define ALC5623_RESET 0x00
20/* 5621 5622 5623 */
21/* speaker output vol 2 2 */
22/* line output vol 4 2 */
23/* HP output vol 4 0 4 */
24#define ALC5623_SPK_OUT_VOL 0x02
25#define ALC5623_HP_OUT_VOL 0x04
26#define ALC5623_MONO_AUX_OUT_VOL 0x06
27#define ALC5623_AUXIN_VOL 0x08
28#define ALC5623_LINE_IN_VOL 0x0A
29#define ALC5623_STEREO_DAC_VOL 0x0C
30#define ALC5623_MIC_VOL 0x0E
31#define ALC5623_MIC_ROUTING_CTRL 0x10
32#define ALC5623_ADC_REC_GAIN 0x12
33#define ALC5623_ADC_REC_MIXER 0x14
34#define ALC5623_SOFT_VOL_CTRL_TIME 0x16
35/* ALC5623_OUTPUT_MIXER_CTRL : */
36/* same remark as for reg 2 line vs speaker */
37#define ALC5623_OUTPUT_MIXER_CTRL 0x1C
38#define ALC5623_MIC_CTRL 0x22
39
40#define ALC5623_DAI_CONTROL 0x34
41#define ALC5623_DAI_SDP_MASTER_MODE (0 << 15)
42#define ALC5623_DAI_SDP_SLAVE_MODE (1 << 15)
43#define ALC5623_DAI_I2S_PCM_MODE (1 << 14)
44#define ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7)
45#define ALC5623_DAI_ADC_DATA_L_R_SWAP (1 << 5)
46#define ALC5623_DAI_DAC_DATA_L_R_SWAP (1 << 4)
47#define ALC5623_DAI_I2S_DL_MASK (3 << 2)
48#define ALC5623_DAI_I2S_DL_32 (3 << 2)
49#define ALC5623_DAI_I2S_DL_24 (2 << 2)
50#define ALC5623_DAI_I2S_DL_20 (1 << 2)
51#define ALC5623_DAI_I2S_DL_16 (0 << 2)
52#define ALC5623_DAI_I2S_DF_PCM (3 << 0)
53#define ALC5623_DAI_I2S_DF_LEFT (2 << 0)
54#define ALC5623_DAI_I2S_DF_RIGHT (1 << 0)
55#define ALC5623_DAI_I2S_DF_I2S (0 << 0)
56
57#define ALC5623_STEREO_AD_DA_CLK_CTRL 0x36
58#define ALC5623_COMPANDING_CTRL 0x38
59
60#define ALC5623_PWR_MANAG_ADD1 0x3A
61#define ALC5623_PWR_ADD1_MAIN_I2S_EN (1 << 15)
62#define ALC5623_PWR_ADD1_ZC_DET_PD_EN (1 << 14)
63#define ALC5623_PWR_ADD1_MIC1_BIAS_EN (1 << 11)
64#define ALC5623_PWR_ADD1_SHORT_CURR_DET_EN (1 << 10)
65#define ALC5623_PWR_ADD1_SOFTGEN_EN (1 << 8) /* rsvd on 5622 */
66#define ALC5623_PWR_ADD1_DEPOP_BUF_HP (1 << 6) /* rsvd on 5622 */
67#define ALC5623_PWR_ADD1_HP_OUT_AMP (1 << 5)
68#define ALC5623_PWR_ADD1_HP_OUT_ENH_AMP (1 << 4) /* rsvd on 5622 */
69#define ALC5623_PWR_ADD1_DEPOP_BUF_AUX (1 << 2)
70#define ALC5623_PWR_ADD1_AUX_OUT_AMP (1 << 1)
71#define ALC5623_PWR_ADD1_AUX_OUT_ENH_AMP (1 << 0) /* rsvd on 5622 */
72
73#define ALC5623_PWR_MANAG_ADD2 0x3C
74#define ALC5623_PWR_ADD2_LINEOUT (1 << 15) /* rt5623 */
75#define ALC5623_PWR_ADD2_CLASS_AB (1 << 15) /* rt5621 */
76#define ALC5623_PWR_ADD2_CLASS_D (1 << 14) /* rt5621 */
77#define ALC5623_PWR_ADD2_VREF (1 << 13)
78#define ALC5623_PWR_ADD2_PLL (1 << 12)
79#define ALC5623_PWR_ADD2_DAC_REF_CIR (1 << 10)
80#define ALC5623_PWR_ADD2_L_DAC_CLK (1 << 9)
81#define ALC5623_PWR_ADD2_R_DAC_CLK (1 << 8)
82#define ALC5623_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7)
83#define ALC5623_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6)
84#define ALC5623_PWR_ADD2_L_HP_MIXER (1 << 5)
85#define ALC5623_PWR_ADD2_R_HP_MIXER (1 << 4)
86#define ALC5623_PWR_ADD2_SPK_MIXER (1 << 3)
87#define ALC5623_PWR_ADD2_MONO_MIXER (1 << 2)
88#define ALC5623_PWR_ADD2_L_ADC_REC_MIXER (1 << 1)
89#define ALC5623_PWR_ADD2_R_ADC_REC_MIXER (1 << 0)
90
91#define ALC5623_PWR_MANAG_ADD3 0x3E
92#define ALC5623_PWR_ADD3_MAIN_BIAS (1 << 15)
93#define ALC5623_PWR_ADD3_AUXOUT_L_VOL_AMP (1 << 14)
94#define ALC5623_PWR_ADD3_AUXOUT_R_VOL_AMP (1 << 13)
95#define ALC5623_PWR_ADD3_SPK_OUT (1 << 12)
96#define ALC5623_PWR_ADD3_HP_L_OUT_VOL (1 << 10)
97#define ALC5623_PWR_ADD3_HP_R_OUT_VOL (1 << 9)
98#define ALC5623_PWR_ADD3_LINEIN_L_VOL (1 << 7)
99#define ALC5623_PWR_ADD3_LINEIN_R_VOL (1 << 6)
100#define ALC5623_PWR_ADD3_AUXIN_L_VOL (1 << 5)
101#define ALC5623_PWR_ADD3_AUXIN_R_VOL (1 << 4)
102#define ALC5623_PWR_ADD3_MIC1_FUN_CTRL (1 << 3)
103#define ALC5623_PWR_ADD3_MIC2_FUN_CTRL (1 << 2)
104#define ALC5623_PWR_ADD3_MIC1_BOOST_AD (1 << 1)
105#define ALC5623_PWR_ADD3_MIC2_BOOST_AD (1 << 0)
106
107#define ALC5623_ADD_CTRL_REG 0x40
108
109#define ALC5623_GLOBAL_CLK_CTRL_REG 0x42
110#define ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL (1 << 15)
111#define ALC5623_GBL_CLK_SYS_SOUR_SEL_MCLK (0 << 15)
112#define ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK (1 << 14)
113#define ALC5623_GBL_CLK_PLL_SOUR_SEL_MCLK (0 << 14)
114#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV8 (3 << 1)
115#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV4 (2 << 1)
116#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV2 (1 << 1)
117#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV1 (0 << 1)
118#define ALC5623_GBL_CLK_PLL_PRE_DIV2 (1 << 0)
119#define ALC5623_GBL_CLK_PLL_PRE_DIV1 (0 << 0)
120
121#define ALC5623_PLL_CTRL 0x44
122#define ALC5623_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8)
123#define ALC5623_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4)
124#define ALC5623_PLL_CTRL_M_VAL(m) ((m)&0xf)
125
126#define ALC5623_GPIO_OUTPUT_PIN_CTRL 0x4A
127#define ALC5623_GPIO_PIN_CONFIG 0x4C
128#define ALC5623_GPIO_PIN_POLARITY 0x4E
129#define ALC5623_GPIO_PIN_STICKY 0x50
130#define ALC5623_GPIO_PIN_WAKEUP 0x52
131#define ALC5623_GPIO_PIN_STATUS 0x54
132#define ALC5623_GPIO_PIN_SHARING 0x56
133#define ALC5623_OVER_CURR_STATUS 0x58
134#define ALC5623_JACK_DET_CTRL 0x5A
135
136#define ALC5623_MISC_CTRL 0x5E
137#define ALC5623_MISC_DISABLE_FAST_VREG (1 << 15)
138#define ALC5623_MISC_SPK_CLASS_AB_OC_PD (1 << 13) /* 5621 */
139#define ALC5623_MISC_SPK_CLASS_AB_OC_DET (1 << 12) /* 5621 */
140#define ALC5623_MISC_HP_DEPOP_MODE3_EN (1 << 10)
141#define ALC5623_MISC_HP_DEPOP_MODE2_EN (1 << 9)
142#define ALC5623_MISC_HP_DEPOP_MODE1_EN (1 << 8)
143#define ALC5623_MISC_AUXOUT_DEPOP_MODE3_EN (1 << 6)
144#define ALC5623_MISC_AUXOUT_DEPOP_MODE2_EN (1 << 5)
145#define ALC5623_MISC_AUXOUT_DEPOP_MODE1_EN (1 << 4)
146#define ALC5623_MISC_M_DAC_L_INPUT (1 << 3)
147#define ALC5623_MISC_M_DAC_R_INPUT (1 << 2)
148#define ALC5623_MISC_IRQOUT_INV_CTRL (1 << 0)
149
150#define ALC5623_PSEDUEO_SPATIAL_CTRL 0x60
151#define ALC5623_EQ_CTRL 0x62
152#define ALC5623_EQ_MODE_ENABLE 0x66
153#define ALC5623_AVC_CTRL 0x68
154#define ALC5623_HID_CTRL_INDEX 0x6A
155#define ALC5623_HID_CTRL_DATA 0x6C
156#define ALC5623_VENDOR_ID1 0x7C
157#define ALC5623_VENDOR_ID2 0x7E
158
159#define ALC5623_PLL_FR_MCLK 0
160#define ALC5623_PLL_FR_BCK 1
161#endif
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c
index 823643932dde..46dbfd067f79 100644
--- a/sound/soc/codecs/cq93vc.c
+++ b/sound/soc/codecs/cq93vc.c
@@ -36,8 +36,6 @@
36#include <sound/pcm.h> 36#include <sound/pcm.h>
37#include <sound/pcm_params.h> 37#include <sound/pcm_params.h>
38#include <sound/soc.h> 38#include <sound/soc.h>
39#include <sound/soc-dai.h>
40#include <sound/soc-dapm.h>
41#include <sound/initval.h> 39#include <sound/initval.h>
42 40
43#include <mach/dm365.h> 41#include <mach/dm365.h>
@@ -116,7 +114,7 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec,
116 DAVINCI_VC_REG12_POWER_ALL_OFF); 114 DAVINCI_VC_REG12_POWER_ALL_OFF);
117 break; 115 break;
118 } 116 }
119 codec->bias_level = level; 117 codec->dapm.bias_level = level;
120 118
121 return 0; 119 return 0;
122} 120}
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
index 6d4bdc609ac8..8b51245f2318 100644
--- a/sound/soc/codecs/cs4270.c
+++ b/sound/soc/codecs/cs4270.c
@@ -106,6 +106,21 @@
106#define CS4270_MUTE_DAC_A 0x01 106#define CS4270_MUTE_DAC_A 0x01
107#define CS4270_MUTE_DAC_B 0x02 107#define CS4270_MUTE_DAC_B 0x02
108 108
109/* Power-on default values for the registers
110 *
111 * This array contains the power-on default values of the registers, with the
112 * exception of the "CHIPID" register (01h). The lower four bits of that
113 * register contain the hardware revision, so it is treated as volatile.
114 *
115 * Also note that on the CS4270, the first readable register is 1, but ASoC
116 * assumes the first register is 0. Therfore, the array must have an entry for
117 * register 0, but we use cs4270_reg_is_readable() to tell ASoC that it can't
118 * be read.
119 */
120static const u8 cs4270_default_reg_cache[CS4270_LASTREG + 1] = {
121 0x00, 0x00, 0x00, 0x30, 0x00, 0x60, 0x20, 0x00, 0x00
122};
123
109static const char *supply_names[] = { 124static const char *supply_names[] = {
110 "va", "vd", "vlc" 125 "va", "vd", "vlc"
111}; 126};
@@ -114,7 +129,6 @@ static const char *supply_names[] = {
114struct cs4270_private { 129struct cs4270_private {
115 enum snd_soc_control_type control_type; 130 enum snd_soc_control_type control_type;
116 void *control_data; 131 void *control_data;
117 u8 reg_cache[CS4270_NUMREGS];
118 unsigned int mclk; /* Input frequency of the MCLK pin */ 132 unsigned int mclk; /* Input frequency of the MCLK pin */
119 unsigned int mode; /* The mode (I2S or left-justified) */ 133 unsigned int mode; /* The mode (I2S or left-justified) */
120 unsigned int slave_mode; 134 unsigned int slave_mode;
@@ -179,6 +193,20 @@ static struct cs4270_mode_ratios cs4270_mode_ratios[] = {
179/* The number of MCLK/LRCK ratios supported by the CS4270 */ 193/* The number of MCLK/LRCK ratios supported by the CS4270 */
180#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios) 194#define NUM_MCLK_RATIOS ARRAY_SIZE(cs4270_mode_ratios)
181 195
196static int cs4270_reg_is_readable(unsigned int reg)
197{
198 return (reg >= CS4270_FIRSTREG) && (reg <= CS4270_LASTREG);
199}
200
201static int cs4270_reg_is_volatile(unsigned int reg)
202{
203 /* Unreadable registers are considered volatile */
204 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
205 return 1;
206
207 return reg == CS4270_CHIPID;
208}
209
182/** 210/**
183 * cs4270_set_dai_sysclk - determine the CS4270 samples rates. 211 * cs4270_set_dai_sysclk - determine the CS4270 samples rates.
184 * @codec_dai: the codec DAI 212 * @codec_dai: the codec DAI
@@ -264,97 +292,6 @@ static int cs4270_set_dai_fmt(struct snd_soc_dai *codec_dai,
264} 292}
265 293
266/** 294/**
267 * cs4270_fill_cache - pre-fill the CS4270 register cache.
268 * @codec: the codec for this CS4270
269 *
270 * This function fills in the CS4270 register cache by reading the register
271 * values from the hardware.
272 *
273 * This CS4270 registers are cached to avoid excessive I2C I/O operations.
274 * After the initial read to pre-fill the cache, the CS4270 never updates
275 * the register values, so we won't have a cache coherency problem.
276 *
277 * We use the auto-increment feature of the CS4270 to read all registers in
278 * one shot.
279 */
280static int cs4270_fill_cache(struct snd_soc_codec *codec)
281{
282 u8 *cache = codec->reg_cache;
283 struct i2c_client *i2c_client = codec->control_data;
284 s32 length;
285
286 length = i2c_smbus_read_i2c_block_data(i2c_client,
287 CS4270_FIRSTREG | CS4270_I2C_INCR, CS4270_NUMREGS, cache);
288
289 if (length != CS4270_NUMREGS) {
290 dev_err(codec->dev, "i2c read failure, addr=0x%x\n",
291 i2c_client->addr);
292 return -EIO;
293 }
294
295 return 0;
296}
297
298/**
299 * cs4270_read_reg_cache - read from the CS4270 register cache.
300 * @codec: the codec for this CS4270
301 * @reg: the register to read
302 *
303 * This function returns the value for a given register. It reads only from
304 * the register cache, not the hardware itself.
305 *
306 * This CS4270 registers are cached to avoid excessive I2C I/O operations.
307 * After the initial read to pre-fill the cache, the CS4270 never updates
308 * the register values, so we won't have a cache coherency problem.
309 */
310static unsigned int cs4270_read_reg_cache(struct snd_soc_codec *codec,
311 unsigned int reg)
312{
313 u8 *cache = codec->reg_cache;
314
315 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
316 return -EIO;
317
318 return cache[reg - CS4270_FIRSTREG];
319}
320
321/**
322 * cs4270_i2c_write - write to a CS4270 register via the I2C bus.
323 * @codec: the codec for this CS4270
324 * @reg: the register to write
325 * @value: the value to write to the register
326 *
327 * This function writes the given value to the given CS4270 register, and
328 * also updates the register cache.
329 *
330 * Note that we don't use the hw_write function pointer of snd_soc_codec.
331 * That's because it's too clunky: the hw_write_t prototype does not match
332 * i2c_smbus_write_byte_data(), and it's just another layer of overhead.
333 */
334static int cs4270_i2c_write(struct snd_soc_codec *codec, unsigned int reg,
335 unsigned int value)
336{
337 u8 *cache = codec->reg_cache;
338
339 if ((reg < CS4270_FIRSTREG) || (reg > CS4270_LASTREG))
340 return -EIO;
341
342 /* Only perform an I2C operation if the new value is different */
343 if (cache[reg - CS4270_FIRSTREG] != value) {
344 struct i2c_client *client = codec->control_data;
345 if (i2c_smbus_write_byte_data(client, reg, value)) {
346 dev_err(codec->dev, "i2c write failed\n");
347 return -EIO;
348 }
349
350 /* We've written to the hardware, so update the cache */
351 cache[reg - CS4270_FIRSTREG] = value;
352 }
353
354 return 0;
355}
356
357/**
358 * cs4270_hw_params - program the CS4270 with the given hardware parameters. 295 * cs4270_hw_params - program the CS4270 with the given hardware parameters.
359 * @substream: the audio stream 296 * @substream: the audio stream
360 * @params: the hardware parameters to set 297 * @params: the hardware parameters to set
@@ -551,15 +488,16 @@ static struct snd_soc_dai_driver cs4270_dai = {
551static int cs4270_probe(struct snd_soc_codec *codec) 488static int cs4270_probe(struct snd_soc_codec *codec)
552{ 489{
553 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); 490 struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec);
554 int i, ret, reg; 491 int i, ret;
555 492
556 codec->control_data = cs4270->control_data; 493 codec->control_data = cs4270->control_data;
557 494
558 /* The I2C interface is set up, so pre-fill our register cache */ 495 /* Tell ASoC what kind of I/O to use to read the registers. ASoC will
559 496 * then do the I2C transactions itself.
560 ret = cs4270_fill_cache(codec); 497 */
498 ret = snd_soc_codec_set_cache_io(codec, 8, 8, cs4270->control_type);
561 if (ret < 0) { 499 if (ret < 0) {
562 dev_err(codec->dev, "failed to fill register cache\n"); 500 dev_err(codec->dev, "failed to set cache I/O (ret=%i)\n", ret);
563 return ret; 501 return ret;
564 } 502 }
565 503
@@ -568,10 +506,7 @@ static int cs4270_probe(struct snd_soc_codec *codec)
568 * this feature disabled by default. An application (e.g. alsactl) can 506 * this feature disabled by default. An application (e.g. alsactl) can
569 * re-enabled it by using the controls. 507 * re-enabled it by using the controls.
570 */ 508 */
571 509 ret = snd_soc_update_bits(codec, CS4270_MUTE, CS4270_MUTE_AUTO, 0);
572 reg = cs4270_read_reg_cache(codec, CS4270_MUTE);
573 reg &= ~CS4270_MUTE_AUTO;
574 ret = cs4270_i2c_write(codec, CS4270_MUTE, reg);
575 if (ret < 0) { 510 if (ret < 0) {
576 dev_err(codec->dev, "i2c write failed\n"); 511 dev_err(codec->dev, "i2c write failed\n");
577 return ret; 512 return ret;
@@ -582,10 +517,8 @@ static int cs4270_probe(struct snd_soc_codec *codec)
582 * playback has started. An application (e.g. alsactl) can 517 * playback has started. An application (e.g. alsactl) can
583 * re-enabled it by using the controls. 518 * re-enabled it by using the controls.
584 */ 519 */
585 520 ret = snd_soc_update_bits(codec, CS4270_TRANS,
586 reg = cs4270_read_reg_cache(codec, CS4270_TRANS); 521 CS4270_TRANS_SOFT | CS4270_TRANS_ZERO, 0);
587 reg &= ~(CS4270_TRANS_SOFT | CS4270_TRANS_ZERO);
588 ret = cs4270_i2c_write(codec, CS4270_TRANS, reg);
589 if (ret < 0) { 522 if (ret < 0) {
590 dev_err(codec->dev, "i2c write failed\n"); 523 dev_err(codec->dev, "i2c write failed\n");
591 return ret; 524 return ret;
@@ -708,15 +641,16 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec)
708 * Assign this variable to the codec_dev field of the machine driver's 641 * Assign this variable to the codec_dev field of the machine driver's
709 * snd_soc_device structure. 642 * snd_soc_device structure.
710 */ 643 */
711static struct snd_soc_codec_driver soc_codec_device_cs4270 = { 644static const struct snd_soc_codec_driver soc_codec_device_cs4270 = {
712 .probe = cs4270_probe, 645 .probe = cs4270_probe,
713 .remove = cs4270_remove, 646 .remove = cs4270_remove,
714 .suspend = cs4270_soc_suspend, 647 .suspend = cs4270_soc_suspend,
715 .resume = cs4270_soc_resume, 648 .resume = cs4270_soc_resume,
716 .read = cs4270_read_reg_cache, 649 .volatile_register = cs4270_reg_is_volatile,
717 .write = cs4270_i2c_write, 650 .readable_register = cs4270_reg_is_readable,
718 .reg_cache_size = CS4270_NUMREGS, 651 .reg_cache_size = CS4270_LASTREG + 1,
719 .reg_word_size = sizeof(u8), 652 .reg_word_size = sizeof(u8),
653 .reg_cache_default = cs4270_default_reg_cache,
720}; 654};
721 655
722/** 656/**
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c
index cb086eaf4e07..8fb7070108dd 100644
--- a/sound/soc/codecs/cs42l51.c
+++ b/sound/soc/codecs/cs42l51.c
@@ -26,7 +26,6 @@
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <sound/core.h> 27#include <sound/core.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/tlv.h> 29#include <sound/tlv.h>
31#include <sound/initval.h> 30#include <sound/initval.h>
32#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
@@ -47,7 +46,6 @@ struct cs42l51_private {
47 unsigned int mclk; 46 unsigned int mclk;
48 unsigned int audio_mode; /* The mode (I2S or left-justified) */ 47 unsigned int audio_mode; /* The mode (I2S or left-justified) */
49 enum master_slave_mode func; 48 enum master_slave_mode func;
50 u8 reg_cache[CS42L51_NUMREGS];
51}; 49};
52 50
53#define CS42L51_FORMATS ( \ 51#define CS42L51_FORMATS ( \
@@ -519,6 +517,7 @@ static struct snd_soc_dai_driver cs42l51_dai = {
519static int cs42l51_probe(struct snd_soc_codec *codec) 517static int cs42l51_probe(struct snd_soc_codec *codec)
520{ 518{
521 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); 519 struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec);
520 struct snd_soc_dapm_context *dapm = &codec->dapm;
522 int ret, reg; 521 int ret, reg;
523 522
524 codec->control_data = cs42l51->control_data; 523 codec->control_data = cs42l51->control_data;
@@ -550,9 +549,9 @@ static int cs42l51_probe(struct snd_soc_codec *codec)
550 549
551 snd_soc_add_controls(codec, cs42l51_snd_controls, 550 snd_soc_add_controls(codec, cs42l51_snd_controls,
552 ARRAY_SIZE(cs42l51_snd_controls)); 551 ARRAY_SIZE(cs42l51_snd_controls));
553 snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets, 552 snd_soc_dapm_new_controls(dapm, cs42l51_dapm_widgets,
554 ARRAY_SIZE(cs42l51_dapm_widgets)); 553 ARRAY_SIZE(cs42l51_dapm_widgets));
555 snd_soc_dapm_add_routes(codec, cs42l51_routes, 554 snd_soc_dapm_add_routes(dapm, cs42l51_routes,
556 ARRAY_SIZE(cs42l51_routes)); 555 ARRAY_SIZE(cs42l51_routes));
557 556
558 return 0; 557 return 0;
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c
index e8d27c8f9ba3..03d1e860d229 100644
--- a/sound/soc/codecs/cx20442.c
+++ b/sound/soc/codecs/cx20442.c
@@ -18,7 +18,7 @@
18 18
19#include <sound/core.h> 19#include <sound/core.h>
20#include <sound/initval.h> 20#include <sound/initval.h>
21#include <sound/soc-dapm.h> 21#include <sound/soc.h>
22 22
23#include "cx20442.h" 23#include "cx20442.h"
24 24
@@ -26,7 +26,6 @@
26struct cx20442_priv { 26struct cx20442_priv {
27 enum snd_soc_control_type control_type; 27 enum snd_soc_control_type control_type;
28 void *control_data; 28 void *control_data;
29 u8 reg_cache[1];
30}; 29};
31 30
32#define CX20442_PM 0x0 31#define CX20442_PM 0x0
@@ -89,10 +88,11 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = {
89 88
90static int cx20442_add_widgets(struct snd_soc_codec *codec) 89static int cx20442_add_widgets(struct snd_soc_codec *codec)
91{ 90{
92 snd_soc_dapm_new_controls(codec, cx20442_dapm_widgets, 91 struct snd_soc_dapm_context *dapm = &codec->dapm;
93 ARRAY_SIZE(cx20442_dapm_widgets));
94 92
95 snd_soc_dapm_add_routes(codec, cx20442_audio_map, 93 snd_soc_dapm_new_controls(dapm, cx20442_dapm_widgets,
94 ARRAY_SIZE(cx20442_dapm_widgets));
95 snd_soc_dapm_add_routes(dapm, cx20442_audio_map,
96 ARRAY_SIZE(cx20442_audio_map)); 96 ARRAY_SIZE(cx20442_audio_map));
97 97
98 return 0; 98 return 0;
@@ -263,7 +263,7 @@ static void v253_close(struct tty_struct *tty)
263 /* Prevent the codec driver from further accessing the modem */ 263 /* Prevent the codec driver from further accessing the modem */
264 codec->hw_write = NULL; 264 codec->hw_write = NULL;
265 cx20442->control_data = NULL; 265 cx20442->control_data = NULL;
266 codec->pop_time = 0; 266 codec->card->pop_time = 0;
267} 267}
268 268
269/* Line discipline .hangup() */ 269/* Line discipline .hangup() */
@@ -291,7 +291,7 @@ static void v253_receive(struct tty_struct *tty,
291 /* Set up codec driver access to modem controls */ 291 /* Set up codec driver access to modem controls */
292 cx20442->control_data = tty; 292 cx20442->control_data = tty;
293 codec->hw_write = (hw_write_t)tty->ops->write; 293 codec->hw_write = (hw_write_t)tty->ops->write;
294 codec->pop_time = 1; 294 codec->card->pop_time = 1;
295 } 295 }
296} 296}
297 297
@@ -348,7 +348,7 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
348 348
349 cx20442->control_data = NULL; 349 cx20442->control_data = NULL;
350 codec->hw_write = NULL; 350 codec->hw_write = NULL;
351 codec->pop_time = 0; 351 codec->card->pop_time = 0;
352 352
353 return 0; 353 return 0;
354} 354}
diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c
index 58bb9b994811..92fd9d7a9221 100644
--- a/sound/soc/codecs/da7210.c
+++ b/sound/soc/codecs/da7210.c
@@ -21,7 +21,7 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/soc-dapm.h> 24#include <sound/soc.h>
25#include <sound/initval.h> 25#include <sound/initval.h>
26#include <sound/tlv.h> 26#include <sound/tlv.h>
27 27
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
new file mode 100644
index 000000000000..57e9dac88d38
--- /dev/null
+++ b/sound/soc/codecs/dmic.c
@@ -0,0 +1,81 @@
1/*
2 * dmic.c -- SoC audio for Generic Digital MICs
3 *
4 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
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/platform_device.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28
29static struct snd_soc_dai_driver dmic_dai = {
30 .name = "dmic-hifi",
31 .capture = {
32 .stream_name = "Capture",
33 .channels_min = 1,
34 .channels_max = 8,
35 .rates = SNDRV_PCM_RATE_CONTINUOUS,
36 .formats = SNDRV_PCM_FMTBIT_S32_LE
37 | SNDRV_PCM_FMTBIT_S24_LE
38 | SNDRV_PCM_FMTBIT_S16_LE,
39 },
40};
41
42static struct snd_soc_codec_driver soc_dmic = {};
43
44static int __devinit dmic_dev_probe(struct platform_device *pdev)
45{
46 return snd_soc_register_codec(&pdev->dev,
47 &soc_dmic, &dmic_dai, 1);
48}
49
50static int __devexit dmic_dev_remove(struct platform_device *pdev)
51{
52 snd_soc_unregister_codec(&pdev->dev);
53 return 0;
54}
55
56MODULE_ALIAS("platform:dmic-codec");
57
58static struct platform_driver dmic_driver = {
59 .driver = {
60 .name = "dmic-codec",
61 .owner = THIS_MODULE,
62 },
63 .probe = dmic_dev_probe,
64 .remove = __devexit_p(dmic_dev_remove),
65};
66
67static int __init dmic_init(void)
68{
69 return platform_driver_register(&dmic_driver);
70}
71module_init(dmic_init);
72
73static void __exit dmic_exit(void)
74{
75 platform_driver_unregister(&dmic_driver);
76}
77module_exit(dmic_exit);
78
79MODULE_DESCRIPTION("Generic DMIC driver");
80MODULE_AUTHOR("Liam Girdwood <lrg@slimlogic.co.uk>");
81MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c
index 16253ec9b022..f7cd346fd727 100644
--- a/sound/soc/codecs/jz4740.c
+++ b/sound/soc/codecs/jz4740.c
@@ -22,7 +22,6 @@
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/initval.h> 24#include <sound/initval.h>
25#include <sound/soc-dapm.h>
26#include <sound/soc.h> 25#include <sound/soc.h>
27 26
28#define JZ4740_REG_CODEC_1 0x0 27#define JZ4740_REG_CODEC_1 0x0
@@ -266,7 +265,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
266 break; 265 break;
267 case SND_SOC_BIAS_STANDBY: 266 case SND_SOC_BIAS_STANDBY:
268 /* The only way to clear the suspend flag is to reset the codec */ 267 /* The only way to clear the suspend flag is to reset the codec */
269 if (codec->bias_level == SND_SOC_BIAS_OFF) 268 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
270 jz4740_codec_wakeup(codec); 269 jz4740_codec_wakeup(codec);
271 270
272 mask = JZ4740_CODEC_1_VREF_DISABLE | 271 mask = JZ4740_CODEC_1_VREF_DISABLE |
@@ -288,23 +287,25 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec,
288 break; 287 break;
289 } 288 }
290 289
291 codec->bias_level = level; 290 codec->dapm.bias_level = level;
292 291
293 return 0; 292 return 0;
294} 293}
295 294
296static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) 295static int jz4740_codec_dev_probe(struct snd_soc_codec *codec)
297{ 296{
297 struct snd_soc_dapm_context *dapm = &codec->dapm;
298
298 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, 299 snd_soc_update_bits(codec, JZ4740_REG_CODEC_1,
299 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); 300 JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE);
300 301
301 snd_soc_add_controls(codec, jz4740_codec_controls, 302 snd_soc_add_controls(codec, jz4740_codec_controls,
302 ARRAY_SIZE(jz4740_codec_controls)); 303 ARRAY_SIZE(jz4740_codec_controls));
303 304
304 snd_soc_dapm_new_controls(codec, jz4740_codec_dapm_widgets, 305 snd_soc_dapm_new_controls(dapm, jz4740_codec_dapm_widgets,
305 ARRAY_SIZE(jz4740_codec_dapm_widgets)); 306 ARRAY_SIZE(jz4740_codec_dapm_widgets));
306 307
307 snd_soc_dapm_add_routes(codec, jz4740_codec_dapm_routes, 308 snd_soc_dapm_add_routes(dapm, jz4740_codec_dapm_routes,
308 ARRAY_SIZE(jz4740_codec_dapm_routes)); 309 ARRAY_SIZE(jz4740_codec_dapm_routes));
309 310
310 snd_soc_dapm_new_widgets(codec); 311 snd_soc_dapm_new_widgets(codec);
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 72f0dbc6e0f2..89498f9ad2e5 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -20,7 +20,6 @@
20#include <sound/pcm.h> 20#include <sound/pcm.h>
21#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/initval.h> 23#include <sound/initval.h>
25#include <sound/tlv.h> 24#include <sound/tlv.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
@@ -1229,15 +1228,17 @@ static const struct snd_soc_dapm_route audio_map[] = {
1229 1228
1230static int max98088_add_widgets(struct snd_soc_codec *codec) 1229static int max98088_add_widgets(struct snd_soc_codec *codec)
1231{ 1230{
1232 snd_soc_dapm_new_controls(codec, max98088_dapm_widgets, 1231 struct snd_soc_dapm_context *dapm = &codec->dapm;
1232
1233 snd_soc_dapm_new_controls(dapm, max98088_dapm_widgets,
1233 ARRAY_SIZE(max98088_dapm_widgets)); 1234 ARRAY_SIZE(max98088_dapm_widgets));
1234 1235
1235 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 1236 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
1236 1237
1237 snd_soc_add_controls(codec, max98088_snd_controls, 1238 snd_soc_add_controls(codec, max98088_snd_controls,
1238 ARRAY_SIZE(max98088_snd_controls)); 1239 ARRAY_SIZE(max98088_snd_controls));
1239 1240
1240 snd_soc_dapm_new_widgets(codec); 1241 snd_soc_dapm_new_widgets(dapm);
1241 return 0; 1242 return 0;
1242} 1243}
1243 1244
@@ -1622,7 +1623,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
1622 break; 1623 break;
1623 1624
1624 case SND_SOC_BIAS_STANDBY: 1625 case SND_SOC_BIAS_STANDBY:
1625 if (codec->bias_level == SND_SOC_BIAS_OFF) 1626 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
1626 max98088_sync_cache(codec); 1627 max98088_sync_cache(codec);
1627 1628
1628 snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN, 1629 snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN,
@@ -1635,7 +1636,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec,
1635 codec->cache_sync = 1; 1636 codec->cache_sync = 1;
1636 break; 1637 break;
1637 } 1638 }
1638 codec->bias_level = level; 1639 codec->dapm.bias_level = level;
1639 return 0; 1640 return 0;
1640} 1641}
1641 1642
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index 6f38d619bf8a..2727befd158e 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -38,7 +38,6 @@
38#include <sound/pcm.h> 38#include <sound/pcm.h>
39#include <sound/pcm_params.h> 39#include <sound/pcm_params.h>
40#include <sound/soc.h> 40#include <sound/soc.h>
41#include <sound/soc-dapm.h>
42#include <sound/initval.h> 41#include <sound/initval.h>
43 42
44#include "ssm2602.h" 43#include "ssm2602.h"
@@ -207,10 +206,11 @@ static const struct snd_soc_dapm_route audio_conn[] = {
207 206
208static int ssm2602_add_widgets(struct snd_soc_codec *codec) 207static int ssm2602_add_widgets(struct snd_soc_codec *codec)
209{ 208{
210 snd_soc_dapm_new_controls(codec, ssm2602_dapm_widgets, 209 struct snd_soc_dapm_context *dapm = &codec->dapm;
211 ARRAY_SIZE(ssm2602_dapm_widgets));
212 210
213 snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn)); 211 snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets,
212 ARRAY_SIZE(ssm2602_dapm_widgets));
213 snd_soc_dapm_add_routes(dapm, audio_conn, ARRAY_SIZE(audio_conn));
214 214
215 return 0; 215 return 0;
216} 216}
@@ -493,7 +493,7 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec,
493 break; 493 break;
494 494
495 } 495 }
496 codec->bias_level = level; 496 codec->dapm.bias_level = level;
497 return 0; 497 return 0;
498} 498}
499 499
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c
index 061f9e5a497b..78b2b50271e2 100644
--- a/sound/soc/codecs/stac9766.c
+++ b/sound/soc/codecs/stac9766.c
@@ -236,7 +236,7 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec,
236 stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff); 236 stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff);
237 break; 237 break;
238 } 238 }
239 codec->bias_level = level; 239 codec->dapm.bias_level = level;
240 return 0; 240 return 0;
241} 241}
242 242
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c
index e8652b1ae326..54a30ef0ec8b 100644
--- a/sound/soc/codecs/tlv320aic23.c
+++ b/sound/soc/codecs/tlv320aic23.c
@@ -30,7 +30,6 @@
30#include <sound/pcm.h> 30#include <sound/pcm.h>
31#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34#include <sound/tlv.h> 33#include <sound/tlv.h>
35#include <sound/initval.h> 34#include <sound/initval.h>
36 35
@@ -391,11 +390,12 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
391 390
392static int tlv320aic23_add_widgets(struct snd_soc_codec *codec) 391static int tlv320aic23_add_widgets(struct snd_soc_codec *codec)
393{ 392{
394 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 393 struct snd_soc_dapm_context *dapm = &codec->dapm;
395 ARRAY_SIZE(tlv320aic23_dapm_widgets));
396 394
395 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
396 ARRAY_SIZE(tlv320aic23_dapm_widgets));
397 /* set up audio path interconnects */ 397 /* set up audio path interconnects */
398 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 398 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
399 399
400 return 0; 400 return 0;
401} 401}
@@ -574,7 +574,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
574 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff); 574 tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
575 break; 575 break;
576 } 576 }
577 codec->bias_level = level; 577 codec->dapm.bias_level = level;
578 return 0; 578 return 0;
579} 579}
580 580
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c
index 6b7d71ec0004..e2a7608d3944 100644
--- a/sound/soc/codecs/tlv320aic26.c
+++ b/sound/soc/codecs/tlv320aic26.c
@@ -18,7 +18,6 @@
18#include <sound/pcm.h> 18#include <sound/pcm.h>
19#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/initval.h> 21#include <sound/initval.h>
23 22
24#include "tlv320aic26.h" 23#include "tlv320aic26.h"
@@ -31,7 +30,6 @@ MODULE_LICENSE("GPL");
31struct aic26 { 30struct aic26 {
32 struct spi_device *spi; 31 struct spi_device *spi;
33 struct snd_soc_codec codec; 32 struct snd_soc_codec codec;
34 u16 reg_cache[AIC26_NUM_REGS]; /* shadow registers */
35 int master; 33 int master;
36 int datfm; 34 int datfm;
37 int mclk; 35 int mclk;
@@ -355,7 +353,6 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set);
355 */ 353 */
356static int aic26_probe(struct snd_soc_codec *codec) 354static int aic26_probe(struct snd_soc_codec *codec)
357{ 355{
358 struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec);
359 int ret, err, i, reg; 356 int ret, err, i, reg;
360 357
361 dev_info(codec->dev, "Probing AIC26 SoC CODEC driver\n"); 358 dev_info(codec->dev, "Probing AIC26 SoC CODEC driver\n");
@@ -373,7 +370,7 @@ static int aic26_probe(struct snd_soc_codec *codec)
373 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg); 370 aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg);
374 371
375 /* Fill register cache */ 372 /* Fill register cache */
376 for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++) 373 for (i = 0; i < codec->driver->reg_cache_size; i++)
377 aic26_reg_read(codec, i); 374 aic26_reg_read(codec, i);
378 375
379 /* Register the sysfs files for debugging */ 376 /* Register the sysfs files for debugging */
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index 77b8f9ae29be..3bedab26892f 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -46,7 +46,6 @@
46#include <sound/pcm.h> 46#include <sound/pcm.h>
47#include <sound/pcm_params.h> 47#include <sound/pcm_params.h>
48#include <sound/soc.h> 48#include <sound/soc.h>
49#include <sound/soc-dapm.h>
50#include <sound/initval.h> 49#include <sound/initval.h>
51#include <sound/tlv.h> 50#include <sound/tlv.h>
52#include <sound/tlv320aic3x.h> 51#include <sound/tlv320aic3x.h>
@@ -61,6 +60,8 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = {
61 "DRVDD", /* ADC Analog and Output Driver Voltage */ 60 "DRVDD", /* ADC Analog and Output Driver Voltage */
62}; 61};
63 62
63static LIST_HEAD(reset_list);
64
64struct aic3x_priv; 65struct aic3x_priv;
65 66
66struct aic3x_disable_nb { 67struct aic3x_disable_nb {
@@ -77,6 +78,7 @@ struct aic3x_priv {
77 struct aic3x_setup_data *setup; 78 struct aic3x_setup_data *setup;
78 void *control_data; 79 void *control_data;
79 unsigned int sysclk; 80 unsigned int sysclk;
81 struct list_head list;
80 int master; 82 int master;
81 int gpio_reset; 83 int gpio_reset;
82 int power; 84 int power;
@@ -183,7 +185,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
183 185
184 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { 186 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
185 /* find dapm widget path assoc with kcontrol */ 187 /* find dapm widget path assoc with kcontrol */
186 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 188 list_for_each_entry(path, &widget->dapm->card->paths, list) {
187 if (path->kcontrol != kcontrol) 189 if (path->kcontrol != kcontrol)
188 continue; 190 continue;
189 191
@@ -199,7 +201,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
199 } 201 }
200 202
201 if (found) 203 if (found)
202 snd_soc_dapm_sync(widget->codec); 204 snd_soc_dapm_sync(widget->dapm);
203 } 205 }
204 206
205 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); 207 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
@@ -788,17 +790,19 @@ static const struct snd_soc_dapm_route intercon_3007[] = {
788static int aic3x_add_widgets(struct snd_soc_codec *codec) 790static int aic3x_add_widgets(struct snd_soc_codec *codec)
789{ 791{
790 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 792 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
793 struct snd_soc_dapm_context *dapm = &codec->dapm;
791 794
792 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, 795 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
793 ARRAY_SIZE(aic3x_dapm_widgets)); 796 ARRAY_SIZE(aic3x_dapm_widgets));
794 797
795 /* set up audio path interconnects */ 798 /* set up audio path interconnects */
796 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 799 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
797 800
798 if (aic3x->model == AIC3X_MODEL_3007) { 801 if (aic3x->model == AIC3X_MODEL_3007) {
799 snd_soc_dapm_new_controls(codec, aic3007_dapm_widgets, 802 snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets,
800 ARRAY_SIZE(aic3007_dapm_widgets)); 803 ARRAY_SIZE(aic3007_dapm_widgets));
801 snd_soc_dapm_add_routes(codec, intercon_3007, ARRAY_SIZE(intercon_3007)); 804 snd_soc_dapm_add_routes(dapm, intercon_3007,
805 ARRAY_SIZE(intercon_3007));
802 } 806 }
803 807
804 return 0; 808 return 0;
@@ -1075,7 +1079,7 @@ static int aic3x_regulator_event(struct notifier_block *nb,
1075 * Put codec to reset and require cache sync as at least one 1079 * Put codec to reset and require cache sync as at least one
1076 * of the supplies was disabled 1080 * of the supplies was disabled
1077 */ 1081 */
1078 if (aic3x->gpio_reset >= 0) 1082 if (gpio_is_valid(aic3x->gpio_reset))
1079 gpio_set_value(aic3x->gpio_reset, 0); 1083 gpio_set_value(aic3x->gpio_reset, 0);
1080 aic3x->codec->cache_sync = 1; 1084 aic3x->codec->cache_sync = 1;
1081 } 1085 }
@@ -1102,7 +1106,7 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
1102 if (!codec->cache_sync) 1106 if (!codec->cache_sync)
1103 goto out; 1107 goto out;
1104 1108
1105 if (aic3x->gpio_reset >= 0) { 1109 if (gpio_is_valid(aic3x->gpio_reset)) {
1106 udelay(1); 1110 udelay(1);
1107 gpio_set_value(aic3x->gpio_reset, 1); 1111 gpio_set_value(aic3x->gpio_reset, 1);
1108 } 1112 }
@@ -1135,7 +1139,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1135 case SND_SOC_BIAS_ON: 1139 case SND_SOC_BIAS_ON:
1136 break; 1140 break;
1137 case SND_SOC_BIAS_PREPARE: 1141 case SND_SOC_BIAS_PREPARE:
1138 if (codec->bias_level == SND_SOC_BIAS_STANDBY && 1142 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY &&
1139 aic3x->master) { 1143 aic3x->master) {
1140 /* enable pll */ 1144 /* enable pll */
1141 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); 1145 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
@@ -1146,7 +1150,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1146 case SND_SOC_BIAS_STANDBY: 1150 case SND_SOC_BIAS_STANDBY:
1147 if (!aic3x->power) 1151 if (!aic3x->power)
1148 aic3x_set_power(codec, 1); 1152 aic3x_set_power(codec, 1);
1149 if (codec->bias_level == SND_SOC_BIAS_PREPARE && 1153 if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE &&
1150 aic3x->master) { 1154 aic3x->master) {
1151 /* disable pll */ 1155 /* disable pll */
1152 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); 1156 reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG);
@@ -1159,7 +1163,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec,
1159 aic3x_set_power(codec, 0); 1163 aic3x_set_power(codec, 0);
1160 break; 1164 break;
1161 } 1165 }
1162 codec->bias_level = level; 1166 codec->dapm.bias_level = level;
1163 1167
1164 return 0; 1168 return 0;
1165} 1169}
@@ -1344,14 +1348,28 @@ static int aic3x_init(struct snd_soc_codec *codec)
1344 return 0; 1348 return 0;
1345} 1349}
1346 1350
1351static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x)
1352{
1353 struct aic3x_priv *a;
1354
1355 list_for_each_entry(a, &reset_list, list) {
1356 if (gpio_is_valid(aic3x->gpio_reset) &&
1357 aic3x->gpio_reset == a->gpio_reset)
1358 return true;
1359 }
1360
1361 return false;
1362}
1363
1347static int aic3x_probe(struct snd_soc_codec *codec) 1364static int aic3x_probe(struct snd_soc_codec *codec)
1348{ 1365{
1349 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1366 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
1350 int ret, i; 1367 int ret, i;
1351 1368
1369 INIT_LIST_HEAD(&aic3x->list);
1352 codec->control_data = aic3x->control_data; 1370 codec->control_data = aic3x->control_data;
1353 aic3x->codec = codec; 1371 aic3x->codec = codec;
1354 codec->idle_bias_off = 1; 1372 codec->dapm.idle_bias_off = 1;
1355 1373
1356 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); 1374 ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type);
1357 if (ret != 0) { 1375 if (ret != 0) {
@@ -1359,7 +1377,8 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1359 return ret; 1377 return ret;
1360 } 1378 }
1361 1379
1362 if (aic3x->gpio_reset >= 0) { 1380 if (gpio_is_valid(aic3x->gpio_reset) &&
1381 !aic3x_is_shared_reset(aic3x)) {
1363 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset"); 1382 ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset");
1364 if (ret != 0) 1383 if (ret != 0)
1365 goto err_gpio; 1384 goto err_gpio;
@@ -1405,6 +1424,7 @@ static int aic3x_probe(struct snd_soc_codec *codec)
1405 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); 1424 snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1);
1406 1425
1407 aic3x_add_widgets(codec); 1426 aic3x_add_widgets(codec);
1427 list_add(&aic3x->list, &reset_list);
1408 1428
1409 return 0; 1429 return 0;
1410 1430
@@ -1414,10 +1434,10 @@ err_notif:
1414 &aic3x->disable_nb[i].nb); 1434 &aic3x->disable_nb[i].nb);
1415 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); 1435 regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies);
1416err_get: 1436err_get:
1417 if (aic3x->gpio_reset >= 0) 1437 if (gpio_is_valid(aic3x->gpio_reset) &&
1438 !aic3x_is_shared_reset(aic3x))
1418 gpio_free(aic3x->gpio_reset); 1439 gpio_free(aic3x->gpio_reset);
1419err_gpio: 1440err_gpio:
1420 kfree(aic3x);
1421 return ret; 1441 return ret;
1422} 1442}
1423 1443
@@ -1427,7 +1447,9 @@ static int aic3x_remove(struct snd_soc_codec *codec)
1427 int i; 1447 int i;
1428 1448
1429 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); 1449 aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1430 if (aic3x->gpio_reset >= 0) { 1450 list_del(&aic3x->list);
1451 if (gpio_is_valid(aic3x->gpio_reset) &&
1452 !aic3x_is_shared_reset(aic3x)) {
1431 gpio_set_value(aic3x->gpio_reset, 0); 1453 gpio_set_value(aic3x->gpio_reset, 0);
1432 gpio_free(aic3x->gpio_reset); 1454 gpio_free(aic3x->gpio_reset);
1433 } 1455 }
@@ -1523,21 +1545,6 @@ static struct i2c_driver aic3x_i2c_driver = {
1523 .remove = aic3x_i2c_remove, 1545 .remove = aic3x_i2c_remove,
1524 .id_table = aic3x_i2c_id, 1546 .id_table = aic3x_i2c_id,
1525}; 1547};
1526
1527static inline void aic3x_i2c_init(void)
1528{
1529 int ret;
1530
1531 ret = i2c_add_driver(&aic3x_i2c_driver);
1532 if (ret)
1533 printk(KERN_ERR "%s: error regsitering i2c driver, %d\n",
1534 __func__, ret);
1535}
1536
1537static inline void aic3x_i2c_exit(void)
1538{
1539 i2c_del_driver(&aic3x_i2c_driver);
1540}
1541#endif 1548#endif
1542 1549
1543static int __init aic3x_modinit(void) 1550static int __init aic3x_modinit(void)
diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c
index c5ab8c805771..71d7be8ac488 100644
--- a/sound/soc/codecs/tlv320dac33.c
+++ b/sound/soc/codecs/tlv320dac33.c
@@ -36,21 +36,21 @@
36#include <sound/pcm.h> 36#include <sound/pcm.h>
37#include <sound/pcm_params.h> 37#include <sound/pcm_params.h>
38#include <sound/soc.h> 38#include <sound/soc.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h> 39#include <sound/initval.h>
41#include <sound/tlv.h> 40#include <sound/tlv.h>
42 41
43#include <sound/tlv320dac33-plat.h> 42#include <sound/tlv320dac33-plat.h>
44#include "tlv320dac33.h" 43#include "tlv320dac33.h"
45 44
46#define DAC33_BUFFER_SIZE_BYTES 24576 /* bytes, 12288 16 bit words, 45/*
47 * 6144 stereo */ 46 * The internal FIFO is 24576 bytes long
48#define DAC33_BUFFER_SIZE_SAMPLES 6144 47 * It can be configured to hold 16bit or 24bit samples
49 48 * In 16bit configuration the FIFO can hold 6144 stereo samples
50#define NSAMPLE_MAX 5700 49 * In 24bit configuration the FIFO can hold 4096 stereo samples
51 50 */
52#define MODE7_LTHR 10 51#define DAC33_FIFO_SIZE_16BIT 6144
53#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10) 52#define DAC33_FIFO_SIZE_24BIT 4096
53#define DAC33_MODE7_MARGIN 10 /* Safety margin for FIFO in Mode7 */
54 54
55#define BURST_BASEFREQ_HZ 49152000 55#define BURST_BASEFREQ_HZ 49152000
56 56
@@ -100,16 +100,11 @@ struct tlv320dac33_priv {
100 unsigned int refclk; 100 unsigned int refclk;
101 101
102 unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */ 102 unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */
103 unsigned int nsample_min; /* nsample should not be lower than
104 * this */
105 unsigned int nsample_max; /* nsample should not be higher than
106 * this */
107 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ 103 enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */
104 unsigned int fifo_size; /* Size of the FIFO in samples */
108 unsigned int nsample; /* burst read amount from host */ 105 unsigned int nsample; /* burst read amount from host */
109 int mode1_latency; /* latency caused by the i2c writes in 106 int mode1_latency; /* latency caused by the i2c writes in
110 * us */ 107 * us */
111 int auto_fifo_config; /* Configure the FIFO based on the
112 * period size */
113 u8 burst_bclkdiv; /* BCLK divider value in burst mode */ 108 u8 burst_bclkdiv; /* BCLK divider value in burst mode */
114 unsigned int burst_rate; /* Interface speed in Burst modes */ 109 unsigned int burst_rate; /* Interface speed in Burst modes */
115 110
@@ -303,7 +298,6 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
303 if (unlikely(!dac33->chip_power)) 298 if (unlikely(!dac33->chip_power))
304 return; 299 return;
305 300
306 /* 44-46: DAC Control Registers */
307 /* A : DAC sample rate Fsref/1.5 */ 301 /* A : DAC sample rate Fsref/1.5 */
308 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0)); 302 dac33_write(codec, DAC33_DAC_CTRL_A, DAC33_DACRATE(0));
309 /* B : DAC src=normal, not muted */ 303 /* B : DAC src=normal, not muted */
@@ -316,8 +310,6 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
316 clock source = internal osc (?) */ 310 clock source = internal osc (?) */
317 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN); 311 dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN);
318 312
319 dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB);
320
321 /* Restore only selected registers (gains mostly) */ 313 /* Restore only selected registers (gains mostly) */
322 dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL, 314 dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL,
323 dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL)); 315 dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL));
@@ -328,6 +320,10 @@ static void dac33_init_chip(struct snd_soc_codec *codec)
328 dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL)); 320 dac33_read_reg_cache(codec, DAC33_LINEL_TO_LLO_VOL));
329 dac33_write(codec, DAC33_LINER_TO_RLO_VOL, 321 dac33_write(codec, DAC33_LINER_TO_RLO_VOL,
330 dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); 322 dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL));
323
324 dac33_write(codec, DAC33_OUT_AMP_CTRL,
325 dac33_read_reg_cache(codec, DAC33_OUT_AMP_CTRL));
326
331} 327}
332 328
333static inline int dac33_read_id(struct snd_soc_codec *codec) 329static inline int dac33_read_id(struct snd_soc_codec *codec)
@@ -357,6 +353,21 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power)
357 dac33_write(codec, DAC33_PWR_CTRL, reg); 353 dac33_write(codec, DAC33_PWR_CTRL, reg);
358} 354}
359 355
356static inline void dac33_disable_digital(struct snd_soc_codec *codec)
357{
358 u8 reg;
359
360 /* Stop the DAI clock */
361 reg = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B);
362 reg &= ~DAC33_BCLKON;
363 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg);
364
365 /* Power down the Oscillator, and DACs */
366 reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL);
367 reg &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB);
368 dac33_write(codec, DAC33_PWR_CTRL, reg);
369}
370
360static int dac33_hard_power(struct snd_soc_codec *codec, int power) 371static int dac33_hard_power(struct snd_soc_codec *codec, int power)
361{ 372{
362 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 373 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
@@ -405,7 +416,7 @@ exit:
405 return ret; 416 return ret;
406} 417}
407 418
408static int playback_event(struct snd_soc_dapm_widget *w, 419static int dac33_playback_event(struct snd_soc_dapm_widget *w,
409 struct snd_kcontrol *kcontrol, int event) 420 struct snd_kcontrol *kcontrol, int event)
410{ 421{
411 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec); 422 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec);
@@ -417,77 +428,13 @@ static int playback_event(struct snd_soc_dapm_widget *w,
417 dac33_prepare_chip(dac33->substream); 428 dac33_prepare_chip(dac33->substream);
418 } 429 }
419 break; 430 break;
431 case SND_SOC_DAPM_POST_PMD:
432 dac33_disable_digital(w->codec);
433 break;
420 } 434 }
421 return 0; 435 return 0;
422} 436}
423 437
424static int dac33_get_nsample(struct snd_kcontrol *kcontrol,
425 struct snd_ctl_elem_value *ucontrol)
426{
427 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
428 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
429
430 ucontrol->value.integer.value[0] = dac33->nsample;
431
432 return 0;
433}
434
435static int dac33_set_nsample(struct snd_kcontrol *kcontrol,
436 struct snd_ctl_elem_value *ucontrol)
437{
438 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
439 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
440 int ret = 0;
441
442 if (dac33->nsample == ucontrol->value.integer.value[0])
443 return 0;
444
445 if (ucontrol->value.integer.value[0] < dac33->nsample_min ||
446 ucontrol->value.integer.value[0] > dac33->nsample_max) {
447 ret = -EINVAL;
448 } else {
449 dac33->nsample = ucontrol->value.integer.value[0];
450 /* Re calculate the burst time */
451 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
452 dac33->nsample);
453 }
454
455 return ret;
456}
457
458static int dac33_get_uthr(struct snd_kcontrol *kcontrol,
459 struct snd_ctl_elem_value *ucontrol)
460{
461 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
462 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
463
464 ucontrol->value.integer.value[0] = dac33->uthr;
465
466 return 0;
467}
468
469static int dac33_set_uthr(struct snd_kcontrol *kcontrol,
470 struct snd_ctl_elem_value *ucontrol)
471{
472 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
473 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
474 int ret = 0;
475
476 if (dac33->substream)
477 return -EBUSY;
478
479 if (dac33->uthr == ucontrol->value.integer.value[0])
480 return 0;
481
482 if (ucontrol->value.integer.value[0] < (MODE7_LTHR + 10) ||
483 ucontrol->value.integer.value[0] > MODE7_UTHR)
484 ret = -EINVAL;
485 else
486 dac33->uthr = ucontrol->value.integer.value[0];
487
488 return ret;
489}
490
491static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, 438static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol,
492 struct snd_ctl_elem_value *ucontrol) 439 struct snd_ctl_elem_value *ucontrol)
493{ 440{
@@ -572,13 +519,6 @@ static const struct snd_kcontrol_new dac33_mode_snd_controls[] = {
572 dac33_get_fifo_mode, dac33_set_fifo_mode), 519 dac33_get_fifo_mode, dac33_set_fifo_mode),
573}; 520};
574 521
575static const struct snd_kcontrol_new dac33_fifo_snd_controls[] = {
576 SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0,
577 dac33_get_nsample, dac33_set_nsample),
578 SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0,
579 dac33_get_uthr, dac33_set_uthr),
580};
581
582/* Analog bypass */ 522/* Analog bypass */
583static const struct snd_kcontrol_new dac33_dapm_abypassl_control = 523static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
584 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1); 524 SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1);
@@ -586,6 +526,25 @@ static const struct snd_kcontrol_new dac33_dapm_abypassl_control =
586static const struct snd_kcontrol_new dac33_dapm_abypassr_control = 526static const struct snd_kcontrol_new dac33_dapm_abypassr_control =
587 SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1); 527 SOC_DAPM_SINGLE("Switch", DAC33_LINER_TO_RLO_VOL, 7, 1, 1);
588 528
529/* LOP L/R invert selection */
530static const char *dac33_lr_lom_texts[] = {"DAC", "LOP"};
531
532static const struct soc_enum dac33_left_lom_enum =
533 SOC_ENUM_SINGLE(DAC33_OUT_AMP_CTRL, 3,
534 ARRAY_SIZE(dac33_lr_lom_texts),
535 dac33_lr_lom_texts);
536
537static const struct snd_kcontrol_new dac33_dapm_left_lom_control =
538SOC_DAPM_ENUM("Route", dac33_left_lom_enum);
539
540static const struct soc_enum dac33_right_lom_enum =
541 SOC_ENUM_SINGLE(DAC33_OUT_AMP_CTRL, 2,
542 ARRAY_SIZE(dac33_lr_lom_texts),
543 dac33_lr_lom_texts);
544
545static const struct snd_kcontrol_new dac33_dapm_right_lom_control =
546SOC_DAPM_ENUM("Route", dac33_right_lom_enum);
547
589static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = { 548static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
590 SND_SOC_DAPM_OUTPUT("LEFT_LO"), 549 SND_SOC_DAPM_OUTPUT("LEFT_LO"),
591 SND_SOC_DAPM_OUTPUT("RIGHT_LO"), 550 SND_SOC_DAPM_OUTPUT("RIGHT_LO"),
@@ -593,8 +552,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
593 SND_SOC_DAPM_INPUT("LINEL"), 552 SND_SOC_DAPM_INPUT("LINEL"),
594 SND_SOC_DAPM_INPUT("LINER"), 553 SND_SOC_DAPM_INPUT("LINER"),
595 554
596 SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0), 555 SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0),
597 SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0), 556 SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0),
598 557
599 /* Analog bypass */ 558 /* Analog bypass */
600 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0, 559 SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0,
@@ -602,12 +561,30 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = {
602 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0, 561 SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0,
603 &dac33_dapm_abypassr_control), 562 &dac33_dapm_abypassr_control),
604 563
605 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power", 564 SND_SOC_DAPM_MUX("Left LOM Inverted From", SND_SOC_NOPM, 0, 0,
565 &dac33_dapm_left_lom_control),
566 SND_SOC_DAPM_MUX("Right LOM Inverted From", SND_SOC_NOPM, 0, 0,
567 &dac33_dapm_right_lom_control),
568 /*
569 * For DAPM path, when only the anlog bypass path is enabled, and the
570 * LOP inverted from the corresponding DAC side.
571 * This is needed, so we can attach the DAC power supply in this case.
572 */
573 SND_SOC_DAPM_PGA("Left Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
574 SND_SOC_DAPM_PGA("Right Bypass PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
575
576 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amplifier",
606 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0), 577 DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0),
607 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power", 578 SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier",
608 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0), 579 DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0),
609 580
610 SND_SOC_DAPM_PRE("Prepare Playback", playback_event), 581 SND_SOC_DAPM_SUPPLY("Left DAC Power",
582 DAC33_LDAC_PWR_CTRL, 2, 0, NULL, 0),
583 SND_SOC_DAPM_SUPPLY("Right DAC Power",
584 DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0),
585
586 SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event),
587 SND_SOC_DAPM_POST("Post Playback", dac33_playback_event),
611}; 588};
612 589
613static const struct snd_soc_dapm_route audio_map[] = { 590static const struct snd_soc_dapm_route audio_map[] = {
@@ -615,24 +592,39 @@ static const struct snd_soc_dapm_route audio_map[] = {
615 {"Analog Left Bypass", "Switch", "LINEL"}, 592 {"Analog Left Bypass", "Switch", "LINEL"},
616 {"Analog Right Bypass", "Switch", "LINER"}, 593 {"Analog Right Bypass", "Switch", "LINER"},
617 594
618 {"Output Left Amp Power", NULL, "DACL"}, 595 {"Output Left Amplifier", NULL, "DACL"},
619 {"Output Right Amp Power", NULL, "DACR"}, 596 {"Output Right Amplifier", NULL, "DACR"},
620 597
621 {"Output Left Amp Power", NULL, "Analog Left Bypass"}, 598 {"Left Bypass PGA", NULL, "Analog Left Bypass"},
622 {"Output Right Amp Power", NULL, "Analog Right Bypass"}, 599 {"Right Bypass PGA", NULL, "Analog Right Bypass"},
600
601 {"Left LOM Inverted From", "DAC", "Left Bypass PGA"},
602 {"Right LOM Inverted From", "DAC", "Right Bypass PGA"},
603 {"Left LOM Inverted From", "LOP", "Analog Left Bypass"},
604 {"Right LOM Inverted From", "LOP", "Analog Right Bypass"},
605
606 {"Output Left Amplifier", NULL, "Left LOM Inverted From"},
607 {"Output Right Amplifier", NULL, "Right LOM Inverted From"},
608
609 {"DACL", NULL, "Left DAC Power"},
610 {"DACR", NULL, "Right DAC Power"},
611
612 {"Left Bypass PGA", NULL, "Left DAC Power"},
613 {"Right Bypass PGA", NULL, "Right DAC Power"},
623 614
624 /* output */ 615 /* output */
625 {"LEFT_LO", NULL, "Output Left Amp Power"}, 616 {"LEFT_LO", NULL, "Output Left Amplifier"},
626 {"RIGHT_LO", NULL, "Output Right Amp Power"}, 617 {"RIGHT_LO", NULL, "Output Right Amplifier"},
627}; 618};
628 619
629static int dac33_add_widgets(struct snd_soc_codec *codec) 620static int dac33_add_widgets(struct snd_soc_codec *codec)
630{ 621{
631 snd_soc_dapm_new_controls(codec, dac33_dapm_widgets, 622 struct snd_soc_dapm_context *dapm = &codec->dapm;
632 ARRAY_SIZE(dac33_dapm_widgets));
633 623
624 snd_soc_dapm_new_controls(dapm, dac33_dapm_widgets,
625 ARRAY_SIZE(dac33_dapm_widgets));
634 /* set up audio path interconnects */ 626 /* set up audio path interconnects */
635 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 627 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
636 628
637 return 0; 629 return 0;
638} 630}
@@ -640,16 +632,18 @@ static int dac33_add_widgets(struct snd_soc_codec *codec)
640static int dac33_set_bias_level(struct snd_soc_codec *codec, 632static int dac33_set_bias_level(struct snd_soc_codec *codec,
641 enum snd_soc_bias_level level) 633 enum snd_soc_bias_level level)
642{ 634{
635 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
643 int ret; 636 int ret;
644 637
645 switch (level) { 638 switch (level) {
646 case SND_SOC_BIAS_ON: 639 case SND_SOC_BIAS_ON:
647 dac33_soft_power(codec, 1); 640 if (!dac33->substream)
641 dac33_soft_power(codec, 1);
648 break; 642 break;
649 case SND_SOC_BIAS_PREPARE: 643 case SND_SOC_BIAS_PREPARE:
650 break; 644 break;
651 case SND_SOC_BIAS_STANDBY: 645 case SND_SOC_BIAS_STANDBY:
652 if (codec->bias_level == SND_SOC_BIAS_OFF) { 646 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
653 /* Coming from OFF, switch on the codec */ 647 /* Coming from OFF, switch on the codec */
654 ret = dac33_hard_power(codec, 1); 648 ret = dac33_hard_power(codec, 1);
655 if (ret != 0) 649 if (ret != 0)
@@ -660,14 +654,14 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec,
660 break; 654 break;
661 case SND_SOC_BIAS_OFF: 655 case SND_SOC_BIAS_OFF:
662 /* Do not power off, when the codec is already off */ 656 /* Do not power off, when the codec is already off */
663 if (codec->bias_level == SND_SOC_BIAS_OFF) 657 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
664 return 0; 658 return 0;
665 ret = dac33_hard_power(codec, 0); 659 ret = dac33_hard_power(codec, 0);
666 if (ret != 0) 660 if (ret != 0)
667 return ret; 661 return ret;
668 break; 662 break;
669 } 663 }
670 codec->bias_level = level; 664 codec->dapm.bias_level = level;
671 665
672 return 0; 666 return 0;
673} 667}
@@ -705,7 +699,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33)
705 spin_unlock_irq(&dac33->lock); 699 spin_unlock_irq(&dac33->lock);
706 700
707 dac33_write16(codec, DAC33_PREFILL_MSB, 701 dac33_write16(codec, DAC33_PREFILL_MSB,
708 DAC33_THRREG(MODE7_LTHR)); 702 DAC33_THRREG(DAC33_MODE7_MARGIN));
709 703
710 /* Enable Upper Threshold IRQ */ 704 /* Enable Upper Threshold IRQ */
711 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT); 705 dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT);
@@ -815,6 +809,8 @@ static int dac33_startup(struct snd_pcm_substream *substream,
815 /* Stream started, save the substream pointer */ 809 /* Stream started, save the substream pointer */
816 dac33->substream = substream; 810 dac33->substream = substream;
817 811
812 snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
813
818 return 0; 814 return 0;
819} 815}
820 816
@@ -826,18 +822,17 @@ static void dac33_shutdown(struct snd_pcm_substream *substream,
826 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); 822 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
827 823
828 dac33->substream = NULL; 824 dac33->substream = NULL;
829
830 /* Reset the nSample restrictions */
831 dac33->nsample_min = 0;
832 dac33->nsample_max = NSAMPLE_MAX;
833} 825}
834 826
827#define CALC_BURST_RATE(bclkdiv, bclk_per_sample) \
828 (BURST_BASEFREQ_HZ / bclkdiv / bclk_per_sample)
835static int dac33_hw_params(struct snd_pcm_substream *substream, 829static int dac33_hw_params(struct snd_pcm_substream *substream,
836 struct snd_pcm_hw_params *params, 830 struct snd_pcm_hw_params *params,
837 struct snd_soc_dai *dai) 831 struct snd_soc_dai *dai)
838{ 832{
839 struct snd_soc_pcm_runtime *rtd = substream->private_data; 833 struct snd_soc_pcm_runtime *rtd = substream->private_data;
840 struct snd_soc_codec *codec = rtd->codec; 834 struct snd_soc_codec *codec = rtd->codec;
835 struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec);
841 836
842 /* Check parameters for validity */ 837 /* Check parameters for validity */
843 switch (params_rate(params)) { 838 switch (params_rate(params)) {
@@ -852,6 +847,12 @@ static int dac33_hw_params(struct snd_pcm_substream *substream,
852 847
853 switch (params_format(params)) { 848 switch (params_format(params)) {
854 case SNDRV_PCM_FORMAT_S16_LE: 849 case SNDRV_PCM_FORMAT_S16_LE:
850 dac33->fifo_size = DAC33_FIFO_SIZE_16BIT;
851 dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 32);
852 break;
853 case SNDRV_PCM_FORMAT_S32_LE:
854 dac33->fifo_size = DAC33_FIFO_SIZE_24BIT;
855 dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 64);
855 break; 856 break;
856 default: 857 default:
857 dev_err(codec->dev, "unsupported format %d\n", 858 dev_err(codec->dev, "unsupported format %d\n",
@@ -906,6 +907,9 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
906 aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16); 907 aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16);
907 fifoctrl_a |= DAC33_WIDTH; 908 fifoctrl_a |= DAC33_WIDTH;
908 break; 909 break;
910 case SNDRV_PCM_FORMAT_S32_LE:
911 aictrl_a |= (DAC33_NCYCL_32 | DAC33_WLEN_24);
912 break;
909 default: 913 default:
910 dev_err(codec->dev, "unsupported format %d\n", 914 dev_err(codec->dev, "unsupported format %d\n",
911 substream->runtime->format); 915 substream->runtime->format);
@@ -1040,7 +1044,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
1040 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 1044 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C,
1041 dac33->burst_bclkdiv); 1045 dac33->burst_bclkdiv);
1042 else 1046 else
1043 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32); 1047 if (substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE)
1048 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32);
1049 else
1050 dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 16);
1044 1051
1045 switch (dac33->fifo_mode) { 1052 switch (dac33->fifo_mode) {
1046 case DAC33_FIFO_MODE1: 1053 case DAC33_FIFO_MODE1:
@@ -1053,7 +1060,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream)
1053 * at the bottom, and also at the top of the FIFO 1060 * at the bottom, and also at the top of the FIFO
1054 */ 1061 */
1055 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr)); 1062 dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr));
1056 dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR)); 1063 dac33_write16(codec, DAC33_LTHR_MSB,
1064 DAC33_THRREG(DAC33_MODE7_MARGIN));
1057 break; 1065 break;
1058 default: 1066 default:
1059 break; 1067 break;
@@ -1082,42 +1090,21 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1082 /* Number of samples under i2c latency */ 1090 /* Number of samples under i2c latency */
1083 dac33->alarm_threshold = US_TO_SAMPLES(rate, 1091 dac33->alarm_threshold = US_TO_SAMPLES(rate,
1084 dac33->mode1_latency); 1092 dac33->mode1_latency);
1085 nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - 1093 nsample_limit = dac33->fifo_size - dac33->alarm_threshold;
1086 dac33->alarm_threshold; 1094
1087 1095 if (period_size <= dac33->alarm_threshold)
1088 if (dac33->auto_fifo_config) {
1089 if (period_size <= dac33->alarm_threshold)
1090 /*
1091 * Configure nSamaple to number of periods,
1092 * which covers the latency requironment.
1093 */
1094 dac33->nsample = period_size *
1095 ((dac33->alarm_threshold / period_size) +
1096 (dac33->alarm_threshold % period_size ?
1097 1 : 0));
1098 else if (period_size > nsample_limit)
1099 dac33->nsample = nsample_limit;
1100 else
1101 dac33->nsample = period_size;
1102 } else {
1103 /* nSample time shall not be shorter than i2c latency */
1104 dac33->nsample_min = dac33->alarm_threshold;
1105 /* 1096 /*
1106 * nSample should not be bigger than alsa buffer minus 1097 * Configure nSamaple to number of periods,
1107 * size of one period to avoid overruns 1098 * which covers the latency requironment.
1108 */ 1099 */
1109 dac33->nsample_max = substream->runtime->buffer_size - 1100 dac33->nsample = period_size *
1110 period_size; 1101 ((dac33->alarm_threshold / period_size) +
1111 1102 (dac33->alarm_threshold % period_size ?
1112 if (dac33->nsample_max > nsample_limit) 1103 1 : 0));
1113 dac33->nsample_max = nsample_limit; 1104 else if (period_size > nsample_limit)
1114 1105 dac33->nsample = nsample_limit;
1115 /* Correct the nSample if it is outside of the ranges */ 1106 else
1116 if (dac33->nsample < dac33->nsample_min) 1107 dac33->nsample = period_size;
1117 dac33->nsample = dac33->nsample_min;
1118 if (dac33->nsample > dac33->nsample_max)
1119 dac33->nsample = dac33->nsample_max;
1120 }
1121 1108
1122 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate, 1109 dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate,
1123 dac33->nsample); 1110 dac33->nsample);
@@ -1125,19 +1112,16 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream)
1125 dac33->t_stamp2 = 0; 1112 dac33->t_stamp2 = 0;
1126 break; 1113 break;
1127 case DAC33_FIFO_MODE7: 1114 case DAC33_FIFO_MODE7:
1128 if (dac33->auto_fifo_config) { 1115 dac33->uthr = UTHR_FROM_PERIOD_SIZE(period_size, rate,
1129 dac33->uthr = UTHR_FROM_PERIOD_SIZE( 1116 dac33->burst_rate) + 9;
1130 period_size, 1117 if (dac33->uthr > (dac33->fifo_size - DAC33_MODE7_MARGIN))
1131 rate, 1118 dac33->uthr = dac33->fifo_size - DAC33_MODE7_MARGIN;
1132 dac33->burst_rate) + 9; 1119 if (dac33->uthr < (DAC33_MODE7_MARGIN + 10))
1133 if (dac33->uthr > MODE7_UTHR) 1120 dac33->uthr = (DAC33_MODE7_MARGIN + 10);
1134 dac33->uthr = MODE7_UTHR; 1121
1135 if (dac33->uthr < (MODE7_LTHR + 10))
1136 dac33->uthr = (MODE7_LTHR + 10);
1137 }
1138 dac33->mode7_us_to_lthr = 1122 dac33->mode7_us_to_lthr =
1139 SAMPLES_TO_US(substream->runtime->rate, 1123 SAMPLES_TO_US(substream->runtime->rate,
1140 dac33->uthr - MODE7_LTHR + 1); 1124 dac33->uthr - DAC33_MODE7_MARGIN + 1);
1141 dac33->t_stamp1 = 0; 1125 dac33->t_stamp1 = 0;
1142 break; 1126 break;
1143 default: 1127 default:
@@ -1255,8 +1239,8 @@ static snd_pcm_sframes_t dac33_dai_delay(
1255 samples += (samples_in - samples_out); 1239 samples += (samples_in - samples_out);
1256 1240
1257 if (likely(samples > 0)) 1241 if (likely(samples > 0))
1258 delay = samples > DAC33_BUFFER_SIZE_SAMPLES ? 1242 delay = samples > dac33->fifo_size ?
1259 DAC33_BUFFER_SIZE_SAMPLES : samples; 1243 dac33->fifo_size : samples;
1260 else 1244 else
1261 delay = 0; 1245 delay = 0;
1262 } 1246 }
@@ -1308,7 +1292,7 @@ static snd_pcm_sframes_t dac33_dai_delay(
1308 samples_in = US_TO_SAMPLES( 1292 samples_in = US_TO_SAMPLES(
1309 dac33->burst_rate, 1293 dac33->burst_rate,
1310 time_delta); 1294 time_delta);
1311 delay = MODE7_LTHR + samples_in - samples_out; 1295 delay = DAC33_MODE7_MARGIN + samples_in - samples_out;
1312 1296
1313 if (unlikely(delay > uthr)) 1297 if (unlikely(delay > uthr))
1314 delay = uthr; 1298 delay = uthr;
@@ -1415,7 +1399,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1415 1399
1416 codec->control_data = dac33->control_data; 1400 codec->control_data = dac33->control_data;
1417 codec->hw_write = (hw_write_t) i2c_master_send; 1401 codec->hw_write = (hw_write_t) i2c_master_send;
1418 codec->idle_bias_off = 1; 1402 codec->dapm.idle_bias_off = 1;
1419 dac33->codec = codec; 1403 dac33->codec = codec;
1420 1404
1421 /* Read the tlv320dac33 ID registers */ 1405 /* Read the tlv320dac33 ID registers */
@@ -1459,14 +1443,10 @@ static int dac33_soc_probe(struct snd_soc_codec *codec)
1459 snd_soc_add_controls(codec, dac33_snd_controls, 1443 snd_soc_add_controls(codec, dac33_snd_controls,
1460 ARRAY_SIZE(dac33_snd_controls)); 1444 ARRAY_SIZE(dac33_snd_controls));
1461 /* Only add the FIFO controls, if we have valid IRQ number */ 1445 /* Only add the FIFO controls, if we have valid IRQ number */
1462 if (dac33->irq >= 0) { 1446 if (dac33->irq >= 0)
1463 snd_soc_add_controls(codec, dac33_mode_snd_controls, 1447 snd_soc_add_controls(codec, dac33_mode_snd_controls,
1464 ARRAY_SIZE(dac33_mode_snd_controls)); 1448 ARRAY_SIZE(dac33_mode_snd_controls));
1465 /* FIFO usage controls only, if autoio config is not selected */ 1449
1466 if (!dac33->auto_fifo_config)
1467 snd_soc_add_controls(codec, dac33_fifo_snd_controls,
1468 ARRAY_SIZE(dac33_fifo_snd_controls));
1469 }
1470 dac33_add_widgets(codec); 1450 dac33_add_widgets(codec);
1471 1451
1472err_power: 1452err_power:
@@ -1515,7 +1495,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = {
1515 1495
1516#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ 1496#define DAC33_RATES (SNDRV_PCM_RATE_44100 | \
1517 SNDRV_PCM_RATE_48000) 1497 SNDRV_PCM_RATE_48000)
1518#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE 1498#define DAC33_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
1519 1499
1520static struct snd_soc_dai_ops dac33_dai_ops = { 1500static struct snd_soc_dai_ops dac33_dai_ops = {
1521 .startup = dac33_startup, 1501 .startup = dac33_startup,
@@ -1563,17 +1543,11 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client,
1563 1543
1564 dac33->power_gpio = pdata->power_gpio; 1544 dac33->power_gpio = pdata->power_gpio;
1565 dac33->burst_bclkdiv = pdata->burst_bclkdiv; 1545 dac33->burst_bclkdiv = pdata->burst_bclkdiv;
1566 /* Pre calculate the burst rate */
1567 dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32;
1568 dac33->keep_bclk = pdata->keep_bclk; 1546 dac33->keep_bclk = pdata->keep_bclk;
1569 dac33->auto_fifo_config = pdata->auto_fifo_config;
1570 dac33->mode1_latency = pdata->mode1_latency; 1547 dac33->mode1_latency = pdata->mode1_latency;
1571 if (!dac33->mode1_latency) 1548 if (!dac33->mode1_latency)
1572 dac33->mode1_latency = 10000; /* 10ms */ 1549 dac33->mode1_latency = 10000; /* 10ms */
1573 dac33->irq = client->irq; 1550 dac33->irq = client->irq;
1574 dac33->nsample = NSAMPLE_MAX;
1575 dac33->nsample_max = NSAMPLE_MAX;
1576 dac33->uthr = MODE7_UTHR;
1577 /* Disable FIFO use by default */ 1551 /* Disable FIFO use by default */
1578 dac33->fifo_mode = DAC33_FIFO_BYPASS; 1552 dac33->fifo_mode = DAC33_FIFO_BYPASS;
1579 1553
diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c
index d2c243095673..1f1ac8110bef 100644
--- a/sound/soc/codecs/tpa6130a2.c
+++ b/sound/soc/codecs/tpa6130a2.c
@@ -29,7 +29,6 @@
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <sound/tpa6130a2-plat.h> 30#include <sound/tpa6130a2-plat.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/tlv.h> 32#include <sound/tlv.h>
34 33
35#include "tpa6130a2.h" 34#include "tpa6130a2.h"
@@ -42,7 +41,7 @@ struct tpa6130a2_data {
42 unsigned char regs[TPA6130A2_CACHEREGNUM]; 41 unsigned char regs[TPA6130A2_CACHEREGNUM];
43 struct regulator *supply; 42 struct regulator *supply;
44 int power_gpio; 43 int power_gpio;
45 unsigned char power_state; 44 u8 power_state:1;
46 enum tpa_model id; 45 enum tpa_model id;
47}; 46};
48 47
@@ -117,7 +116,7 @@ static int tpa6130a2_initialize(void)
117 return ret; 116 return ret;
118} 117}
119 118
120static int tpa6130a2_power(int power) 119static int tpa6130a2_power(u8 power)
121{ 120{
122 struct tpa6130a2_data *data; 121 struct tpa6130a2_data *data;
123 u8 val; 122 u8 val;
@@ -127,17 +126,19 @@ static int tpa6130a2_power(int power)
127 data = i2c_get_clientdata(tpa6130a2_client); 126 data = i2c_get_clientdata(tpa6130a2_client);
128 127
129 mutex_lock(&data->mutex); 128 mutex_lock(&data->mutex);
130 if (power && !data->power_state) { 129 if (power == data->power_state)
131 /* Power on */ 130 goto exit;
132 if (data->power_gpio >= 0)
133 gpio_set_value(data->power_gpio, 1);
134 131
132 if (power) {
135 ret = regulator_enable(data->supply); 133 ret = regulator_enable(data->supply);
136 if (ret != 0) { 134 if (ret != 0) {
137 dev_err(&tpa6130a2_client->dev, 135 dev_err(&tpa6130a2_client->dev,
138 "Failed to enable supply: %d\n", ret); 136 "Failed to enable supply: %d\n", ret);
139 goto exit; 137 goto exit;
140 } 138 }
139 /* Power on */
140 if (data->power_gpio >= 0)
141 gpio_set_value(data->power_gpio, 1);
141 142
142 data->power_state = 1; 143 data->power_state = 1;
143 ret = tpa6130a2_initialize(); 144 ret = tpa6130a2_initialize();
@@ -150,12 +151,7 @@ static int tpa6130a2_power(int power)
150 data->power_state = 0; 151 data->power_state = 0;
151 goto exit; 152 goto exit;
152 } 153 }
153 154 } else {
154 /* Clear SWS */
155 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
156 val &= ~TPA6130A2_SWS;
157 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
158 } else if (!power && data->power_state) {
159 /* set SWS */ 155 /* set SWS */
160 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 156 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
161 val |= TPA6130A2_SWS; 157 val |= TPA6130A2_SWS;
@@ -300,6 +296,7 @@ static void tpa6130a2_channel_enable(u8 channel, int enable)
300 /* Enable amplifier */ 296 /* Enable amplifier */
301 val = tpa6130a2_read(TPA6130A2_REG_CONTROL); 297 val = tpa6130a2_read(TPA6130A2_REG_CONTROL);
302 val |= channel; 298 val |= channel;
299 val &= ~TPA6130A2_SWS;
303 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); 300 tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val);
304 301
305 /* Unmute channel */ 302 /* Unmute channel */
@@ -320,72 +317,24 @@ static void tpa6130a2_channel_enable(u8 channel, int enable)
320 } 317 }
321} 318}
322 319
323static int tpa6130a2_left_event(struct snd_soc_dapm_widget *w, 320int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable)
324 struct snd_kcontrol *kcontrol, int event)
325{
326 switch (event) {
327 case SND_SOC_DAPM_POST_PMU:
328 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 1);
329 break;
330 case SND_SOC_DAPM_POST_PMD:
331 tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 0);
332 break;
333 }
334 return 0;
335}
336
337static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w,
338 struct snd_kcontrol *kcontrol, int event)
339{
340 switch (event) {
341 case SND_SOC_DAPM_POST_PMU:
342 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 1);
343 break;
344 case SND_SOC_DAPM_POST_PMD:
345 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 0);
346 break;
347 }
348 return 0;
349}
350
351static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w,
352 struct snd_kcontrol *kcontrol, int event)
353{ 321{
354 int ret = 0; 322 int ret = 0;
355 323 if (enable) {
356 switch (event) {
357 case SND_SOC_DAPM_POST_PMU:
358 ret = tpa6130a2_power(1); 324 ret = tpa6130a2_power(1);
359 break; 325 if (ret < 0)
360 case SND_SOC_DAPM_POST_PMD: 326 return ret;
327 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
328 1);
329 } else {
330 tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L,
331 0);
361 ret = tpa6130a2_power(0); 332 ret = tpa6130a2_power(0);
362 break;
363 } 333 }
334
364 return ret; 335 return ret;
365} 336}
366 337EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable);
367static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = {
368 SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM,
369 0, 0, NULL, 0, tpa6130a2_left_event,
370 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
371 SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM,
372 0, 0, NULL, 0, tpa6130a2_right_event,
373 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
374 SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM,
375 0, 0, tpa6130a2_supply_event,
376 SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD),
377 /* Outputs */
378 SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Left"),
379 SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Right"),
380};
381
382static const struct snd_soc_dapm_route audio_map[] = {
383 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"},
384 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"},
385
386 {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"},
387 {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"},
388};
389 338
390int tpa6130a2_add_controls(struct snd_soc_codec *codec) 339int tpa6130a2_add_controls(struct snd_soc_codec *codec)
391{ 340{
@@ -396,18 +345,12 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec)
396 345
397 data = i2c_get_clientdata(tpa6130a2_client); 346 data = i2c_get_clientdata(tpa6130a2_client);
398 347
399 snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets,
400 ARRAY_SIZE(tpa6130a2_dapm_widgets));
401
402 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map));
403
404 if (data->id == TPA6140A2) 348 if (data->id == TPA6140A2)
405 return snd_soc_add_controls(codec, tpa6140a2_controls, 349 return snd_soc_add_controls(codec, tpa6140a2_controls,
406 ARRAY_SIZE(tpa6140a2_controls)); 350 ARRAY_SIZE(tpa6140a2_controls));
407 else 351 else
408 return snd_soc_add_controls(codec, tpa6130a2_controls, 352 return snd_soc_add_controls(codec, tpa6130a2_controls,
409 ARRAY_SIZE(tpa6130a2_controls)); 353 ARRAY_SIZE(tpa6130a2_controls));
410
411} 354}
412EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); 355EXPORT_SYMBOL_GPL(tpa6130a2_add_controls);
413 356
diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h
index 57e867fd86d1..5df49c8756b2 100644
--- a/sound/soc/codecs/tpa6130a2.h
+++ b/sound/soc/codecs/tpa6130a2.h
@@ -57,5 +57,6 @@
57#define TPA6130A2_VERSION_MASK (0x0f) 57#define TPA6130A2_VERSION_MASK (0x0f)
58 58
59extern int tpa6130a2_add_controls(struct snd_soc_codec *codec); 59extern int tpa6130a2_add_controls(struct snd_soc_codec *codec);
60extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable);
60 61
61#endif /* __TPA6130A2_H__ */ 62#endif /* __TPA6130A2_H__ */
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index cbebec6ba1ba..e4d464b937d6 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -32,7 +32,6 @@
32#include <sound/pcm.h> 32#include <sound/pcm.h>
33#include <sound/pcm_params.h> 33#include <sound/pcm_params.h>
34#include <sound/soc.h> 34#include <sound/soc.h>
35#include <sound/soc-dapm.h>
36#include <sound/initval.h> 35#include <sound/initval.h>
37#include <sound/tlv.h> 36#include <sound/tlv.h>
38 37
@@ -233,6 +232,16 @@ static int twl4030_write(struct snd_soc_codec *codec,
233 return 0; 232 return 0;
234} 233}
235 234
235static inline void twl4030_wait_ms(int time)
236{
237 if (time < 60) {
238 time *= 1000;
239 usleep_range(time, time + 500);
240 } else {
241 msleep(time);
242 }
243}
244
236static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) 245static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable)
237{ 246{
238 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 247 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
@@ -338,10 +347,14 @@ static void twl4030_init_chip(struct snd_soc_codec *codec)
338 twl4030_write(codec, TWL4030_REG_ANAMICL, 347 twl4030_write(codec, TWL4030_REG_ANAMICL,
339 reg | TWL4030_CNCL_OFFSET_START); 348 reg | TWL4030_CNCL_OFFSET_START);
340 349
341 /* wait for offset cancellation to complete */ 350 /*
351 * Wait for offset cancellation to complete.
352 * Since this takes a while, do not slam the i2c.
353 * Start polling the status after ~20ms.
354 */
355 msleep(20);
342 do { 356 do {
343 /* this takes a little while, so don't slam i2c */ 357 usleep_range(1000, 2000);
344 udelay(2000);
345 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, 358 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte,
346 TWL4030_REG_ANAMICL); 359 TWL4030_REG_ANAMICL);
347 } while ((i++ < 100) && 360 } while ((i++ < 100) &&
@@ -725,9 +738,12 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
725 /* Base values for ramp delay calculation: 2^19 - 2^26 */ 738 /* Base values for ramp delay calculation: 2^19 - 2^26 */
726 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 739 unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304,
727 8388608, 16777216, 33554432, 67108864}; 740 8388608, 16777216, 33554432, 67108864};
741 unsigned int delay;
728 742
729 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); 743 hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET);
730 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); 744 hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET);
745 delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] /
746 twl4030->sysclk) + 1;
731 747
732 /* Enable external mute control, this dramatically reduces 748 /* Enable external mute control, this dramatically reduces
733 * the pop-noise */ 749 * the pop-noise */
@@ -751,16 +767,14 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp)
751 hs_pop |= TWL4030_RAMP_EN; 767 hs_pop |= TWL4030_RAMP_EN;
752 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 768 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
753 /* Wait ramp delay time + 1, so the VMID can settle */ 769 /* Wait ramp delay time + 1, so the VMID can settle */
754 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / 770 twl4030_wait_ms(delay);
755 twl4030->sysclk) + 1);
756 } else { 771 } else {
757 /* Headset ramp-down _not_ according to 772 /* Headset ramp-down _not_ according to
758 * the TRM, but in a way that it is working */ 773 * the TRM, but in a way that it is working */
759 hs_pop &= ~TWL4030_RAMP_EN; 774 hs_pop &= ~TWL4030_RAMP_EN;
760 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); 775 twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop);
761 /* Wait ramp delay time + 1, so the VMID can settle */ 776 /* Wait ramp delay time + 1, so the VMID can settle */
762 mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / 777 twl4030_wait_ms(delay);
763 twl4030->sysclk) + 1);
764 /* Bypass the reg_cache to mute the headset */ 778 /* Bypass the reg_cache to mute the headset */
765 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, 779 twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
766 hs_gain & (~0x0f), 780 hs_gain & (~0x0f),
@@ -835,7 +849,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w,
835 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); 849 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec);
836 850
837 if (twl4030->digimic_delay) 851 if (twl4030->digimic_delay)
838 mdelay(twl4030->digimic_delay); 852 twl4030_wait_ms(twl4030->digimic_delay);
839 return 0; 853 return 0;
840} 854}
841 855
@@ -1621,10 +1635,11 @@ static const struct snd_soc_dapm_route intercon[] = {
1621 1635
1622static int twl4030_add_widgets(struct snd_soc_codec *codec) 1636static int twl4030_add_widgets(struct snd_soc_codec *codec)
1623{ 1637{
1624 snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets, 1638 struct snd_soc_dapm_context *dapm = &codec->dapm;
1625 ARRAY_SIZE(twl4030_dapm_widgets));
1626 1639
1627 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 1640 snd_soc_dapm_new_controls(dapm, twl4030_dapm_widgets,
1641 ARRAY_SIZE(twl4030_dapm_widgets));
1642 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1628 1643
1629 return 0; 1644 return 0;
1630} 1645}
@@ -1638,14 +1653,14 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
1638 case SND_SOC_BIAS_PREPARE: 1653 case SND_SOC_BIAS_PREPARE:
1639 break; 1654 break;
1640 case SND_SOC_BIAS_STANDBY: 1655 case SND_SOC_BIAS_STANDBY:
1641 if (codec->bias_level == SND_SOC_BIAS_OFF) 1656 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
1642 twl4030_codec_enable(codec, 1); 1657 twl4030_codec_enable(codec, 1);
1643 break; 1658 break;
1644 case SND_SOC_BIAS_OFF: 1659 case SND_SOC_BIAS_OFF:
1645 twl4030_codec_enable(codec, 0); 1660 twl4030_codec_enable(codec, 0);
1646 break; 1661 break;
1647 } 1662 }
1648 codec->bias_level = level; 1663 codec->dapm.bias_level = level;
1649 1664
1650 return 0; 1665 return 0;
1651} 1666}
@@ -1709,6 +1724,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream,
1709 struct snd_soc_codec *codec = rtd->codec; 1724 struct snd_soc_codec *codec = rtd->codec;
1710 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); 1725 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
1711 1726
1727 snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
1712 if (twl4030->master_substream) { 1728 if (twl4030->master_substream) {
1713 twl4030->slave_substream = substream; 1729 twl4030->slave_substream = substream;
1714 /* The DAI has one configuration for playback and capture, so 1730 /* The DAI has one configuration for playback and capture, so
@@ -1833,7 +1849,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
1833 case SNDRV_PCM_FORMAT_S16_LE: 1849 case SNDRV_PCM_FORMAT_S16_LE:
1834 format |= TWL4030_DATA_WIDTH_16S_16W; 1850 format |= TWL4030_DATA_WIDTH_16S_16W;
1835 break; 1851 break;
1836 case SNDRV_PCM_FORMAT_S24_LE: 1852 case SNDRV_PCM_FORMAT_S32_LE:
1837 format |= TWL4030_DATA_WIDTH_32S_24W; 1853 format |= TWL4030_DATA_WIDTH_32S_24W;
1838 break; 1854 break;
1839 default: 1855 default:
@@ -2166,7 +2182,7 @@ static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate)
2166} 2182}
2167 2183
2168#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) 2184#define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000)
2169#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) 2185#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
2170 2186
2171static struct snd_soc_dai_ops twl4030_dai_hifi_ops = { 2187static struct snd_soc_dai_ops twl4030_dai_hifi_ops = {
2172 .startup = twl4030_startup, 2188 .startup = twl4030_startup,
@@ -2245,7 +2261,7 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
2245 snd_soc_codec_set_drvdata(codec, twl4030); 2261 snd_soc_codec_set_drvdata(codec, twl4030);
2246 /* Set the defaults, and power up the codec */ 2262 /* Set the defaults, and power up the codec */
2247 twl4030->sysclk = twl4030_codec_get_mclk() / 1000; 2263 twl4030->sysclk = twl4030_codec_get_mclk() / 1000;
2248 codec->idle_bias_off = 1; 2264 codec->dapm.idle_bias_off = 1;
2249 2265
2250 twl4030_init_chip(codec); 2266 twl4030_init_chip(codec);
2251 2267
@@ -2257,9 +2273,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec)
2257 2273
2258static int twl4030_soc_remove(struct snd_soc_codec *codec) 2274static int twl4030_soc_remove(struct snd_soc_codec *codec)
2259{ 2275{
2276 struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
2277
2260 /* Reset registers to their chip default before leaving */ 2278 /* Reset registers to their chip default before leaving */
2261 twl4030_reset_registers(codec); 2279 twl4030_reset_registers(codec);
2262 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); 2280 twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF);
2281 kfree(twl4030);
2263 return 0; 2282 return 0;
2264} 2283}
2265 2284
@@ -2291,10 +2310,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
2291 2310
2292static int __devexit twl4030_codec_remove(struct platform_device *pdev) 2311static int __devexit twl4030_codec_remove(struct platform_device *pdev)
2293{ 2312{
2294 struct twl4030_priv *twl4030 = dev_get_drvdata(&pdev->dev);
2295
2296 snd_soc_unregister_codec(&pdev->dev); 2313 snd_soc_unregister_codec(&pdev->dev);
2297 kfree(twl4030);
2298 return 0; 2314 return 0;
2299} 2315}
2300 2316
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index 10f6e5214511..4bbf1b15a493 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -34,14 +34,46 @@
34#include <sound/pcm.h> 34#include <sound/pcm.h>
35#include <sound/pcm_params.h> 35#include <sound/pcm_params.h>
36#include <sound/soc.h> 36#include <sound/soc.h>
37#include <sound/soc-dapm.h>
38#include <sound/initval.h> 37#include <sound/initval.h>
39#include <sound/tlv.h> 38#include <sound/tlv.h>
40 39
41#include "twl6040.h" 40#include "twl6040.h"
42 41
43#define TWL6040_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) 42#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000
44#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) 43#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE)
44
45#define TWL6040_OUTHS_0dB 0x00
46#define TWL6040_OUTHS_M30dB 0x0F
47#define TWL6040_OUTHF_0dB 0x03
48#define TWL6040_OUTHF_M52dB 0x1D
49
50#define TWL6040_RAMP_NONE 0
51#define TWL6040_RAMP_UP 1
52#define TWL6040_RAMP_DOWN 2
53
54#define TWL6040_HSL_VOL_MASK 0x0F
55#define TWL6040_HSL_VOL_SHIFT 0
56#define TWL6040_HSR_VOL_MASK 0xF0
57#define TWL6040_HSR_VOL_SHIFT 4
58#define TWL6040_HF_VOL_MASK 0x1F
59#define TWL6040_HF_VOL_SHIFT 0
60
61struct twl6040_output {
62 u16 active;
63 u16 left_vol;
64 u16 right_vol;
65 u16 left_step;
66 u16 right_step;
67 unsigned int step_delay;
68 u16 ramp;
69 u16 mute;
70 struct completion ramp_done;
71};
72
73struct twl6040_jack_data {
74 struct snd_soc_jack *jack;
75 int report;
76};
45 77
46/* codec private data */ 78/* codec private data */
47struct twl6040_data { 79struct twl6040_data {
@@ -53,6 +85,17 @@ struct twl6040_data {
53 unsigned int sysclk; 85 unsigned int sysclk;
54 struct snd_pcm_hw_constraint_list *sysclk_constraints; 86 struct snd_pcm_hw_constraint_list *sysclk_constraints;
55 struct completion ready; 87 struct completion ready;
88 struct twl6040_jack_data hs_jack;
89 struct snd_soc_codec *codec;
90 struct workqueue_struct *workqueue;
91 struct delayed_work delayed_work;
92 struct mutex mutex;
93 struct twl6040_output headset;
94 struct twl6040_output handsfree;
95 struct workqueue_struct *hf_workqueue;
96 struct workqueue_struct *hs_workqueue;
97 struct delayed_work hs_delayed_work;
98 struct delayed_work hf_delayed_work;
56}; 99};
57 100
58/* 101/*
@@ -201,7 +244,7 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec,
201 if (reg >= TWL6040_CACHEREGNUM) 244 if (reg >= TWL6040_CACHEREGNUM)
202 return -EIO; 245 return -EIO;
203 246
204 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg); 247 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &value, reg);
205 twl6040_write_reg_cache(codec, reg, value); 248 twl6040_write_reg_cache(codec, reg, value);
206 249
207 return value; 250 return value;
@@ -217,7 +260,7 @@ static int twl6040_write(struct snd_soc_codec *codec,
217 return -EIO; 260 return -EIO;
218 261
219 twl6040_write_reg_cache(codec, reg, value); 262 twl6040_write_reg_cache(codec, reg, value);
220 return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); 263 return twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, value, reg);
221} 264}
222 265
223static void twl6040_init_vio_regs(struct snd_soc_codec *codec) 266static void twl6040_init_vio_regs(struct snd_soc_codec *codec)
@@ -254,6 +297,305 @@ static void twl6040_init_vdd_regs(struct snd_soc_codec *codec)
254 } 297 }
255} 298}
256 299
300/*
301 * Ramp HS PGA volume to minimise pops at stream startup and shutdown.
302 */
303static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec,
304 unsigned int left_step, unsigned int right_step)
305{
306
307 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
308 struct twl6040_output *headset = &priv->headset;
309 int left_complete = 0, right_complete = 0;
310 u8 reg, val;
311
312 /* left channel */
313 left_step = (left_step > 0xF) ? 0xF : left_step;
314 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
315 val = (~reg & TWL6040_HSL_VOL_MASK);
316
317 if (headset->ramp == TWL6040_RAMP_UP) {
318 /* ramp step up */
319 if (val < headset->left_vol) {
320 val += left_step;
321 reg &= ~TWL6040_HSL_VOL_MASK;
322 twl6040_write(codec, TWL6040_REG_HSGAIN,
323 (reg | (~val & TWL6040_HSL_VOL_MASK)));
324 } else {
325 left_complete = 1;
326 }
327 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
328 /* ramp step down */
329 if (val > 0x0) {
330 val -= left_step;
331 reg &= ~TWL6040_HSL_VOL_MASK;
332 twl6040_write(codec, TWL6040_REG_HSGAIN, reg |
333 (~val & TWL6040_HSL_VOL_MASK));
334 } else {
335 left_complete = 1;
336 }
337 }
338
339 /* right channel */
340 right_step = (right_step > 0xF) ? 0xF : right_step;
341 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN);
342 val = (~reg & TWL6040_HSR_VOL_MASK) >> TWL6040_HSR_VOL_SHIFT;
343
344 if (headset->ramp == TWL6040_RAMP_UP) {
345 /* ramp step up */
346 if (val < headset->right_vol) {
347 val += right_step;
348 reg &= ~TWL6040_HSR_VOL_MASK;
349 twl6040_write(codec, TWL6040_REG_HSGAIN,
350 (reg | (~val << TWL6040_HSR_VOL_SHIFT)));
351 } else {
352 right_complete = 1;
353 }
354 } else if (headset->ramp == TWL6040_RAMP_DOWN) {
355 /* ramp step down */
356 if (val > 0x0) {
357 val -= right_step;
358 reg &= ~TWL6040_HSR_VOL_MASK;
359 twl6040_write(codec, TWL6040_REG_HSGAIN,
360 reg | (~val << TWL6040_HSR_VOL_SHIFT));
361 } else {
362 right_complete = 1;
363 }
364 }
365
366 return left_complete & right_complete;
367}
368
369/*
370 * Ramp HF PGA volume to minimise pops at stream startup and shutdown.
371 */
372static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec,
373 unsigned int left_step, unsigned int right_step)
374{
375 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
376 struct twl6040_output *handsfree = &priv->handsfree;
377 int left_complete = 0, right_complete = 0;
378 u16 reg, val;
379
380 /* left channel */
381 left_step = (left_step > 0x1D) ? 0x1D : left_step;
382 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFLGAIN);
383 reg = 0x1D - reg;
384 val = (reg & TWL6040_HF_VOL_MASK);
385 if (handsfree->ramp == TWL6040_RAMP_UP) {
386 /* ramp step up */
387 if (val < handsfree->left_vol) {
388 val += left_step;
389 reg &= ~TWL6040_HF_VOL_MASK;
390 twl6040_write(codec, TWL6040_REG_HFLGAIN,
391 reg | (0x1D - val));
392 } else {
393 left_complete = 1;
394 }
395 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
396 /* ramp step down */
397 if (val > 0) {
398 val -= left_step;
399 reg &= ~TWL6040_HF_VOL_MASK;
400 twl6040_write(codec, TWL6040_REG_HFLGAIN,
401 reg | (0x1D - val));
402 } else {
403 left_complete = 1;
404 }
405 }
406
407 /* right channel */
408 right_step = (right_step > 0x1D) ? 0x1D : right_step;
409 reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFRGAIN);
410 reg = 0x1D - reg;
411 val = (reg & TWL6040_HF_VOL_MASK);
412 if (handsfree->ramp == TWL6040_RAMP_UP) {
413 /* ramp step up */
414 if (val < handsfree->right_vol) {
415 val += right_step;
416 reg &= ~TWL6040_HF_VOL_MASK;
417 twl6040_write(codec, TWL6040_REG_HFRGAIN,
418 reg | (0x1D - val));
419 } else {
420 right_complete = 1;
421 }
422 } else if (handsfree->ramp == TWL6040_RAMP_DOWN) {
423 /* ramp step down */
424 if (val > 0) {
425 val -= right_step;
426 reg &= ~TWL6040_HF_VOL_MASK;
427 twl6040_write(codec, TWL6040_REG_HFRGAIN,
428 reg | (0x1D - val));
429 }
430 }
431
432 return left_complete & right_complete;
433}
434
435/*
436 * This work ramps both output PGAs at stream start/stop time to
437 * minimise pop associated with DAPM power switching.
438 */
439static void twl6040_pga_hs_work(struct work_struct *work)
440{
441 struct twl6040_data *priv =
442 container_of(work, struct twl6040_data, hs_delayed_work.work);
443 struct snd_soc_codec *codec = priv->codec;
444 struct twl6040_output *headset = &priv->headset;
445 unsigned int delay = headset->step_delay;
446 int i, headset_complete;
447
448 /* do we need to ramp at all ? */
449 if (headset->ramp == TWL6040_RAMP_NONE)
450 return;
451
452 /* HS PGA volumes have 4 bits of resolution to ramp */
453 for (i = 0; i <= 16; i++) {
454 headset_complete = 1;
455 if (headset->ramp != TWL6040_RAMP_NONE)
456 headset_complete = twl6040_hs_ramp_step(codec,
457 headset->left_step,
458 headset->right_step);
459
460 /* ramp finished ? */
461 if (headset_complete)
462 break;
463
464 /*
465 * TODO: tune: delay is longer over 0dB
466 * as increases are larger.
467 */
468 if (i >= 8)
469 schedule_timeout_interruptible(msecs_to_jiffies(delay +
470 (delay >> 1)));
471 else
472 schedule_timeout_interruptible(msecs_to_jiffies(delay));
473 }
474
475 if (headset->ramp == TWL6040_RAMP_DOWN) {
476 headset->active = 0;
477 complete(&headset->ramp_done);
478 } else {
479 headset->active = 1;
480 }
481 headset->ramp = TWL6040_RAMP_NONE;
482}
483
484static void twl6040_pga_hf_work(struct work_struct *work)
485{
486 struct twl6040_data *priv =
487 container_of(work, struct twl6040_data, hf_delayed_work.work);
488 struct snd_soc_codec *codec = priv->codec;
489 struct twl6040_output *handsfree = &priv->handsfree;
490 unsigned int delay = handsfree->step_delay;
491 int i, handsfree_complete;
492
493 /* do we need to ramp at all ? */
494 if (handsfree->ramp == TWL6040_RAMP_NONE)
495 return;
496
497 /* HF PGA volumes have 5 bits of resolution to ramp */
498 for (i = 0; i <= 32; i++) {
499 handsfree_complete = 1;
500 if (handsfree->ramp != TWL6040_RAMP_NONE)
501 handsfree_complete = twl6040_hf_ramp_step(codec,
502 handsfree->left_step,
503 handsfree->right_step);
504
505 /* ramp finished ? */
506 if (handsfree_complete)
507 break;
508
509 /*
510 * TODO: tune: delay is longer over 0dB
511 * as increases are larger.
512 */
513 if (i >= 16)
514 schedule_timeout_interruptible(msecs_to_jiffies(delay +
515 (delay >> 1)));
516 else
517 schedule_timeout_interruptible(msecs_to_jiffies(delay));
518 }
519
520
521 if (handsfree->ramp == TWL6040_RAMP_DOWN) {
522 handsfree->active = 0;
523 complete(&handsfree->ramp_done);
524 } else
525 handsfree->active = 1;
526 handsfree->ramp = TWL6040_RAMP_NONE;
527}
528
529static int pga_event(struct snd_soc_dapm_widget *w,
530 struct snd_kcontrol *kcontrol, int event)
531{
532 struct snd_soc_codec *codec = w->codec;
533 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
534 struct twl6040_output *out;
535 struct delayed_work *work;
536 struct workqueue_struct *queue;
537
538 switch (w->shift) {
539 case 2:
540 case 3:
541 out = &priv->headset;
542 work = &priv->hs_delayed_work;
543 queue = priv->hs_workqueue;
544 out->step_delay = 5; /* 5 ms between volume ramp steps */
545 break;
546 case 4:
547 out = &priv->handsfree;
548 work = &priv->hf_delayed_work;
549 queue = priv->hf_workqueue;
550 out->step_delay = 5; /* 5 ms between volume ramp steps */
551 if (SND_SOC_DAPM_EVENT_ON(event))
552 priv->non_lp++;
553 else
554 priv->non_lp--;
555 break;
556 default:
557 return -1;
558 }
559
560 switch (event) {
561 case SND_SOC_DAPM_POST_PMU:
562 if (out->active)
563 break;
564
565 /* don't use volume ramp for power-up */
566 out->left_step = out->left_vol;
567 out->right_step = out->right_vol;
568
569 if (!delayed_work_pending(work)) {
570 out->ramp = TWL6040_RAMP_UP;
571 queue_delayed_work(queue, work,
572 msecs_to_jiffies(1));
573 }
574 break;
575
576 case SND_SOC_DAPM_PRE_PMD:
577 if (!out->active)
578 break;
579
580 if (!delayed_work_pending(work)) {
581 /* use volume ramp for power-down */
582 out->left_step = 1;
583 out->right_step = 1;
584 out->ramp = TWL6040_RAMP_DOWN;
585 INIT_COMPLETION(out->ramp_done);
586
587 queue_delayed_work(queue, work,
588 msecs_to_jiffies(1));
589
590 wait_for_completion_timeout(&out->ramp_done,
591 msecs_to_jiffies(2000));
592 }
593 break;
594 }
595
596 return 0;
597}
598
257/* twl6040 codec manual power-up sequence */ 599/* twl6040 codec manual power-up sequence */
258static void twl6040_power_up(struct snd_soc_codec *codec) 600static void twl6040_power_up(struct snd_soc_codec *codec)
259{ 601{
@@ -382,6 +724,47 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w,
382 return 0; 724 return 0;
383} 725}
384 726
727void twl6040_hs_jack_report(struct snd_soc_codec *codec,
728 struct snd_soc_jack *jack, int report)
729{
730 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
731 int status;
732
733 mutex_lock(&priv->mutex);
734
735 /* Sync status */
736 status = twl6040_read_reg_volatile(codec, TWL6040_REG_STATUS);
737 if (status & TWL6040_PLUGCOMP)
738 snd_soc_jack_report(jack, report, report);
739 else
740 snd_soc_jack_report(jack, 0, report);
741
742 mutex_unlock(&priv->mutex);
743}
744
745void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
746 struct snd_soc_jack *jack, int report)
747{
748 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
749 struct twl6040_jack_data *hs_jack = &priv->hs_jack;
750
751 hs_jack->jack = jack;
752 hs_jack->report = report;
753
754 twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
755}
756EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect);
757
758static void twl6040_accessory_work(struct work_struct *work)
759{
760 struct twl6040_data *priv = container_of(work,
761 struct twl6040_data, delayed_work.work);
762 struct snd_soc_codec *codec = priv->codec;
763 struct twl6040_jack_data *hs_jack = &priv->hs_jack;
764
765 twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report);
766}
767
385/* audio interrupt handler */ 768/* audio interrupt handler */
386static irqreturn_t twl6040_naudint_handler(int irq, void *data) 769static irqreturn_t twl6040_naudint_handler(int irq, void *data)
387{ 770{
@@ -389,33 +772,180 @@ static irqreturn_t twl6040_naudint_handler(int irq, void *data)
389 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 772 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
390 u8 intid; 773 u8 intid;
391 774
392 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID); 775 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID);
393 776
394 switch (intid) { 777 if (intid & TWL6040_THINT)
395 case TWL6040_THINT:
396 dev_alert(codec->dev, "die temp over-limit detection\n"); 778 dev_alert(codec->dev, "die temp over-limit detection\n");
779
780 if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT))
781 queue_delayed_work(priv->workqueue, &priv->delayed_work,
782 msecs_to_jiffies(200));
783
784 if (intid & TWL6040_HOOKINT)
785 dev_info(codec->dev, "hook detection\n");
786
787 if (intid & TWL6040_HFINT)
788 dev_alert(codec->dev, "hf drivers over current detection\n");
789
790 if (intid & TWL6040_VIBINT)
791 dev_alert(codec->dev, "vib drivers over current detection\n");
792
793 if (intid & TWL6040_READYINT)
794 complete(&priv->ready);
795
796 return IRQ_HANDLED;
797}
798
799static int twl6040_put_volsw(struct snd_kcontrol *kcontrol,
800 struct snd_ctl_elem_value *ucontrol)
801{
802 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
803 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
804 struct twl6040_output *out = NULL;
805 struct soc_mixer_control *mc =
806 (struct soc_mixer_control *)kcontrol->private_value;
807 int ret;
808 unsigned int reg = mc->reg;
809
810 /* For HS and HF we shadow the values and only actually write
811 * them out when active in order to ensure the amplifier comes on
812 * as quietly as possible. */
813 switch (reg) {
814 case TWL6040_REG_HSGAIN:
815 out = &twl6040_priv->headset;
397 break; 816 break;
398 case TWL6040_PLUGINT: 817 default:
399 case TWL6040_UNPLUGINT:
400 case TWL6040_HOOKINT:
401 break; 818 break;
402 case TWL6040_HFINT: 819 }
403 dev_alert(codec->dev, "hf drivers over current detection\n"); 820
821 if (out) {
822 out->left_vol = ucontrol->value.integer.value[0];
823 out->right_vol = ucontrol->value.integer.value[1];
824 if (!out->active)
825 return 1;
826 }
827
828 ret = snd_soc_put_volsw(kcontrol, ucontrol);
829 if (ret < 0)
830 return ret;
831
832 return 1;
833}
834
835static int twl6040_get_volsw(struct snd_kcontrol *kcontrol,
836 struct snd_ctl_elem_value *ucontrol)
837{
838 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
839 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
840 struct twl6040_output *out = &twl6040_priv->headset;
841 struct soc_mixer_control *mc =
842 (struct soc_mixer_control *)kcontrol->private_value;
843 unsigned int reg = mc->reg;
844
845 switch (reg) {
846 case TWL6040_REG_HSGAIN:
847 out = &twl6040_priv->headset;
848 ucontrol->value.integer.value[0] = out->left_vol;
849 ucontrol->value.integer.value[1] = out->right_vol;
850 return 0;
851
852 default:
404 break; 853 break;
405 case TWL6040_VIBINT: 854 }
406 dev_alert(codec->dev, "vib drivers over current detection\n"); 855
856 return snd_soc_get_volsw(kcontrol, ucontrol);
857}
858
859static int twl6040_put_volsw_2r_vu(struct snd_kcontrol *kcontrol,
860 struct snd_ctl_elem_value *ucontrol)
861{
862 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
863 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
864 struct twl6040_output *out = NULL;
865 struct soc_mixer_control *mc =
866 (struct soc_mixer_control *)kcontrol->private_value;
867 int ret;
868 unsigned int reg = mc->reg;
869
870 /* For HS and HF we shadow the values and only actually write
871 * them out when active in order to ensure the amplifier comes on
872 * as quietly as possible. */
873 switch (reg) {
874 case TWL6040_REG_HFLGAIN:
875 case TWL6040_REG_HFRGAIN:
876 out = &twl6040_priv->handsfree;
407 break; 877 break;
408 case TWL6040_READYINT: 878 default:
409 complete(&priv->ready);
410 break; 879 break;
880 }
881
882 if (out) {
883 out->left_vol = ucontrol->value.integer.value[0];
884 out->right_vol = ucontrol->value.integer.value[1];
885 if (!out->active)
886 return 1;
887 }
888
889 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
890 if (ret < 0)
891 return ret;
892
893 return 1;
894}
895
896static int twl6040_get_volsw_2r(struct snd_kcontrol *kcontrol,
897 struct snd_ctl_elem_value *ucontrol)
898{
899 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
900 struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec);
901 struct twl6040_output *out = &twl6040_priv->handsfree;
902 struct soc_mixer_control *mc =
903 (struct soc_mixer_control *)kcontrol->private_value;
904 unsigned int reg = mc->reg;
905
906 /* If these are cached registers use the cache */
907 switch (reg) {
908 case TWL6040_REG_HFLGAIN:
909 case TWL6040_REG_HFRGAIN:
910 out = &twl6040_priv->handsfree;
911 ucontrol->value.integer.value[0] = out->left_vol;
912 ucontrol->value.integer.value[1] = out->right_vol;
913 return 0;
914
411 default: 915 default:
412 dev_err(codec->dev, "unknown audio interrupt %d\n", intid);
413 break; 916 break;
414 } 917 }
415 918
416 return IRQ_HANDLED; 919 return snd_soc_get_volsw_2r(kcontrol, ucontrol);
417} 920}
418 921
922/* double control with volume update */
923#define SOC_TWL6040_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax,\
924 xinvert, tlv_array)\
925{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
926 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
927 SNDRV_CTL_ELEM_ACCESS_READWRITE,\
928 .tlv.p = (tlv_array), \
929 .info = snd_soc_info_volsw, .get = twl6040_get_volsw, \
930 .put = twl6040_put_volsw, \
931 .private_value = (unsigned long)&(struct soc_mixer_control) \
932 {.reg = xreg, .shift = shift_left, .rshift = shift_right,\
933 .max = xmax, .platform_max = xmax, .invert = xinvert} }
934
935/* double control with volume update */
936#define SOC_TWL6040_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax,\
937 xinvert, tlv_array)\
938{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
939 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
940 SNDRV_CTL_ELEM_ACCESS_READWRITE | \
941 SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
942 .tlv.p = (tlv_array), \
943 .info = snd_soc_info_volsw_2r, \
944 .get = twl6040_get_volsw_2r, .put = twl6040_put_volsw_2r_vu, \
945 .private_value = (unsigned long)&(struct soc_mixer_control) \
946 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
947 .rshift = xshift, .max = xmax, .invert = xinvert}, }
948
419/* 949/*
420 * MICATT volume control: 950 * MICATT volume control:
421 * from -6 to 0 dB in 6 dB steps 951 * from -6 to 0 dB in 6 dB steps
@@ -424,9 +954,15 @@ static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0);
424 954
425/* 955/*
426 * MICGAIN volume control: 956 * MICGAIN volume control:
427 * from 6 to 30 dB in 6 dB steps 957 * from -6 to 30 dB in 6 dB steps
428 */ 958 */
429static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0); 959static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -600, 600, 0);
960
961/*
962 * AFMGAIN volume control:
963 * from 18 to 24 dB in 6 dB steps
964 */
965static DECLARE_TLV_DB_SCALE(afm_amp_tlv, 1800, 600, 0);
430 966
431/* 967/*
432 * HSGAIN volume control: 968 * HSGAIN volume control:
@@ -455,8 +991,30 @@ static const char *twl6040_amicr_texts[] =
455 {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"}; 991 {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"};
456 992
457static const struct soc_enum twl6040_enum[] = { 993static const struct soc_enum twl6040_enum[] = {
458 SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 3, twl6040_amicl_texts), 994 SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 4, twl6040_amicl_texts),
459 SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 3, twl6040_amicr_texts), 995 SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 4, twl6040_amicr_texts),
996};
997
998static const char *twl6040_hs_texts[] = {
999 "Off", "HS DAC", "Line-In amp"
1000};
1001
1002static const struct soc_enum twl6040_hs_enum[] = {
1003 SOC_ENUM_SINGLE(TWL6040_REG_HSLCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
1004 twl6040_hs_texts),
1005 SOC_ENUM_SINGLE(TWL6040_REG_HSRCTL, 5, ARRAY_SIZE(twl6040_hs_texts),
1006 twl6040_hs_texts),
1007};
1008
1009static const char *twl6040_hf_texts[] = {
1010 "Off", "HF DAC", "Line-In amp"
1011};
1012
1013static const struct soc_enum twl6040_hf_enum[] = {
1014 SOC_ENUM_SINGLE(TWL6040_REG_HFLCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
1015 twl6040_hf_texts),
1016 SOC_ENUM_SINGLE(TWL6040_REG_HFRCTL, 2, ARRAY_SIZE(twl6040_hf_texts),
1017 twl6040_hf_texts),
460}; 1018};
461 1019
462static const struct snd_kcontrol_new amicl_control = 1020static const struct snd_kcontrol_new amicl_control =
@@ -466,18 +1024,18 @@ static const struct snd_kcontrol_new amicr_control =
466 SOC_DAPM_ENUM("Route", twl6040_enum[1]); 1024 SOC_DAPM_ENUM("Route", twl6040_enum[1]);
467 1025
468/* Headset DAC playback switches */ 1026/* Headset DAC playback switches */
469static const struct snd_kcontrol_new hsdacl_switch_controls = 1027static const struct snd_kcontrol_new hsl_mux_controls =
470 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 5, 1, 0); 1028 SOC_DAPM_ENUM("Route", twl6040_hs_enum[0]);
471 1029
472static const struct snd_kcontrol_new hsdacr_switch_controls = 1030static const struct snd_kcontrol_new hsr_mux_controls =
473 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 5, 1, 0); 1031 SOC_DAPM_ENUM("Route", twl6040_hs_enum[1]);
474 1032
475/* Handsfree DAC playback switches */ 1033/* Handsfree DAC playback switches */
476static const struct snd_kcontrol_new hfdacl_switch_controls = 1034static const struct snd_kcontrol_new hfl_mux_controls =
477 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 2, 1, 0); 1035 SOC_DAPM_ENUM("Route", twl6040_hf_enum[0]);
478 1036
479static const struct snd_kcontrol_new hfdacr_switch_controls = 1037static const struct snd_kcontrol_new hfr_mux_controls =
480 SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0); 1038 SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]);
481 1039
482static const struct snd_kcontrol_new ep_driver_switch_controls = 1040static const struct snd_kcontrol_new ep_driver_switch_controls =
483 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); 1041 SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0);
@@ -489,10 +1047,14 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = {
489 SOC_DOUBLE_TLV("Capture Volume", 1047 SOC_DOUBLE_TLV("Capture Volume",
490 TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv), 1048 TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv),
491 1049
1050 /* AFM gains */
1051 SOC_DOUBLE_TLV("Aux FM Volume",
1052 TWL6040_REG_LINEGAIN, 0, 4, 0xF, 0, afm_amp_tlv),
1053
492 /* Playback gains */ 1054 /* Playback gains */
493 SOC_DOUBLE_TLV("Headset Playback Volume", 1055 SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume",
494 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv), 1056 TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv),
495 SOC_DOUBLE_R_TLV("Handsfree Playback Volume", 1057 SOC_TWL6040_DOUBLE_R_TLV("Handsfree Playback Volume",
496 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), 1058 TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv),
497 SOC_SINGLE_TLV("Earphone Playback Volume", 1059 SOC_SINGLE_TLV("Earphone Playback Volume",
498 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), 1060 TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv),
@@ -525,6 +1087,12 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
525 SND_SOC_DAPM_PGA("MicAmpR", 1087 SND_SOC_DAPM_PGA("MicAmpR",
526 TWL6040_REG_MICRCTL, 0, 0, NULL, 0), 1088 TWL6040_REG_MICRCTL, 0, 0, NULL, 0),
527 1089
1090 /* Auxiliary FM PGAs */
1091 SND_SOC_DAPM_PGA("AFMAmpL",
1092 TWL6040_REG_MICLCTL, 1, 0, NULL, 0),
1093 SND_SOC_DAPM_PGA("AFMAmpR",
1094 TWL6040_REG_MICRCTL, 1, 0, NULL, 0),
1095
528 /* ADCs */ 1096 /* ADCs */
529 SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture", 1097 SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture",
530 TWL6040_REG_MICLCTL, 2, 0), 1098 TWL6040_REG_MICLCTL, 2, 0),
@@ -559,29 +1127,33 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = {
559 twl6040_power_mode_event, 1127 twl6040_power_mode_event,
560 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1128 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
561 1129
562 /* Analog playback switches */ 1130 SND_SOC_DAPM_MUX("HF Left Playback",
563 SND_SOC_DAPM_SWITCH("HSDAC Left Playback", 1131 SND_SOC_NOPM, 0, 0, &hfl_mux_controls),
564 SND_SOC_NOPM, 0, 0, &hsdacl_switch_controls), 1132 SND_SOC_DAPM_MUX("HF Right Playback",
565 SND_SOC_DAPM_SWITCH("HSDAC Right Playback", 1133 SND_SOC_NOPM, 0, 0, &hfr_mux_controls),
566 SND_SOC_NOPM, 0, 0, &hsdacr_switch_controls), 1134 /* Analog playback Muxes */
567 SND_SOC_DAPM_SWITCH("HFDAC Left Playback", 1135 SND_SOC_DAPM_MUX("HS Left Playback",
568 SND_SOC_NOPM, 0, 0, &hfdacl_switch_controls), 1136 SND_SOC_NOPM, 0, 0, &hsl_mux_controls),
569 SND_SOC_DAPM_SWITCH("HFDAC Right Playback", 1137 SND_SOC_DAPM_MUX("HS Right Playback",
570 SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls), 1138 SND_SOC_NOPM, 0, 0, &hsr_mux_controls),
571 1139
572 /* Analog playback drivers */ 1140 /* Analog playback drivers */
573 SND_SOC_DAPM_PGA_E("Handsfree Left Driver", 1141 SND_SOC_DAPM_OUT_DRV_E("Handsfree Left Driver",
574 TWL6040_REG_HFLCTL, 4, 0, NULL, 0, 1142 TWL6040_REG_HFLCTL, 4, 0, NULL, 0,
575 twl6040_power_mode_event, 1143 pga_event,
576 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1144 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
577 SND_SOC_DAPM_PGA_E("Handsfree Right Driver", 1145 SND_SOC_DAPM_OUT_DRV_E("Handsfree Right Driver",
578 TWL6040_REG_HFRCTL, 4, 0, NULL, 0, 1146 TWL6040_REG_HFRCTL, 4, 0, NULL, 0,
579 twl6040_power_mode_event, 1147 pga_event,
580 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), 1148 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
581 SND_SOC_DAPM_PGA("Headset Left Driver", 1149 SND_SOC_DAPM_OUT_DRV_E("Headset Left Driver",
582 TWL6040_REG_HSLCTL, 2, 0, NULL, 0), 1150 TWL6040_REG_HSLCTL, 2, 0, NULL, 0,
583 SND_SOC_DAPM_PGA("Headset Right Driver", 1151 pga_event,
584 TWL6040_REG_HSRCTL, 2, 0, NULL, 0), 1152 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
1153 SND_SOC_DAPM_OUT_DRV_E("Headset Right Driver",
1154 TWL6040_REG_HSRCTL, 2, 0, NULL, 0,
1155 pga_event,
1156 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
585 SND_SOC_DAPM_SWITCH_E("Earphone Driver", 1157 SND_SOC_DAPM_SWITCH_E("Earphone Driver",
586 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, 1158 SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls,
587 twl6040_power_mode_event, 1159 twl6040_power_mode_event,
@@ -611,12 +1183,18 @@ static const struct snd_soc_dapm_route intercon[] = {
611 {"ADC Left", NULL, "MicAmpL"}, 1183 {"ADC Left", NULL, "MicAmpL"},
612 {"ADC Right", NULL, "MicAmpR"}, 1184 {"ADC Right", NULL, "MicAmpR"},
613 1185
614 /* Headset playback path */ 1186 /* AFM path */
615 {"HSDAC Left Playback", "Switch", "HSDAC Left"}, 1187 {"AFMAmpL", "NULL", "AFML"},
616 {"HSDAC Right Playback", "Switch", "HSDAC Right"}, 1188 {"AFMAmpR", "NULL", "AFMR"},
1189
1190 {"HS Left Playback", "HS DAC", "HSDAC Left"},
1191 {"HS Left Playback", "Line-In amp", "AFMAmpL"},
617 1192
618 {"Headset Left Driver", NULL, "HSDAC Left Playback"}, 1193 {"HS Right Playback", "HS DAC", "HSDAC Right"},
619 {"Headset Right Driver", NULL, "HSDAC Right Playback"}, 1194 {"HS Right Playback", "Line-In amp", "AFMAmpR"},
1195
1196 {"Headset Left Driver", "NULL", "HS Left Playback"},
1197 {"Headset Right Driver", "NULL", "HS Right Playback"},
620 1198
621 {"HSOL", NULL, "Headset Left Driver"}, 1199 {"HSOL", NULL, "Headset Left Driver"},
622 {"HSOR", NULL, "Headset Right Driver"}, 1200 {"HSOR", NULL, "Headset Right Driver"},
@@ -625,12 +1203,14 @@ static const struct snd_soc_dapm_route intercon[] = {
625 {"Earphone Driver", "Switch", "HSDAC Left"}, 1203 {"Earphone Driver", "Switch", "HSDAC Left"},
626 {"EP", NULL, "Earphone Driver"}, 1204 {"EP", NULL, "Earphone Driver"},
627 1205
628 /* Handsfree playback path */ 1206 {"HF Left Playback", "HF DAC", "HFDAC Left"},
629 {"HFDAC Left Playback", "Switch", "HFDAC Left"}, 1207 {"HF Left Playback", "Line-In amp", "AFMAmpL"},
630 {"HFDAC Right Playback", "Switch", "HFDAC Right"}, 1208
1209 {"HF Right Playback", "HF DAC", "HFDAC Right"},
1210 {"HF Right Playback", "Line-In amp", "AFMAmpR"},
631 1211
632 {"HFDAC Left PGA", NULL, "HFDAC Left Playback"}, 1212 {"HFDAC Left PGA", NULL, "HF Left Playback"},
633 {"HFDAC Right PGA", NULL, "HFDAC Right Playback"}, 1213 {"HFDAC Right PGA", NULL, "HF Right Playback"},
634 1214
635 {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"}, 1215 {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"},
636 {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"}, 1216 {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"},
@@ -641,12 +1221,12 @@ static const struct snd_soc_dapm_route intercon[] = {
641 1221
642static int twl6040_add_widgets(struct snd_soc_codec *codec) 1222static int twl6040_add_widgets(struct snd_soc_codec *codec)
643{ 1223{
644 snd_soc_dapm_new_controls(codec, twl6040_dapm_widgets, 1224 struct snd_soc_dapm_context *dapm = &codec->dapm;
645 ARRAY_SIZE(twl6040_dapm_widgets));
646
647 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon));
648 1225
649 snd_soc_dapm_new_widgets(codec); 1226 snd_soc_dapm_new_controls(dapm, twl6040_dapm_widgets,
1227 ARRAY_SIZE(twl6040_dapm_widgets));
1228 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
1229 snd_soc_dapm_new_widgets(dapm);
650 1230
651 return 0; 1231 return 0;
652} 1232}
@@ -659,10 +1239,10 @@ static int twl6040_power_up_completion(struct snd_soc_codec *codec,
659 u8 intid; 1239 u8 intid;
660 1240
661 time_left = wait_for_completion_timeout(&priv->ready, 1241 time_left = wait_for_completion_timeout(&priv->ready,
662 msecs_to_jiffies(48)); 1242 msecs_to_jiffies(144));
663 1243
664 if (!time_left) { 1244 if (!time_left) {
665 twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid, 1245 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid,
666 TWL6040_REG_INTID); 1246 TWL6040_REG_INTID);
667 if (!(intid & TWL6040_READYINT)) { 1247 if (!(intid & TWL6040_READYINT)) {
668 dev_err(codec->dev, "timeout waiting for READYINT\n"); 1248 dev_err(codec->dev, "timeout waiting for READYINT\n");
@@ -713,6 +1293,15 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
713 1293
714 /* initialize vdd/vss registers with reg_cache */ 1294 /* initialize vdd/vss registers with reg_cache */
715 twl6040_init_vdd_regs(codec); 1295 twl6040_init_vdd_regs(codec);
1296
1297 /* Set external boost GPO */
1298 twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02);
1299
1300 /* Set initial minimal gain values */
1301 twl6040_write(codec, TWL6040_REG_HSGAIN, 0xFF);
1302 twl6040_write(codec, TWL6040_REG_EARCTL, 0x1E);
1303 twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1D);
1304 twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1D);
716 break; 1305 break;
717 case SND_SOC_BIAS_OFF: 1306 case SND_SOC_BIAS_OFF:
718 if (!priv->codec_powered) 1307 if (!priv->codec_powered)
@@ -739,7 +1328,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec,
739 break; 1328 break;
740 } 1329 }
741 1330
742 codec->bias_level = level; 1331 codec->dapm.bias_level = level;
743 1332
744 return 0; 1333 return 0;
745} 1334}
@@ -772,23 +1361,6 @@ static int twl6040_startup(struct snd_pcm_substream *substream,
772 struct snd_soc_codec *codec = rtd->codec; 1361 struct snd_soc_codec *codec = rtd->codec;
773 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1362 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
774 1363
775 if (!priv->sysclk) {
776 dev_err(codec->dev,
777 "no mclk configured, call set_sysclk() on init\n");
778 return -EINVAL;
779 }
780
781 /*
782 * capture is not supported at 17.64 MHz,
783 * it's reserved for headset low-power playback scenario
784 */
785 if ((priv->sysclk == 17640000) && substream->stream) {
786 dev_err(codec->dev,
787 "capture mode is not supported at %dHz\n",
788 priv->sysclk);
789 return -EINVAL;
790 }
791
792 snd_pcm_hw_constraint_list(substream->runtime, 0, 1364 snd_pcm_hw_constraint_list(substream->runtime, 0,
793 SNDRV_PCM_HW_PARAM_RATE, 1365 SNDRV_PCM_HW_PARAM_RATE,
794 priv->sysclk_constraints); 1366 priv->sysclk_constraints);
@@ -814,10 +1386,17 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
814 1386
815 rate = params_rate(params); 1387 rate = params_rate(params);
816 switch (rate) { 1388 switch (rate) {
1389 case 11250:
1390 case 22500:
1391 case 44100:
817 case 88200: 1392 case 88200:
818 lppllctl |= TWL6040_LPLLFIN; 1393 lppllctl |= TWL6040_LPLLFIN;
819 priv->sysclk = 17640000; 1394 priv->sysclk = 17640000;
820 break; 1395 break;
1396 case 8000:
1397 case 16000:
1398 case 32000:
1399 case 48000:
821 case 96000: 1400 case 96000:
822 lppllctl &= ~TWL6040_LPLLFIN; 1401 lppllctl &= ~TWL6040_LPLLFIN;
823 priv->sysclk = 19200000; 1402 priv->sysclk = 19200000;
@@ -832,31 +1411,37 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream,
832 return 0; 1411 return 0;
833} 1412}
834 1413
835static int twl6040_trigger(struct snd_pcm_substream *substream, 1414static int twl6040_prepare(struct snd_pcm_substream *substream,
836 int cmd, struct snd_soc_dai *dai) 1415 struct snd_soc_dai *dai)
837{ 1416{
838 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1417 struct snd_soc_pcm_runtime *rtd = substream->private_data;
839 struct snd_soc_codec *codec = rtd->codec; 1418 struct snd_soc_codec *codec = rtd->codec;
840 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); 1419 struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec);
841 1420
842 switch (cmd) { 1421 if (!priv->sysclk) {
843 case SNDRV_PCM_TRIGGER_START: 1422 dev_err(codec->dev,
844 case SNDRV_PCM_TRIGGER_RESUME: 1423 "no mclk configured, call set_sysclk() on init\n");
845 /* 1424 return -EINVAL;
846 * low-power playback mode is restricted 1425 }
847 * for headset path only 1426
848 */ 1427 /*
849 if ((priv->sysclk == 17640000) && priv->non_lp) { 1428 * capture is not supported at 17.64 MHz,
1429 * it's reserved for headset low-power playback scenario
1430 */
1431 if ((priv->sysclk == 17640000) &&
1432 substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
1433 dev_err(codec->dev,
1434 "capture mode is not supported at %dHz\n",
1435 priv->sysclk);
1436 return -EINVAL;
1437 }
1438
1439 if ((priv->sysclk == 17640000) && priv->non_lp) {
850 dev_err(codec->dev, 1440 dev_err(codec->dev,
851 "some enabled paths aren't supported at %dHz\n", 1441 "some enabled paths aren't supported at %dHz\n",
852 priv->sysclk); 1442 priv->sysclk);
853 return -EPERM; 1443 return -EPERM;
854 }
855 break;
856 default:
857 break;
858 } 1444 }
859
860 return 0; 1445 return 0;
861} 1446}
862 1447
@@ -970,7 +1555,7 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai,
970static struct snd_soc_dai_ops twl6040_dai_ops = { 1555static struct snd_soc_dai_ops twl6040_dai_ops = {
971 .startup = twl6040_startup, 1556 .startup = twl6040_startup,
972 .hw_params = twl6040_hw_params, 1557 .hw_params = twl6040_hw_params,
973 .trigger = twl6040_trigger, 1558 .prepare = twl6040_prepare,
974 .set_sysclk = twl6040_set_dai_sysclk, 1559 .set_sysclk = twl6040_set_dai_sysclk,
975}; 1560};
976 1561
@@ -1004,6 +1589,7 @@ static int twl6040_suspend(struct snd_soc_codec *codec, pm_message_t state)
1004static int twl6040_resume(struct snd_soc_codec *codec) 1589static int twl6040_resume(struct snd_soc_codec *codec)
1005{ 1590{
1006 twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1591 twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1592 twl6040_set_bias_level(codec, codec->dapm.suspend_bias_level);
1007 1593
1008 return 0; 1594 return 0;
1009} 1595}
@@ -1018,24 +1604,41 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1018 struct twl6040_data *priv; 1604 struct twl6040_data *priv;
1019 int audpwron, naudint; 1605 int audpwron, naudint;
1020 int ret = 0; 1606 int ret = 0;
1607 u8 icrev, intmr = TWL6040_ALLINT_MSK;
1021 1608
1022 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); 1609 priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL);
1023 if (priv == NULL) 1610 if (priv == NULL)
1024 return -ENOMEM; 1611 return -ENOMEM;
1025 snd_soc_codec_set_drvdata(codec, priv); 1612 snd_soc_codec_set_drvdata(codec, priv);
1026 1613
1027 if (twl_codec) { 1614 priv->codec = codec;
1615
1616 twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &icrev, TWL6040_REG_ASICREV);
1617
1618 if (twl_codec && (icrev > 0))
1028 audpwron = twl_codec->audpwron_gpio; 1619 audpwron = twl_codec->audpwron_gpio;
1029 naudint = twl_codec->naudint_irq; 1620 else
1030 } else {
1031 audpwron = -EINVAL; 1621 audpwron = -EINVAL;
1622
1623 if (twl_codec)
1624 naudint = twl_codec->naudint_irq;
1625 else
1032 naudint = 0; 1626 naudint = 0;
1033 }
1034 1627
1035 priv->audpwron = audpwron; 1628 priv->audpwron = audpwron;
1036 priv->naudint = naudint; 1629 priv->naudint = naudint;
1630 priv->workqueue = create_singlethread_workqueue("twl6040-codec");
1631
1632 if (!priv->workqueue)
1633 goto work_err;
1634
1635 INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work);
1636
1637 mutex_init(&priv->mutex);
1037 1638
1038 init_completion(&priv->ready); 1639 init_completion(&priv->ready);
1640 init_completion(&priv->headset.ramp_done);
1641 init_completion(&priv->handsfree.ramp_done);
1039 1642
1040 if (gpio_is_valid(audpwron)) { 1643 if (gpio_is_valid(audpwron)) {
1041 ret = gpio_request(audpwron, "audpwron"); 1644 ret = gpio_request(audpwron, "audpwron");
@@ -1047,7 +1650,14 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1047 goto gpio2_err; 1650 goto gpio2_err;
1048 1651
1049 priv->codec_powered = 0; 1652 priv->codec_powered = 0;
1653
1654 /* enable only codec ready interrupt */
1655 intmr &= ~(TWL6040_READYMSK | TWL6040_PLUGMSK);
1656
1657 /* reset interrupt status to allow correct power up sequence */
1658 twl6040_read_reg_volatile(codec, TWL6040_REG_INTID);
1050 } 1659 }
1660 twl6040_write(codec, TWL6040_REG_INTMR, intmr);
1051 1661
1052 if (naudint) { 1662 if (naudint) {
1053 /* audio interrupt */ 1663 /* audio interrupt */
@@ -1057,25 +1667,29 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1057 "twl6040_codec", codec); 1667 "twl6040_codec", codec);
1058 if (ret) 1668 if (ret)
1059 goto gpio2_err; 1669 goto gpio2_err;
1060 } else {
1061 if (gpio_is_valid(audpwron)) {
1062 /* enable only codec ready interrupt */
1063 twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
1064 ~TWL6040_READYMSK & TWL6040_ALLINT_MSK);
1065 } else {
1066 /* no interrupts at all */
1067 twl6040_write_reg_cache(codec, TWL6040_REG_INTMR,
1068 TWL6040_ALLINT_MSK);
1069 }
1070 } 1670 }
1071 1671
1072 /* init vio registers */ 1672 /* init vio registers */
1073 twl6040_init_vio_regs(codec); 1673 twl6040_init_vio_regs(codec);
1074 1674
1675 priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf");
1676 if (priv->hf_workqueue == NULL) {
1677 ret = -ENOMEM;
1678 goto irq_err;
1679 }
1680 priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs");
1681 if (priv->hs_workqueue == NULL) {
1682 ret = -ENOMEM;
1683 goto wq_err;
1684 }
1685
1686 INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work);
1687 INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work);
1688
1075 /* power on device */ 1689 /* power on device */
1076 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1690 ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1077 if (ret) 1691 if (ret)
1078 goto irq_err; 1692 goto bias_err;
1079 1693
1080 snd_soc_add_controls(codec, twl6040_snd_controls, 1694 snd_soc_add_controls(codec, twl6040_snd_controls,
1081 ARRAY_SIZE(twl6040_snd_controls)); 1695 ARRAY_SIZE(twl6040_snd_controls));
@@ -1083,6 +1697,10 @@ static int twl6040_probe(struct snd_soc_codec *codec)
1083 1697
1084 return 0; 1698 return 0;
1085 1699
1700bias_err:
1701 destroy_workqueue(priv->hs_workqueue);
1702wq_err:
1703 destroy_workqueue(priv->hf_workqueue);
1086irq_err: 1704irq_err:
1087 if (naudint) 1705 if (naudint)
1088 free_irq(naudint, codec); 1706 free_irq(naudint, codec);
@@ -1090,6 +1708,8 @@ gpio2_err:
1090 if (gpio_is_valid(audpwron)) 1708 if (gpio_is_valid(audpwron))
1091 gpio_free(audpwron); 1709 gpio_free(audpwron);
1092gpio1_err: 1710gpio1_err:
1711 destroy_workqueue(priv->workqueue);
1712work_err:
1093 kfree(priv); 1713 kfree(priv);
1094 return ret; 1714 return ret;
1095} 1715}
@@ -1108,6 +1728,9 @@ static int twl6040_remove(struct snd_soc_codec *codec)
1108 if (naudint) 1728 if (naudint)
1109 free_irq(naudint, codec); 1729 free_irq(naudint, codec);
1110 1730
1731 destroy_workqueue(priv->workqueue);
1732 destroy_workqueue(priv->hf_workqueue);
1733 destroy_workqueue(priv->hs_workqueue);
1111 kfree(priv); 1734 kfree(priv);
1112 1735
1113 return 0; 1736 return 0;
diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h
index f7c77fa58a3c..23aeed0963e6 100644
--- a/sound/soc/codecs/twl6040.h
+++ b/sound/soc/codecs/twl6040.h
@@ -79,6 +79,7 @@
79 79
80/* INTMR (0x04) fields */ 80/* INTMR (0x04) fields */
81 81
82#define TWL6040_PLUGMSK 0x02
82#define TWL6040_READYMSK 0x40 83#define TWL6040_READYMSK 0x40
83#define TWL6040_ALLINT_MSK 0x7B 84#define TWL6040_ALLINT_MSK 0x7B
84 85
@@ -135,4 +136,11 @@
135#define TWL6040_HPPLL_ID 1 136#define TWL6040_HPPLL_ID 1
136#define TWL6040_LPPLL_ID 2 137#define TWL6040_LPPLL_ID 2
137 138
139/* STATUS (0x2E) fields */
140
141#define TWL6040_PLUGCOMP 0x02
142
143void twl6040_hs_jack_detect(struct snd_soc_codec *codec,
144 struct snd_soc_jack *jack, int report);
145
138#endif /* End of __TWL6040_H__ */ 146#endif /* End of __TWL6040_H__ */
diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c
index 464f0cfa4c7a..e76847a9438b 100644
--- a/sound/soc/codecs/uda134x.c
+++ b/sound/soc/codecs/uda134x.c
@@ -19,7 +19,6 @@
19#include <sound/pcm.h> 19#include <sound/pcm.h>
20#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23#include <sound/initval.h> 22#include <sound/initval.h>
24 23
25#include <sound/uda134x.h> 24#include <sound/uda134x.h>
@@ -389,7 +388,7 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec,
389 pd->power(0); 388 pd->power(0);
390 break; 389 break;
391 } 390 }
392 codec->bias_level = level; 391 codec->dapm.bias_level = level;
393 return 0; 392 return 0;
394} 393}
395 394
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c
index 0c6c725736c6..c5ca8cfea60f 100644
--- a/sound/soc/codecs/uda1380.c
+++ b/sound/soc/codecs/uda1380.c
@@ -27,7 +27,6 @@
27#include <sound/control.h> 27#include <sound/control.h>
28#include <sound/initval.h> 28#include <sound/initval.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31#include <sound/tlv.h> 30#include <sound/tlv.h>
32#include <sound/uda1380.h> 31#include <sound/uda1380.h>
33 32
@@ -36,7 +35,6 @@
36/* codec private data */ 35/* codec private data */
37struct uda1380_priv { 36struct uda1380_priv {
38 struct snd_soc_codec *codec; 37 struct snd_soc_codec *codec;
39 u16 reg_cache[UDA1380_CACHEREGNUM];
40 unsigned int dac_clk; 38 unsigned int dac_clk;
41 struct work_struct work; 39 struct work_struct work;
42 void *control_data; 40 void *control_data;
@@ -414,10 +412,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
414 412
415static int uda1380_add_widgets(struct snd_soc_codec *codec) 413static int uda1380_add_widgets(struct snd_soc_codec *codec)
416{ 414{
417 snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, 415 struct snd_soc_dapm_context *dapm = &codec->dapm;
418 ARRAY_SIZE(uda1380_dapm_widgets));
419 416
420 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 417 snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
418 ARRAY_SIZE(uda1380_dapm_widgets));
419 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
421 420
422 return 0; 421 return 0;
423} 422}
@@ -603,7 +602,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
603 int reg; 602 int reg;
604 struct uda1380_platform_data *pdata = codec->dev->platform_data; 603 struct uda1380_platform_data *pdata = codec->dev->platform_data;
605 604
606 if (codec->bias_level == level) 605 if (codec->dapm.bias_level == level)
607 return 0; 606 return 0;
608 607
609 switch (level) { 608 switch (level) {
@@ -613,7 +612,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
613 uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm); 612 uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm);
614 break; 613 break;
615 case SND_SOC_BIAS_STANDBY: 614 case SND_SOC_BIAS_STANDBY:
616 if (codec->bias_level == SND_SOC_BIAS_OFF) { 615 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
617 if (gpio_is_valid(pdata->gpio_power)) { 616 if (gpio_is_valid(pdata->gpio_power)) {
618 gpio_set_value(pdata->gpio_power, 1); 617 gpio_set_value(pdata->gpio_power, 1);
619 mdelay(1); 618 mdelay(1);
@@ -636,7 +635,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec,
636 for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++) 635 for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++)
637 set_bit(reg - 0x10, &uda1380_cache_dirty); 636 set_bit(reg - 0x10, &uda1380_cache_dirty);
638 } 637 }
639 codec->bias_level = level; 638 codec->dapm.bias_level = level;
640 return 0; 639 return 0;
641} 640}
642 641
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 0c47c788ccdf..d3ffa2f0122a 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -25,8 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc-dai.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/initval.h> 29#include <sound/initval.h>
31 30
32#include "wl1273.h" 31#include "wl1273.h"
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 4bcd168794e1..80ddf4fd23db 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -36,7 +36,6 @@
36#include <sound/pcm.h> 36#include <sound/pcm.h>
37#include <sound/pcm_params.h> 37#include <sound/pcm_params.h>
38#include <sound/soc.h> 38#include <sound/soc.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h> 39#include <sound/initval.h>
41#include <sound/tlv.h> 40#include <sound/tlv.h>
42 41
@@ -705,6 +704,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
705/* Called from the machine driver */ 704/* Called from the machine driver */
706int wm2000_add_controls(struct snd_soc_codec *codec) 705int wm2000_add_controls(struct snd_soc_codec *codec)
707{ 706{
707 struct snd_soc_dapm_context *dapm = &codec->dapm;
708 int ret; 708 int ret;
709 709
710 if (!wm2000_i2c) { 710 if (!wm2000_i2c) {
@@ -712,12 +712,12 @@ int wm2000_add_controls(struct snd_soc_codec *codec)
712 return -ENODEV; 712 return -ENODEV;
713 } 713 }
714 714
715 ret = snd_soc_dapm_new_controls(codec, wm2000_dapm_widgets, 715 ret = snd_soc_dapm_new_controls(dapm, wm2000_dapm_widgets,
716 ARRAY_SIZE(wm2000_dapm_widgets)); 716 ARRAY_SIZE(wm2000_dapm_widgets));
717 if (ret < 0) 717 if (ret < 0)
718 return ret; 718 return ret;
719 719
720 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 720 ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
721 if (ret < 0) 721 if (ret < 0)
722 return ret; 722 return ret;
723 723
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 7611add7f8c3..6d6dc9efe914 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -24,9 +24,9 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
29#include <trace/events/asoc.h>
30 30
31#include "wm8350.h" 31#include "wm8350.h"
32 32
@@ -54,6 +54,7 @@ struct wm8350_output {
54 54
55struct wm8350_jack_data { 55struct wm8350_jack_data {
56 struct snd_soc_jack *jack; 56 struct snd_soc_jack *jack;
57 struct delayed_work work;
57 int report; 58 int report;
58 int short_report; 59 int short_report;
59}; 60};
@@ -230,8 +231,9 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec)
230 */ 231 */
231static void wm8350_pga_work(struct work_struct *work) 232static void wm8350_pga_work(struct work_struct *work)
232{ 233{
233 struct snd_soc_codec *codec = 234 struct snd_soc_dapm_context *dapm =
234 container_of(work, struct snd_soc_codec, delayed_work.work); 235 container_of(work, struct snd_soc_dapm_context, delayed_work.work);
236 struct snd_soc_codec *codec = dapm->codec;
235 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); 237 struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec);
236 struct wm8350_output *out1 = &wm8350_data->out1, 238 struct wm8350_output *out1 = &wm8350_data->out1,
237 *out2 = &wm8350_data->out2; 239 *out2 = &wm8350_data->out2;
@@ -302,8 +304,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
302 out->ramp = WM8350_RAMP_UP; 304 out->ramp = WM8350_RAMP_UP;
303 out->active = 1; 305 out->active = 1;
304 306
305 if (!delayed_work_pending(&codec->delayed_work)) 307 if (!delayed_work_pending(&codec->dapm.delayed_work))
306 schedule_delayed_work(&codec->delayed_work, 308 schedule_delayed_work(&codec->dapm.delayed_work,
307 msecs_to_jiffies(1)); 309 msecs_to_jiffies(1));
308 break; 310 break;
309 311
@@ -311,8 +313,8 @@ static int pga_event(struct snd_soc_dapm_widget *w,
311 out->ramp = WM8350_RAMP_DOWN; 313 out->ramp = WM8350_RAMP_DOWN;
312 out->active = 0; 314 out->active = 0;
313 315
314 if (!delayed_work_pending(&codec->delayed_work)) 316 if (!delayed_work_pending(&codec->dapm.delayed_work))
315 schedule_delayed_work(&codec->delayed_work, 317 schedule_delayed_work(&codec->dapm.delayed_work,
316 msecs_to_jiffies(1)); 318 msecs_to_jiffies(1));
317 break; 319 break;
318 } 320 }
@@ -786,9 +788,10 @@ static const struct snd_soc_dapm_route audio_map[] = {
786 788
787static int wm8350_add_widgets(struct snd_soc_codec *codec) 789static int wm8350_add_widgets(struct snd_soc_codec *codec)
788{ 790{
791 struct snd_soc_dapm_context *dapm = &codec->dapm;
789 int ret; 792 int ret;
790 793
791 ret = snd_soc_dapm_new_controls(codec, 794 ret = snd_soc_dapm_new_controls(dapm,
792 wm8350_dapm_widgets, 795 wm8350_dapm_widgets,
793 ARRAY_SIZE(wm8350_dapm_widgets)); 796 ARRAY_SIZE(wm8350_dapm_widgets));
794 if (ret != 0) { 797 if (ret != 0) {
@@ -797,7 +800,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec)
797 } 800 }
798 801
799 /* set up audio paths */ 802 /* set up audio paths */
800 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 803 ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
801 if (ret != 0) { 804 if (ret != 0) {
802 dev_err(codec->dev, "DAPM route register failed\n"); 805 dev_err(codec->dev, "DAPM route register failed\n");
803 return ret; 806 return ret;
@@ -1184,7 +1187,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1184 break; 1187 break;
1185 1188
1186 case SND_SOC_BIAS_STANDBY: 1189 case SND_SOC_BIAS_STANDBY:
1187 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1190 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1188 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), 1191 ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies),
1189 priv->supplies); 1192 priv->supplies);
1190 if (ret != 0) 1193 if (ret != 0)
@@ -1317,7 +1320,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec,
1317 priv->supplies); 1320 priv->supplies);
1318 break; 1321 break;
1319 } 1322 }
1320 codec->bias_level = level; 1323 codec->dapm.bias_level = level;
1321 return 0; 1324 return 0;
1322} 1325}
1323 1326
@@ -1334,45 +1337,69 @@ static int wm8350_resume(struct snd_soc_codec *codec)
1334 return 0; 1337 return 0;
1335} 1338}
1336 1339
1337static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) 1340static void wm8350_hp_work(struct wm8350_data *priv,
1341 struct wm8350_jack_data *jack,
1342 u16 mask)
1338{ 1343{
1339 struct wm8350_data *priv = data;
1340 struct wm8350 *wm8350 = priv->codec.control_data; 1344 struct wm8350 *wm8350 = priv->codec.control_data;
1341 u16 reg; 1345 u16 reg;
1342 int report; 1346 int report;
1343 int mask; 1347
1348 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1349 if (reg & mask)
1350 report = jack->report;
1351 else
1352 report = 0;
1353
1354 snd_soc_jack_report(jack->jack, report, jack->report);
1355
1356}
1357
1358static void wm8350_hpl_work(struct work_struct *work)
1359{
1360 struct wm8350_data *priv =
1361 container_of(work, struct wm8350_data, hpl.work.work);
1362
1363 wm8350_hp_work(priv, &priv->hpl, WM8350_JACK_L_LVL);
1364}
1365
1366static void wm8350_hpr_work(struct work_struct *work)
1367{
1368 struct wm8350_data *priv =
1369 container_of(work, struct wm8350_data, hpr.work.work);
1370
1371 wm8350_hp_work(priv, &priv->hpr, WM8350_JACK_R_LVL);
1372}
1373
1374static irqreturn_t wm8350_hp_jack_handler(int irq, void *data)
1375{
1376 struct wm8350_data *priv = data;
1377 struct wm8350 *wm8350 = priv->codec.control_data;
1344 struct wm8350_jack_data *jack = NULL; 1378 struct wm8350_jack_data *jack = NULL;
1345 1379
1346 switch (irq - wm8350->irq_base) { 1380 switch (irq - wm8350->irq_base) {
1347 case WM8350_IRQ_CODEC_JCK_DET_L: 1381 case WM8350_IRQ_CODEC_JCK_DET_L:
1382#ifndef CONFIG_SND_SOC_WM8350_MODULE
1383 trace_snd_soc_jack_irq("WM8350 HPL");
1384#endif
1348 jack = &priv->hpl; 1385 jack = &priv->hpl;
1349 mask = WM8350_JACK_L_LVL;
1350 break; 1386 break;
1351 1387
1352 case WM8350_IRQ_CODEC_JCK_DET_R: 1388 case WM8350_IRQ_CODEC_JCK_DET_R:
1389#ifndef CONFIG_SND_SOC_WM8350_MODULE
1390 trace_snd_soc_jack_irq("WM8350 HPR");
1391#endif
1353 jack = &priv->hpr; 1392 jack = &priv->hpr;
1354 mask = WM8350_JACK_R_LVL;
1355 break; 1393 break;
1356 1394
1357 default: 1395 default:
1358 BUG(); 1396 BUG();
1359 } 1397 }
1360 1398
1361 if (!jack->jack) { 1399 if (device_may_wakeup(wm8350->dev))
1362 dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); 1400 pm_wakeup_event(wm8350->dev, 250);
1363 return IRQ_NONE;
1364 }
1365
1366 /* Debounce */
1367 msleep(200);
1368
1369 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1370 if (reg & mask)
1371 report = jack->report;
1372 else
1373 report = 0;
1374 1401
1375 snd_soc_jack_report(jack->jack, report, jack->report); 1402 schedule_delayed_work(&jack->work, 200);
1376 1403
1377 return IRQ_HANDLED; 1404 return IRQ_HANDLED;
1378} 1405}
@@ -1436,6 +1463,10 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data)
1436 u16 reg; 1463 u16 reg;
1437 int report = 0; 1464 int report = 0;
1438 1465
1466#ifndef CONFIG_SND_SOC_WM8350_MODULE
1467 trace_snd_soc_jack_irq("WM8350 mic");
1468#endif
1469
1439 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); 1470 reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS);
1440 if (reg & WM8350_JACK_MICSCD_LVL) 1471 if (reg & WM8350_JACK_MICSCD_LVL)
1441 report |= priv->mic.short_report; 1472 report |= priv->mic.short_report;
@@ -1550,7 +1581,9 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1550 /* Put the codec into reset if it wasn't already */ 1581 /* Put the codec into reset if it wasn't already */
1551 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1582 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
1552 1583
1553 INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work); 1584 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work);
1585 INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work);
1586 INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work);
1554 1587
1555 /* Enable the codec */ 1588 /* Enable the codec */
1556 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1589 wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1626,7 +1659,6 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
1626{ 1659{
1627 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); 1660 struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec);
1628 struct wm8350 *wm8350 = dev_get_platdata(codec->dev); 1661 struct wm8350 *wm8350 = dev_get_platdata(codec->dev);
1629 int ret;
1630 1662
1631 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, 1663 wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
1632 WM8350_JDL_ENA | WM8350_JDR_ENA); 1664 WM8350_JDL_ENA | WM8350_JDR_ENA);
@@ -1641,15 +1673,12 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec)
1641 priv->hpr.jack = NULL; 1673 priv->hpr.jack = NULL;
1642 priv->mic.jack = NULL; 1674 priv->mic.jack = NULL;
1643 1675
1644 /* cancel any work waiting to be queued. */ 1676 cancel_delayed_work_sync(&priv->hpl.work);
1645 ret = cancel_delayed_work(&codec->delayed_work); 1677 cancel_delayed_work_sync(&priv->hpr.work);
1646 1678
1647 /* if there was any work waiting then we run it now and 1679 /* if there was any work waiting then we run it now and
1648 * wait for its completion */ 1680 * wait for its completion */
1649 if (ret) { 1681 flush_delayed_work_sync(&codec->dapm.delayed_work);
1650 schedule_delayed_work(&codec->delayed_work, 0);
1651 flush_scheduled_work();
1652 }
1653 1682
1654 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); 1683 wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);
1655 1684
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 850299786e02..3c3bc079167e 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -26,7 +26,6 @@
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/initval.h> 29#include <sound/initval.h>
31#include <sound/tlv.h> 30#include <sound/tlv.h>
32 31
@@ -911,10 +910,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
911 910
912static int wm8400_add_widgets(struct snd_soc_codec *codec) 911static int wm8400_add_widgets(struct snd_soc_codec *codec)
913{ 912{
914 snd_soc_dapm_new_controls(codec, wm8400_dapm_widgets, 913 struct snd_soc_dapm_context *dapm = &codec->dapm;
915 ARRAY_SIZE(wm8400_dapm_widgets));
916 914
917 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 915 snd_soc_dapm_new_controls(dapm, wm8400_dapm_widgets,
916 ARRAY_SIZE(wm8400_dapm_widgets));
917 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
918 918
919 return 0; 919 return 0;
920} 920}
@@ -1219,7 +1219,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1219 break; 1219 break;
1220 1220
1221 case SND_SOC_BIAS_STANDBY: 1221 case SND_SOC_BIAS_STANDBY:
1222 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1222 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1223 ret = regulator_bulk_enable(ARRAY_SIZE(power), 1223 ret = regulator_bulk_enable(ARRAY_SIZE(power),
1224 &power[0]); 1224 &power[0]);
1225 if (ret != 0) { 1225 if (ret != 0) {
@@ -1306,7 +1306,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec,
1306 break; 1306 break;
1307 } 1307 }
1308 1308
1309 codec->bias_level = level; 1309 codec->dapm.bias_level = level;
1310 return 0; 1310 return 0;
1311} 1311}
1312 1312
diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c
index 8f107095760e..db0dced74843 100644
--- a/sound/soc/codecs/wm8510.c
+++ b/sound/soc/codecs/wm8510.c
@@ -24,7 +24,6 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29 28
30#include "wm8510.h" 29#include "wm8510.h"
@@ -216,10 +215,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
216 215
217static int wm8510_add_widgets(struct snd_soc_codec *codec) 216static int wm8510_add_widgets(struct snd_soc_codec *codec)
218{ 217{
219 snd_soc_dapm_new_controls(codec, wm8510_dapm_widgets, 218 struct snd_soc_dapm_context *dapm = &codec->dapm;
220 ARRAY_SIZE(wm8510_dapm_widgets));
221 219
222 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 220 snd_soc_dapm_new_controls(dapm, wm8510_dapm_widgets,
221 ARRAY_SIZE(wm8510_dapm_widgets));
222 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
223 223
224 return 0; 224 return 0;
225} 225}
@@ -478,7 +478,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
478 case SND_SOC_BIAS_STANDBY: 478 case SND_SOC_BIAS_STANDBY:
479 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; 479 power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN;
480 480
481 if (codec->bias_level == SND_SOC_BIAS_OFF) { 481 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
482 /* Initial cap charge at VMID 5k */ 482 /* Initial cap charge at VMID 5k */
483 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); 483 snd_soc_write(codec, WM8510_POWER1, power1 | 0x3);
484 mdelay(100); 484 mdelay(100);
@@ -495,7 +495,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec,
495 break; 495 break;
496 } 496 }
497 497
498 codec->bias_level = level; 498 codec->dapm.bias_level = level;
499 return 0; 499 return 0;
500} 500}
501 501
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c
index deca79ea2b4b..5eb2f501ce32 100644
--- a/sound/soc/codecs/wm8523.c
+++ b/sound/soc/codecs/wm8523.c
@@ -24,7 +24,6 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30 29
@@ -109,10 +108,11 @@ static const struct snd_soc_dapm_route intercon[] = {
109 108
110static int wm8523_add_widgets(struct snd_soc_codec *codec) 109static int wm8523_add_widgets(struct snd_soc_codec *codec)
111{ 110{
112 snd_soc_dapm_new_controls(codec, wm8523_dapm_widgets, 111 struct snd_soc_dapm_context *dapm = &codec->dapm;
113 ARRAY_SIZE(wm8523_dapm_widgets));
114 112
115 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 113 snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets,
114 ARRAY_SIZE(wm8523_dapm_widgets));
115 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
116 116
117 return 0; 117 return 0;
118} 118}
@@ -327,7 +327,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
327 break; 327 break;
328 328
329 case SND_SOC_BIAS_STANDBY: 329 case SND_SOC_BIAS_STANDBY:
330 if (codec->bias_level == SND_SOC_BIAS_OFF) { 330 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
331 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), 331 ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies),
332 wm8523->supplies); 332 wm8523->supplies);
333 if (ret != 0) { 333 if (ret != 0) {
@@ -366,7 +366,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec,
366 wm8523->supplies); 366 wm8523->supplies);
367 break; 367 break;
368 } 368 }
369 codec->bias_level = level; 369 codec->dapm.bias_level = level;
370 return 0; 370 return 0;
371} 371}
372 372
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 8725d4e75431..8f6b5ee6645b 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -31,7 +31,6 @@
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <sound/pcm_params.h> 32#include <sound/pcm_params.h>
33#include <sound/soc.h> 33#include <sound/soc.h>
34#include <sound/soc-dapm.h>
35#include <sound/tlv.h> 34#include <sound/tlv.h>
36#include <sound/initval.h> 35#include <sound/initval.h>
37#include <asm/div64.h> 36#include <asm/div64.h>
@@ -191,7 +190,6 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = {
191struct wm8580_priv { 190struct wm8580_priv {
192 enum snd_soc_control_type control_type; 191 enum snd_soc_control_type control_type;
193 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; 192 struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES];
194 u16 reg_cache[WM8580_MAX_REGISTER + 1];
195 struct pll_state a; 193 struct pll_state a;
196 struct pll_state b; 194 struct pll_state b;
197 int sysclk[2]; 195 int sysclk[2];
@@ -302,10 +300,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
302 300
303static int wm8580_add_widgets(struct snd_soc_codec *codec) 301static int wm8580_add_widgets(struct snd_soc_codec *codec)
304{ 302{
305 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets, 303 struct snd_soc_dapm_context *dapm = &codec->dapm;
306 ARRAY_SIZE(wm8580_dapm_widgets));
307 304
308 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 305 snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets,
306 ARRAY_SIZE(wm8580_dapm_widgets));
307 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
309 308
310 return 0; 309 return 0;
311} 310}
@@ -507,13 +506,13 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream,
507 } 506 }
508 507
509 /* Look up the SYSCLK ratio; accept only exact matches */ 508 /* Look up the SYSCLK ratio; accept only exact matches */
510 ratio = wm8580->sysclk[dai->id] / params_rate(params); 509 ratio = wm8580->sysclk[dai->driver->id] / params_rate(params);
511 for (i = 0; i < ARRAY_SIZE(wm8580_sysclk_ratios); i++) 510 for (i = 0; i < ARRAY_SIZE(wm8580_sysclk_ratios); i++)
512 if (ratio == wm8580_sysclk_ratios[i]) 511 if (ratio == wm8580_sysclk_ratios[i])
513 break; 512 break;
514 if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) { 513 if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) {
515 dev_err(codec->dev, "Invalid clock ratio %d/%d\n", 514 dev_err(codec->dev, "Invalid clock ratio %d/%d\n",
516 wm8580->sysclk[dai->id], params_rate(params)); 515 wm8580->sysclk[dai->driver->id], params_rate(params));
517 return -EINVAL; 516 return -EINVAL;
518 } 517 }
519 paifa |= i; 518 paifa |= i;
@@ -716,7 +715,7 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
716 715
717 switch (clk_id) { 716 switch (clk_id) {
718 case WM8580_CLKSRC_ADCMCLK: 717 case WM8580_CLKSRC_ADCMCLK:
719 if (dai->id != WM8580_DAI_PAIFTX) 718 if (dai->driver->id != WM8580_DAI_PAIFTX)
720 return -EINVAL; 719 return -EINVAL;
721 sel = 0 << sel_shift; 720 sel = 0 << sel_shift;
722 break; 721 break;
@@ -735,7 +734,7 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id,
735 } 734 }
736 735
737 /* We really should validate PLL settings but not yet */ 736 /* We really should validate PLL settings but not yet */
738 wm8580->sysclk[dai->id] = freq; 737 wm8580->sysclk[dai->driver->id] = freq;
739 738
740 return snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel); 739 return snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel);
741} 740}
@@ -767,7 +766,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
767 break; 766 break;
768 767
769 case SND_SOC_BIAS_STANDBY: 768 case SND_SOC_BIAS_STANDBY:
770 if (codec->bias_level == SND_SOC_BIAS_OFF) { 769 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
771 /* Power up and get individual control of the DACs */ 770 /* Power up and get individual control of the DACs */
772 reg = snd_soc_read(codec, WM8580_PWRDN1); 771 reg = snd_soc_read(codec, WM8580_PWRDN1);
773 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); 772 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD);
@@ -785,7 +784,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
785 snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); 784 snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN);
786 break; 785 break;
787 } 786 }
788 codec->bias_level = level; 787 codec->dapm.bias_level = level;
789 return 0; 788 return 0;
790} 789}
791 790
@@ -905,7 +904,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
905 .set_bias_level = wm8580_set_bias_level, 904 .set_bias_level = wm8580_set_bias_level,
906 .reg_cache_size = ARRAY_SIZE(wm8580_reg), 905 .reg_cache_size = ARRAY_SIZE(wm8580_reg),
907 .reg_word_size = sizeof(u16), 906 .reg_word_size = sizeof(u16),
908 .reg_cache_default = &wm8580_reg, 907 .reg_cache_default = wm8580_reg,
909}; 908};
910 909
911#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 910#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c
index 54fbd76c8bca..97c30382d3ff 100644
--- a/sound/soc/codecs/wm8711.c
+++ b/sound/soc/codecs/wm8711.c
@@ -25,7 +25,6 @@
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30#include <sound/initval.h> 29#include <sound/initval.h>
31 30
@@ -34,7 +33,6 @@
34/* codec private data */ 33/* codec private data */
35struct wm8711_priv { 34struct wm8711_priv {
36 enum snd_soc_control_type bus_type; 35 enum snd_soc_control_type bus_type;
37 u16 reg_cache[WM8711_CACHEREGNUM];
38 unsigned int sysclk; 36 unsigned int sysclk;
39}; 37};
40 38
@@ -93,10 +91,11 @@ static const struct snd_soc_dapm_route intercon[] = {
93 91
94static int wm8711_add_widgets(struct snd_soc_codec *codec) 92static int wm8711_add_widgets(struct snd_soc_codec *codec)
95{ 93{
96 snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets, 94 struct snd_soc_dapm_context *dapm = &codec->dapm;
97 ARRAY_SIZE(wm8711_dapm_widgets));
98 95
99 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 96 snd_soc_dapm_new_controls(dapm, wm8711_dapm_widgets,
97 ARRAY_SIZE(wm8711_dapm_widgets));
98 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
100 99
101 return 0; 100 return 0;
102} 101}
@@ -318,7 +317,7 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec,
318 snd_soc_write(codec, WM8711_PWR, 0xffff); 317 snd_soc_write(codec, WM8711_PWR, 0xffff);
319 break; 318 break;
320 } 319 }
321 codec->bias_level = level; 320 codec->dapm.bias_level = level;
322 return 0; 321 return 0;
323} 322}
324 323
diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c
index 075f35e4f4cb..736b0352d0a7 100644
--- a/sound/soc/codecs/wm8728.c
+++ b/sound/soc/codecs/wm8728.c
@@ -23,7 +23,6 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29 28
@@ -73,10 +72,11 @@ static const struct snd_soc_dapm_route intercon[] = {
73 72
74static int wm8728_add_widgets(struct snd_soc_codec *codec) 73static int wm8728_add_widgets(struct snd_soc_codec *codec)
75{ 74{
76 snd_soc_dapm_new_controls(codec, wm8728_dapm_widgets, 75 struct snd_soc_dapm_context *dapm = &codec->dapm;
77 ARRAY_SIZE(wm8728_dapm_widgets));
78 76
79 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 77 snd_soc_dapm_new_controls(dapm, wm8728_dapm_widgets,
78 ARRAY_SIZE(wm8728_dapm_widgets));
79 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
80 80
81 return 0; 81 return 0;
82} 82}
@@ -180,7 +180,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
180 case SND_SOC_BIAS_ON: 180 case SND_SOC_BIAS_ON:
181 case SND_SOC_BIAS_PREPARE: 181 case SND_SOC_BIAS_PREPARE:
182 case SND_SOC_BIAS_STANDBY: 182 case SND_SOC_BIAS_STANDBY:
183 if (codec->bias_level == SND_SOC_BIAS_OFF) { 183 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
184 /* Power everything up... */ 184 /* Power everything up... */
185 reg = snd_soc_read(codec, WM8728_DACCTL); 185 reg = snd_soc_read(codec, WM8728_DACCTL);
186 snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4); 186 snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4);
@@ -197,7 +197,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec,
197 snd_soc_write(codec, WM8728_DACCTL, reg | 0x4); 197 snd_soc_write(codec, WM8728_DACCTL, reg | 0x4);
198 break; 198 break;
199 } 199 }
200 codec->bias_level = level; 200 codec->dapm.bias_level = level;
201 return 0; 201 return 0;
202} 202}
203 203
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index e725c09a3e79..0a67c31b2663 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -26,7 +26,6 @@
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/initval.h> 29#include <sound/initval.h>
31#include <sound/tlv.h> 30#include <sound/tlv.h>
32 31
@@ -44,9 +43,10 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = {
44struct wm8731_priv { 43struct wm8731_priv {
45 enum snd_soc_control_type control_type; 44 enum snd_soc_control_type control_type;
46 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 45 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES];
47 u16 reg_cache[WM8731_CACHEREGNUM];
48 unsigned int sysclk; 46 unsigned int sysclk;
49 int sysclk_type; 47 int sysclk_type;
48 int playback_fs;
49 bool deemph;
50}; 50};
51 51
52 52
@@ -65,16 +65,79 @@ static const u16 wm8731_reg[WM8731_CACHEREGNUM] = {
65#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) 65#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0)
66 66
67static const char *wm8731_input_select[] = {"Line In", "Mic"}; 67static const char *wm8731_input_select[] = {"Line In", "Mic"};
68static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"};
69 68
70static const struct soc_enum wm8731_enum[] = { 69static const struct soc_enum wm8731_insel_enum =
71 SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select), 70 SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select);
72 SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph), 71
73}; 72static int wm8731_deemph[] = { 0, 32000, 44100, 48000 };
73
74static int wm8731_set_deemph(struct snd_soc_codec *codec)
75{
76 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
77 int val, i, best;
78
79 /* If we're using deemphasis select the nearest available sample
80 * rate.
81 */
82 if (wm8731->deemph) {
83 best = 1;
84 for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) {
85 if (abs(wm8731_deemph[i] - wm8731->playback_fs) <
86 abs(wm8731_deemph[best] - wm8731->playback_fs))
87 best = i;
88 }
89
90 val = best << 1;
91 } else {
92 best = 0;
93 val = 0;
94 }
95
96 dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
97 best, wm8731_deemph[best]);
98
99 return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val);
100}
101
102static int wm8731_get_deemph(struct snd_kcontrol *kcontrol,
103 struct snd_ctl_elem_value *ucontrol)
104{
105 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
106 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
107
108 ucontrol->value.enumerated.item[0] = wm8731->deemph;
109
110 return 0;
111}
112
113static int wm8731_put_deemph(struct snd_kcontrol *kcontrol,
114 struct snd_ctl_elem_value *ucontrol)
115{
116 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
117 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec);
118 int deemph = ucontrol->value.enumerated.item[0];
119 int ret = 0;
120
121 if (deemph > 1)
122 return -EINVAL;
123
124 mutex_lock(&codec->mutex);
125 if (wm8731->deemph != deemph) {
126 wm8731->deemph = deemph;
127
128 wm8731_set_deemph(codec);
129
130 ret = 1;
131 }
132 mutex_unlock(&codec->mutex);
133
134 return ret;
135}
74 136
75static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0); 137static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0);
76static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0); 138static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0);
77static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); 139static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
140static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 2000, 0);
78 141
79static const struct snd_kcontrol_new wm8731_snd_controls[] = { 142static const struct snd_kcontrol_new wm8731_snd_controls[] = {
80 143
@@ -87,7 +150,7 @@ SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0,
87 in_tlv), 150 in_tlv),
88SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1), 151SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1),
89 152
90SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0), 153SOC_SINGLE_TLV("Mic Boost Volume", WM8731_APANA, 0, 1, 0, mic_tlv),
91SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1), 154SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1),
92 155
93SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1, 156SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
@@ -96,7 +159,8 @@ SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1,
96SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), 159SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1),
97SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), 160SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0),
98 161
99SOC_ENUM("Playback De-emphasis", wm8731_enum[1]), 162SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
163 wm8731_get_deemph, wm8731_put_deemph),
100}; 164};
101 165
102/* Output Mixer */ 166/* Output Mixer */
@@ -108,7 +172,7 @@ SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
108 172
109/* Input mux */ 173/* Input mux */
110static const struct snd_kcontrol_new wm8731_input_mux_controls = 174static const struct snd_kcontrol_new wm8731_input_mux_controls =
111SOC_DAPM_ENUM("Input Select", wm8731_enum[0]); 175SOC_DAPM_ENUM("Input Select", wm8731_insel_enum);
112 176
113static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { 177static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = {
114SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0), 178SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0),
@@ -165,10 +229,11 @@ static const struct snd_soc_dapm_route intercon[] = {
165 229
166static int wm8731_add_widgets(struct snd_soc_codec *codec) 230static int wm8731_add_widgets(struct snd_soc_codec *codec)
167{ 231{
168 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, 232 struct snd_soc_dapm_context *dapm = &codec->dapm;
169 ARRAY_SIZE(wm8731_dapm_widgets));
170 233
171 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 234 snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
235 ARRAY_SIZE(wm8731_dapm_widgets));
236 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
172 237
173 return 0; 238 return 0;
174} 239}
@@ -239,6 +304,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
239 u16 srate = (coeff_div[i].sr << 2) | 304 u16 srate = (coeff_div[i].sr << 2) |
240 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 305 (coeff_div[i].bosr << 1) | coeff_div[i].usb;
241 306
307 wm8731->playback_fs = params_rate(params);
308
242 snd_soc_write(codec, WM8731_SRATE, srate); 309 snd_soc_write(codec, WM8731_SRATE, srate);
243 310
244 /* bit size */ 311 /* bit size */
@@ -253,6 +320,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream,
253 break; 320 break;
254 } 321 }
255 322
323 wm8731_set_deemph(codec);
324
256 snd_soc_write(codec, WM8731_IFACE, iface); 325 snd_soc_write(codec, WM8731_IFACE, iface);
257 return 0; 326 return 0;
258} 327}
@@ -319,7 +388,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai,
319 return -EINVAL; 388 return -EINVAL;
320 } 389 }
321 390
322 snd_soc_dapm_sync(codec); 391 snd_soc_dapm_sync(&codec->dapm);
323 392
324 return 0; 393 return 0;
325} 394}
@@ -399,7 +468,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
399 case SND_SOC_BIAS_PREPARE: 468 case SND_SOC_BIAS_PREPARE:
400 break; 469 break;
401 case SND_SOC_BIAS_STANDBY: 470 case SND_SOC_BIAS_STANDBY:
402 if (codec->bias_level == SND_SOC_BIAS_OFF) { 471 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
403 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), 472 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies),
404 wm8731->supplies); 473 wm8731->supplies);
405 if (ret != 0) 474 if (ret != 0)
@@ -428,7 +497,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec,
428 wm8731->supplies); 497 wm8731->supplies);
429 break; 498 break;
430 } 499 }
431 codec->bias_level = level; 500 codec->dapm.bias_level = level;
432 return 0; 501 return 0;
433} 502}
434 503
@@ -542,7 +611,6 @@ err_regulator_enable:
542err_regulator_get: 611err_regulator_get:
543 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 612 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
544 613
545 kfree(wm8731);
546 return ret; 614 return ret;
547} 615}
548 616
diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c
new file mode 100644
index 000000000000..30c67d06a904
--- /dev/null
+++ b/sound/soc/codecs/wm8737.c
@@ -0,0 +1,754 @@
1/*
2 * wm8737.c -- WM8737 ALSA SoC Audio driver
3 *
4 * Copyright 2010 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/regulator/consumer.h>
21#include <linux/spi/spi.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include "wm8737.h"
32
33#define WM8737_NUM_SUPPLIES 4
34static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = {
35 "DCVDD",
36 "DBVDD",
37 "AVDD",
38 "MVDD",
39};
40
41/* codec private data */
42struct wm8737_priv {
43 enum snd_soc_control_type control_type;
44 struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES];
45 unsigned int mclk;
46};
47
48static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = {
49 0x00C3, /* R0 - Left PGA volume */
50 0x00C3, /* R1 - Right PGA volume */
51 0x0007, /* R2 - AUDIO path L */
52 0x0007, /* R3 - AUDIO path R */
53 0x0000, /* R4 - 3D Enhance */
54 0x0000, /* R5 - ADC Control */
55 0x0000, /* R6 - Power Management */
56 0x000A, /* R7 - Audio Format */
57 0x0000, /* R8 - Clocking */
58 0x000F, /* R9 - MIC Preamp Control */
59 0x0003, /* R10 - Misc Bias Control */
60 0x0000, /* R11 - Noise Gate */
61 0x007C, /* R12 - ALC1 */
62 0x0000, /* R13 - ALC2 */
63 0x0032, /* R14 - ALC3 */
64};
65
66static int wm8737_reset(struct snd_soc_codec *codec)
67{
68 return snd_soc_write(codec, WM8737_RESET, 0);
69}
70
71static const unsigned int micboost_tlv[] = {
72 TLV_DB_RANGE_HEAD(4),
73 0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0),
74 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0),
75 2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0),
76 3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0),
77};
78static const DECLARE_TLV_DB_SCALE(pga_tlv, -9750, 50, 1);
79static const DECLARE_TLV_DB_SCALE(adc_tlv, -600, 600, 0);
80static const DECLARE_TLV_DB_SCALE(ng_tlv, -7800, 600, 0);
81static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -1200, 600, 0);
82static const DECLARE_TLV_DB_SCALE(alc_target_tlv, -1800, 100, 0);
83
84static const char *micbias_enum_text[] = {
85 "25%",
86 "50%",
87 "75%",
88 "100%",
89};
90
91static const struct soc_enum micbias_enum =
92 SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 0, 4, micbias_enum_text);
93
94static const char *low_cutoff_text[] = {
95 "Low", "High"
96};
97
98static const struct soc_enum low_3d =
99 SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 6, 2, low_cutoff_text);
100
101static const char *high_cutoff_text[] = {
102 "High", "Low"
103};
104
105static const struct soc_enum high_3d =
106 SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text);
107
108static const char *alc_fn_text[] = {
109 "Disabled", "Right", "Left", "Stereo"
110};
111
112static const struct soc_enum alc_fn =
113 SOC_ENUM_SINGLE(WM8737_ALC1, 7, 4, alc_fn_text);
114
115static const char *alc_hold_text[] = {
116 "0", "2.67ms", "5.33ms", "10.66ms", "21.32ms", "42.64ms", "85.28ms",
117 "170.56ms", "341.12ms", "682.24ms", "1.364s", "2.728s", "5.458s",
118 "10.916s", "21.832s", "43.691s"
119};
120
121static const struct soc_enum alc_hold =
122 SOC_ENUM_SINGLE(WM8737_ALC2, 0, 16, alc_hold_text);
123
124static const char *alc_atk_text[] = {
125 "8.4ms", "16.8ms", "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms",
126 "1.075s", "2.15s", "4.3s", "8.6s"
127};
128
129static const struct soc_enum alc_atk =
130 SOC_ENUM_SINGLE(WM8737_ALC3, 0, 11, alc_atk_text);
131
132static const char *alc_dcy_text[] = {
133 "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", "1.075s", "2.15s",
134 "4.3s", "8.6s", "17.2s", "34.41s"
135};
136
137static const struct soc_enum alc_dcy =
138 SOC_ENUM_SINGLE(WM8737_ALC3, 4, 11, alc_dcy_text);
139
140static const struct snd_kcontrol_new wm8737_snd_controls[] = {
141SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
142 6, 3, 0, micboost_tlv),
143SOC_DOUBLE_R("Mic Boost Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
144 4, 1, 0),
145SOC_DOUBLE("Mic ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
146 3, 1, 0),
147
148SOC_DOUBLE_R_TLV("Capture Volume", WM8737_LEFT_PGA_VOLUME,
149 WM8737_RIGHT_PGA_VOLUME, 0, 255, 0, pga_tlv),
150SOC_DOUBLE("Capture ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R,
151 2, 1, 0),
152
153SOC_DOUBLE("INPUT1 DC Bias Switch", WM8737_MISC_BIAS_CONTROL, 0, 1, 1, 0),
154
155SOC_ENUM("Mic PGA Bias", micbias_enum),
156SOC_SINGLE("ADC Low Power Switch", WM8737_ADC_CONTROL, 2, 1, 0),
157SOC_SINGLE("High Pass Filter Switch", WM8737_ADC_CONTROL, 0, 1, 1),
158SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0),
159
160SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0),
161SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0),
162SOC_ENUM("3D Low Cut-off", low_3d),
163SOC_ENUM("3D High Cut-off", low_3d),
164SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv),
165
166SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0),
167SOC_SINGLE_TLV("Noise Gate Threshold Volume", WM8737_NOISE_GATE, 2, 7, 0,
168 ng_tlv),
169
170SOC_ENUM("ALC", alc_fn),
171SOC_SINGLE_TLV("ALC Max Gain Volume", WM8737_ALC1, 4, 7, 0, alc_max_tlv),
172SOC_SINGLE_TLV("ALC Target Volume", WM8737_ALC1, 0, 15, 0, alc_target_tlv),
173SOC_ENUM("ALC Hold Time", alc_hold),
174SOC_SINGLE("ALC ZC Switch", WM8737_ALC2, 4, 1, 0),
175SOC_ENUM("ALC Attack Time", alc_atk),
176SOC_ENUM("ALC Decay Time", alc_dcy),
177};
178
179static const char *linsel_text[] = {
180 "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC",
181};
182
183static const struct soc_enum linsel_enum =
184 SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_L, 7, 4, linsel_text);
185
186static const struct snd_kcontrol_new linsel_mux =
187 SOC_DAPM_ENUM("LINSEL", linsel_enum);
188
189
190static const char *rinsel_text[] = {
191 "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC",
192};
193
194static const struct soc_enum rinsel_enum =
195 SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_R, 7, 4, rinsel_text);
196
197static const struct snd_kcontrol_new rinsel_mux =
198 SOC_DAPM_ENUM("RINSEL", rinsel_enum);
199
200static const char *bypass_text[] = {
201 "Direct", "Preamp"
202};
203
204static const struct soc_enum lbypass_enum =
205 SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 2, 2, bypass_text);
206
207static const struct snd_kcontrol_new lbypass_mux =
208 SOC_DAPM_ENUM("Left Bypass", lbypass_enum);
209
210
211static const struct soc_enum rbypass_enum =
212 SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 3, 2, bypass_text);
213
214static const struct snd_kcontrol_new rbypass_mux =
215 SOC_DAPM_ENUM("Left Bypass", rbypass_enum);
216
217static const struct snd_soc_dapm_widget wm8737_dapm_widgets[] = {
218SND_SOC_DAPM_INPUT("LINPUT1"),
219SND_SOC_DAPM_INPUT("LINPUT2"),
220SND_SOC_DAPM_INPUT("LINPUT3"),
221SND_SOC_DAPM_INPUT("RINPUT1"),
222SND_SOC_DAPM_INPUT("RINPUT2"),
223SND_SOC_DAPM_INPUT("RINPUT3"),
224SND_SOC_DAPM_INPUT("LACIN"),
225SND_SOC_DAPM_INPUT("RACIN"),
226
227SND_SOC_DAPM_MUX("LINSEL", SND_SOC_NOPM, 0, 0, &linsel_mux),
228SND_SOC_DAPM_MUX("RINSEL", SND_SOC_NOPM, 0, 0, &rinsel_mux),
229
230SND_SOC_DAPM_MUX("Left Preamp Mux", SND_SOC_NOPM, 0, 0, &lbypass_mux),
231SND_SOC_DAPM_MUX("Right Preamp Mux", SND_SOC_NOPM, 0, 0, &rbypass_mux),
232
233SND_SOC_DAPM_PGA("PGAL", WM8737_POWER_MANAGEMENT, 5, 0, NULL, 0),
234SND_SOC_DAPM_PGA("PGAR", WM8737_POWER_MANAGEMENT, 4, 0, NULL, 0),
235
236SND_SOC_DAPM_DAC("ADCL", NULL, WM8737_POWER_MANAGEMENT, 3, 0),
237SND_SOC_DAPM_DAC("ADCR", NULL, WM8737_POWER_MANAGEMENT, 2, 0),
238
239SND_SOC_DAPM_AIF_OUT("AIF", "Capture", 0, WM8737_POWER_MANAGEMENT, 6, 0),
240};
241
242static const struct snd_soc_dapm_route intercon[] = {
243 { "LINSEL", "LINPUT1", "LINPUT1" },
244 { "LINSEL", "LINPUT2", "LINPUT2" },
245 { "LINSEL", "LINPUT3", "LINPUT3" },
246 { "LINSEL", "LINPUT1 DC", "LINPUT1" },
247
248 { "RINSEL", "RINPUT1", "RINPUT1" },
249 { "RINSEL", "RINPUT2", "RINPUT2" },
250 { "RINSEL", "RINPUT3", "RINPUT3" },
251 { "RINSEL", "RINPUT1 DC", "RINPUT1" },
252
253 { "Left Preamp Mux", "Preamp", "LINSEL" },
254 { "Left Preamp Mux", "Direct", "LACIN" },
255
256 { "Right Preamp Mux", "Preamp", "RINSEL" },
257 { "Right Preamp Mux", "Direct", "RACIN" },
258
259 { "PGAL", NULL, "Left Preamp Mux" },
260 { "PGAR", NULL, "Right Preamp Mux" },
261
262 { "ADCL", NULL, "PGAL" },
263 { "ADCR", NULL, "PGAR" },
264
265 { "AIF", NULL, "ADCL" },
266 { "AIF", NULL, "ADCR" },
267};
268
269static int wm8737_add_widgets(struct snd_soc_codec *codec)
270{
271 struct snd_soc_dapm_context *dapm = &codec->dapm;
272
273 snd_soc_dapm_new_controls(dapm, wm8737_dapm_widgets,
274 ARRAY_SIZE(wm8737_dapm_widgets));
275 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
276
277 return 0;
278}
279
280/* codec mclk clock divider coefficients */
281static const struct {
282 u32 mclk;
283 u32 rate;
284 u8 usb;
285 u8 sr;
286} coeff_div[] = {
287 { 12288000, 8000, 0, 0x4 },
288 { 12288000, 12000, 0, 0x8 },
289 { 12288000, 16000, 0, 0xa },
290 { 12288000, 24000, 0, 0x1c },
291 { 12288000, 32000, 0, 0xc },
292 { 12288000, 48000, 0, 0 },
293 { 12288000, 96000, 0, 0xe },
294
295 { 11289600, 8000, 0, 0x14 },
296 { 11289600, 11025, 0, 0x18 },
297 { 11289600, 22050, 0, 0x1a },
298 { 11289600, 44100, 0, 0x10 },
299 { 11289600, 88200, 0, 0x1e },
300
301 { 18432000, 8000, 0, 0x5 },
302 { 18432000, 12000, 0, 0x9 },
303 { 18432000, 16000, 0, 0xb },
304 { 18432000, 24000, 0, 0x1b },
305 { 18432000, 32000, 0, 0xd },
306 { 18432000, 48000, 0, 0x1 },
307 { 18432000, 96000, 0, 0x1f },
308
309 { 16934400, 8000, 0, 0x15 },
310 { 16934400, 11025, 0, 0x19 },
311 { 16934400, 22050, 0, 0x1b },
312 { 16934400, 44100, 0, 0x11 },
313 { 16934400, 88200, 0, 0x1f },
314
315 { 12000000, 8000, 1, 0x4 },
316 { 12000000, 11025, 1, 0x19 },
317 { 12000000, 12000, 1, 0x8 },
318 { 12000000, 16000, 1, 0xa },
319 { 12000000, 22050, 1, 0x1b },
320 { 12000000, 24000, 1, 0x1c },
321 { 12000000, 32000, 1, 0xc },
322 { 12000000, 44100, 1, 0x11 },
323 { 12000000, 48000, 1, 0x0 },
324 { 12000000, 88200, 1, 0x1f },
325 { 12000000, 96000, 1, 0xe },
326};
327
328static int wm8737_hw_params(struct snd_pcm_substream *substream,
329 struct snd_pcm_hw_params *params,
330 struct snd_soc_dai *dai)
331{
332 struct snd_soc_pcm_runtime *rtd = substream->private_data;
333 struct snd_soc_codec *codec = rtd->codec;
334 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
335 int i;
336 u16 clocking = 0;
337 u16 af = 0;
338
339 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
340 if (coeff_div[i].rate != params_rate(params))
341 continue;
342
343 if (coeff_div[i].mclk == wm8737->mclk)
344 break;
345
346 if (coeff_div[i].mclk == wm8737->mclk * 2) {
347 clocking |= WM8737_CLKDIV2;
348 break;
349 }
350 }
351
352 if (i == ARRAY_SIZE(coeff_div)) {
353 dev_err(codec->dev, "%dHz MCLK can't support %dHz\n",
354 wm8737->mclk, params_rate(params));
355 return -EINVAL;
356 }
357
358 clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT);
359
360 switch (params_format(params)) {
361 case SNDRV_PCM_FORMAT_S16_LE:
362 break;
363 case SNDRV_PCM_FORMAT_S20_3LE:
364 af |= 0x8;
365 break;
366 case SNDRV_PCM_FORMAT_S24_LE:
367 af |= 0x10;
368 break;
369 case SNDRV_PCM_FORMAT_S32_LE:
370 af |= 0x18;
371 break;
372 default:
373 return -EINVAL;
374 }
375
376 snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af);
377 snd_soc_update_bits(codec, WM8737_CLOCKING,
378 WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK,
379 clocking);
380
381 return 0;
382}
383
384static int wm8737_set_dai_sysclk(struct snd_soc_dai *codec_dai,
385 int clk_id, unsigned int freq, int dir)
386{
387 struct snd_soc_codec *codec = codec_dai->codec;
388 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
389 int i;
390
391 for (i = 0; i < ARRAY_SIZE(coeff_div); i++) {
392 if (freq == coeff_div[i].mclk ||
393 freq == coeff_div[i].mclk * 2) {
394 wm8737->mclk = freq;
395 return 0;
396 }
397 }
398
399 dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq);
400
401 return -EINVAL;
402}
403
404
405static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai,
406 unsigned int fmt)
407{
408 struct snd_soc_codec *codec = codec_dai->codec;
409 u16 af = 0;
410
411 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
412 case SND_SOC_DAIFMT_CBM_CFM:
413 af |= WM8737_MS;
414 break;
415 case SND_SOC_DAIFMT_CBS_CFS:
416 break;
417 default:
418 return -EINVAL;
419 }
420
421 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
422 case SND_SOC_DAIFMT_I2S:
423 af |= 0x2;
424 break;
425 case SND_SOC_DAIFMT_RIGHT_J:
426 break;
427 case SND_SOC_DAIFMT_LEFT_J:
428 af |= 0x1;
429 break;
430 case SND_SOC_DAIFMT_DSP_A:
431 af |= 0x3;
432 break;
433 case SND_SOC_DAIFMT_DSP_B:
434 af |= 0x13;
435 break;
436 default:
437 return -EINVAL;
438 }
439
440 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
441 case SND_SOC_DAIFMT_NB_NF:
442 break;
443 case SND_SOC_DAIFMT_NB_IF:
444 af |= WM8737_LRP;
445 break;
446 default:
447 return -EINVAL;
448 }
449
450 snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT,
451 WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af);
452
453 return 0;
454}
455
456static int wm8737_set_bias_level(struct snd_soc_codec *codec,
457 enum snd_soc_bias_level level)
458{
459 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
460 int ret;
461
462 switch (level) {
463 case SND_SOC_BIAS_ON:
464 break;
465
466 case SND_SOC_BIAS_PREPARE:
467 /* VMID at 2*75k */
468 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
469 WM8737_VMIDSEL_MASK, 0);
470 break;
471
472 case SND_SOC_BIAS_STANDBY:
473 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
474 ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
475 wm8737->supplies);
476 if (ret != 0) {
477 dev_err(codec->dev,
478 "Failed to enable supplies: %d\n",
479 ret);
480 return ret;
481 }
482
483 snd_soc_cache_sync(codec);
484
485 /* Fast VMID ramp at 2*2.5k */
486 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
487 WM8737_VMIDSEL_MASK, 0x4);
488
489 /* Bring VMID up */
490 snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
491 WM8737_VMID_MASK |
492 WM8737_VREF_MASK,
493 WM8737_VMID_MASK |
494 WM8737_VREF_MASK);
495
496 msleep(500);
497 }
498
499 /* VMID at 2*300k */
500 snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL,
501 WM8737_VMIDSEL_MASK, 2);
502
503 break;
504
505 case SND_SOC_BIAS_OFF:
506 snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT,
507 WM8737_VMID_MASK | WM8737_VREF_MASK, 0);
508
509 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies),
510 wm8737->supplies);
511 break;
512 }
513
514 codec->dapm.bias_level = level;
515 return 0;
516}
517
518#define WM8737_RATES SNDRV_PCM_RATE_8000_96000
519
520#define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
521 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
522
523static struct snd_soc_dai_ops wm8737_dai_ops = {
524 .hw_params = wm8737_hw_params,
525 .set_sysclk = wm8737_set_dai_sysclk,
526 .set_fmt = wm8737_set_dai_fmt,
527};
528
529static struct snd_soc_dai_driver wm8737_dai = {
530 .name = "wm8737",
531 .capture = {
532 .stream_name = "Capture",
533 .channels_min = 2, /* Mono modes not yet supported */
534 .channels_max = 2,
535 .rates = WM8737_RATES,
536 .formats = WM8737_FORMATS,
537 },
538 .ops = &wm8737_dai_ops,
539};
540
541#ifdef CONFIG_PM
542static int wm8737_suspend(struct snd_soc_codec *codec, pm_message_t state)
543{
544 wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
545 return 0;
546}
547
548static int wm8737_resume(struct snd_soc_codec *codec)
549{
550 wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
551 return 0;
552}
553#else
554#define wm8737_suspend NULL
555#define wm8737_resume NULL
556#endif
557
558static int wm8737_probe(struct snd_soc_codec *codec)
559{
560 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
561 int ret, i;
562
563 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type);
564 if (ret != 0) {
565 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
566 return ret;
567 }
568
569 for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++)
570 wm8737->supplies[i].supply = wm8737_supply_names[i];
571
572 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies),
573 wm8737->supplies);
574 if (ret != 0) {
575 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
576 return ret;
577 }
578
579 ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies),
580 wm8737->supplies);
581 if (ret != 0) {
582 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
583 goto err_get;
584 }
585
586 ret = wm8737_reset(codec);
587 if (ret < 0) {
588 dev_err(codec->dev, "Failed to issue reset\n");
589 goto err_enable;
590 }
591
592 snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU,
593 WM8737_LVU);
594 snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU,
595 WM8737_RVU);
596
597 wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
598
599 /* Bias level configuration will have done an extra enable */
600 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
601
602 snd_soc_add_controls(codec, wm8737_snd_controls,
603 ARRAY_SIZE(wm8737_snd_controls));
604 wm8737_add_widgets(codec);
605
606 return 0;
607
608err_enable:
609 regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
610err_get:
611 regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
612
613 return ret;
614}
615
616static int wm8737_remove(struct snd_soc_codec *codec)
617{
618 struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec);
619
620 wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF);
621 regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies);
622 return 0;
623}
624
625static struct snd_soc_codec_driver soc_codec_dev_wm8737 = {
626 .probe = wm8737_probe,
627 .remove = wm8737_remove,
628 .suspend = wm8737_suspend,
629 .resume = wm8737_resume,
630 .set_bias_level = wm8737_set_bias_level,
631
632 .reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */
633 .reg_word_size = sizeof(u16),
634 .reg_cache_default = wm8737_reg,
635};
636
637#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
638static __devinit int wm8737_i2c_probe(struct i2c_client *i2c,
639 const struct i2c_device_id *id)
640{
641 struct wm8737_priv *wm8737;
642 int ret;
643
644 wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
645 if (wm8737 == NULL)
646 return -ENOMEM;
647
648 i2c_set_clientdata(i2c, wm8737);
649 wm8737->control_type = SND_SOC_I2C;
650
651 ret = snd_soc_register_codec(&i2c->dev,
652 &soc_codec_dev_wm8737, &wm8737_dai, 1);
653 if (ret < 0)
654 kfree(wm8737);
655 return ret;
656
657}
658
659static __devexit int wm8737_i2c_remove(struct i2c_client *client)
660{
661 snd_soc_unregister_codec(&client->dev);
662 kfree(i2c_get_clientdata(client));
663 return 0;
664}
665
666static const struct i2c_device_id wm8737_i2c_id[] = {
667 { "wm8737", 0 },
668 { }
669};
670MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id);
671
672static struct i2c_driver wm8737_i2c_driver = {
673 .driver = {
674 .name = "wm8737",
675 .owner = THIS_MODULE,
676 },
677 .probe = wm8737_i2c_probe,
678 .remove = __devexit_p(wm8737_i2c_remove),
679 .id_table = wm8737_i2c_id,
680};
681#endif
682
683#if defined(CONFIG_SPI_MASTER)
684static int __devinit wm8737_spi_probe(struct spi_device *spi)
685{
686 struct wm8737_priv *wm8737;
687 int ret;
688
689 wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL);
690 if (wm8737 == NULL)
691 return -ENOMEM;
692
693 wm8737->control_type = SND_SOC_SPI;
694 spi_set_drvdata(spi, wm8737);
695
696 ret = snd_soc_register_codec(&spi->dev,
697 &soc_codec_dev_wm8737, &wm8737_dai, 1);
698 if (ret < 0)
699 kfree(wm8737);
700 return ret;
701}
702
703static int __devexit wm8737_spi_remove(struct spi_device *spi)
704{
705 snd_soc_unregister_codec(&spi->dev);
706 kfree(spi_get_drvdata(spi));
707 return 0;
708}
709
710static struct spi_driver wm8737_spi_driver = {
711 .driver = {
712 .name = "wm8737",
713 .owner = THIS_MODULE,
714 },
715 .probe = wm8737_spi_probe,
716 .remove = __devexit_p(wm8737_spi_remove),
717};
718#endif /* CONFIG_SPI_MASTER */
719
720static int __init wm8737_modinit(void)
721{
722 int ret;
723#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
724 ret = i2c_add_driver(&wm8737_i2c_driver);
725 if (ret != 0) {
726 printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n",
727 ret);
728 }
729#endif
730#if defined(CONFIG_SPI_MASTER)
731 ret = spi_register_driver(&wm8737_spi_driver);
732 if (ret != 0) {
733 printk(KERN_ERR "Failed to register WM8737 SPI driver: %d\n",
734 ret);
735 }
736#endif
737 return 0;
738}
739module_init(wm8737_modinit);
740
741static void __exit wm8737_exit(void)
742{
743#if defined(CONFIG_SPI_MASTER)
744 spi_unregister_driver(&wm8737_spi_driver);
745#endif
746#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
747 i2c_del_driver(&wm8737_i2c_driver);
748#endif
749}
750module_exit(wm8737_exit);
751
752MODULE_DESCRIPTION("ASoC WM8737 driver");
753MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
754MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8737.h b/sound/soc/codecs/wm8737.h
new file mode 100644
index 000000000000..23d14c8ff6e7
--- /dev/null
+++ b/sound/soc/codecs/wm8737.h
@@ -0,0 +1,322 @@
1#ifndef _WM8737_H
2#define _WM8737_H
3
4/*
5 * wm8737.c -- WM8523 ALSA SoC Audio driver
6 *
7 * Copyright 2010 Wolfson Microelectronics plc
8 *
9 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
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/*
17 * Register values.
18 */
19#define WM8737_LEFT_PGA_VOLUME 0x00
20#define WM8737_RIGHT_PGA_VOLUME 0x01
21#define WM8737_AUDIO_PATH_L 0x02
22#define WM8737_AUDIO_PATH_R 0x03
23#define WM8737_3D_ENHANCE 0x04
24#define WM8737_ADC_CONTROL 0x05
25#define WM8737_POWER_MANAGEMENT 0x06
26#define WM8737_AUDIO_FORMAT 0x07
27#define WM8737_CLOCKING 0x08
28#define WM8737_MIC_PREAMP_CONTROL 0x09
29#define WM8737_MISC_BIAS_CONTROL 0x0A
30#define WM8737_NOISE_GATE 0x0B
31#define WM8737_ALC1 0x0C
32#define WM8737_ALC2 0x0D
33#define WM8737_ALC3 0x0E
34#define WM8737_RESET 0x0F
35
36#define WM8737_REGISTER_COUNT 16
37#define WM8737_MAX_REGISTER 0x0F
38
39/*
40 * Field Definitions.
41 */
42
43/*
44 * R0 (0x00) - Left PGA volume
45 */
46#define WM8737_LVU 0x0100 /* LVU */
47#define WM8737_LVU_MASK 0x0100 /* LVU */
48#define WM8737_LVU_SHIFT 8 /* LVU */
49#define WM8737_LVU_WIDTH 1 /* LVU */
50#define WM8737_LINVOL_MASK 0x00FF /* LINVOL - [7:0] */
51#define WM8737_LINVOL_SHIFT 0 /* LINVOL - [7:0] */
52#define WM8737_LINVOL_WIDTH 8 /* LINVOL - [7:0] */
53
54/*
55 * R1 (0x01) - Right PGA volume
56 */
57#define WM8737_RVU 0x0100 /* RVU */
58#define WM8737_RVU_MASK 0x0100 /* RVU */
59#define WM8737_RVU_SHIFT 8 /* RVU */
60#define WM8737_RVU_WIDTH 1 /* RVU */
61#define WM8737_RINVOL_MASK 0x00FF /* RINVOL - [7:0] */
62#define WM8737_RINVOL_SHIFT 0 /* RINVOL - [7:0] */
63#define WM8737_RINVOL_WIDTH 8 /* RINVOL - [7:0] */
64
65/*
66 * R2 (0x02) - AUDIO path L
67 */
68#define WM8737_LINSEL_MASK 0x0180 /* LINSEL - [8:7] */
69#define WM8737_LINSEL_SHIFT 7 /* LINSEL - [8:7] */
70#define WM8737_LINSEL_WIDTH 2 /* LINSEL - [8:7] */
71#define WM8737_LMICBOOST_MASK 0x0060 /* LMICBOOST - [6:5] */
72#define WM8737_LMICBOOST_SHIFT 5 /* LMICBOOST - [6:5] */
73#define WM8737_LMICBOOST_WIDTH 2 /* LMICBOOST - [6:5] */
74#define WM8737_LMBE 0x0010 /* LMBE */
75#define WM8737_LMBE_MASK 0x0010 /* LMBE */
76#define WM8737_LMBE_SHIFT 4 /* LMBE */
77#define WM8737_LMBE_WIDTH 1 /* LMBE */
78#define WM8737_LMZC 0x0008 /* LMZC */
79#define WM8737_LMZC_MASK 0x0008 /* LMZC */
80#define WM8737_LMZC_SHIFT 3 /* LMZC */
81#define WM8737_LMZC_WIDTH 1 /* LMZC */
82#define WM8737_LPZC 0x0004 /* LPZC */
83#define WM8737_LPZC_MASK 0x0004 /* LPZC */
84#define WM8737_LPZC_SHIFT 2 /* LPZC */
85#define WM8737_LPZC_WIDTH 1 /* LPZC */
86#define WM8737_LZCTO_MASK 0x0003 /* LZCTO - [1:0] */
87#define WM8737_LZCTO_SHIFT 0 /* LZCTO - [1:0] */
88#define WM8737_LZCTO_WIDTH 2 /* LZCTO - [1:0] */
89
90/*
91 * R3 (0x03) - AUDIO path R
92 */
93#define WM8737_RINSEL_MASK 0x0180 /* RINSEL - [8:7] */
94#define WM8737_RINSEL_SHIFT 7 /* RINSEL - [8:7] */
95#define WM8737_RINSEL_WIDTH 2 /* RINSEL - [8:7] */
96#define WM8737_RMICBOOST_MASK 0x0060 /* RMICBOOST - [6:5] */
97#define WM8737_RMICBOOST_SHIFT 5 /* RMICBOOST - [6:5] */
98#define WM8737_RMICBOOST_WIDTH 2 /* RMICBOOST - [6:5] */
99#define WM8737_RMBE 0x0010 /* RMBE */
100#define WM8737_RMBE_MASK 0x0010 /* RMBE */
101#define WM8737_RMBE_SHIFT 4 /* RMBE */
102#define WM8737_RMBE_WIDTH 1 /* RMBE */
103#define WM8737_RMZC 0x0008 /* RMZC */
104#define WM8737_RMZC_MASK 0x0008 /* RMZC */
105#define WM8737_RMZC_SHIFT 3 /* RMZC */
106#define WM8737_RMZC_WIDTH 1 /* RMZC */
107#define WM8737_RPZC 0x0004 /* RPZC */
108#define WM8737_RPZC_MASK 0x0004 /* RPZC */
109#define WM8737_RPZC_SHIFT 2 /* RPZC */
110#define WM8737_RPZC_WIDTH 1 /* RPZC */
111#define WM8737_RZCTO_MASK 0x0003 /* RZCTO - [1:0] */
112#define WM8737_RZCTO_SHIFT 0 /* RZCTO - [1:0] */
113#define WM8737_RZCTO_WIDTH 2 /* RZCTO - [1:0] */
114
115/*
116 * R4 (0x04) - 3D Enhance
117 */
118#define WM8737_DIV2 0x0080 /* DIV2 */
119#define WM8737_DIV2_MASK 0x0080 /* DIV2 */
120#define WM8737_DIV2_SHIFT 7 /* DIV2 */
121#define WM8737_DIV2_WIDTH 1 /* DIV2 */
122#define WM8737_3DLC 0x0040 /* 3DLC */
123#define WM8737_3DLC_MASK 0x0040 /* 3DLC */
124#define WM8737_3DLC_SHIFT 6 /* 3DLC */
125#define WM8737_3DLC_WIDTH 1 /* 3DLC */
126#define WM8737_3DUC 0x0020 /* 3DUC */
127#define WM8737_3DUC_MASK 0x0020 /* 3DUC */
128#define WM8737_3DUC_SHIFT 5 /* 3DUC */
129#define WM8737_3DUC_WIDTH 1 /* 3DUC */
130#define WM8737_3DDEPTH_MASK 0x001E /* 3DDEPTH - [4:1] */
131#define WM8737_3DDEPTH_SHIFT 1 /* 3DDEPTH - [4:1] */
132#define WM8737_3DDEPTH_WIDTH 4 /* 3DDEPTH - [4:1] */
133#define WM8737_3DE 0x0001 /* 3DE */
134#define WM8737_3DE_MASK 0x0001 /* 3DE */
135#define WM8737_3DE_SHIFT 0 /* 3DE */
136#define WM8737_3DE_WIDTH 1 /* 3DE */
137
138/*
139 * R5 (0x05) - ADC Control
140 */
141#define WM8737_MONOMIX_MASK 0x0180 /* MONOMIX - [8:7] */
142#define WM8737_MONOMIX_SHIFT 7 /* MONOMIX - [8:7] */
143#define WM8737_MONOMIX_WIDTH 2 /* MONOMIX - [8:7] */
144#define WM8737_POLARITY_MASK 0x0060 /* POLARITY - [6:5] */
145#define WM8737_POLARITY_SHIFT 5 /* POLARITY - [6:5] */
146#define WM8737_POLARITY_WIDTH 2 /* POLARITY - [6:5] */
147#define WM8737_HPOR 0x0010 /* HPOR */
148#define WM8737_HPOR_MASK 0x0010 /* HPOR */
149#define WM8737_HPOR_SHIFT 4 /* HPOR */
150#define WM8737_HPOR_WIDTH 1 /* HPOR */
151#define WM8737_LP 0x0004 /* LP */
152#define WM8737_LP_MASK 0x0004 /* LP */
153#define WM8737_LP_SHIFT 2 /* LP */
154#define WM8737_LP_WIDTH 1 /* LP */
155#define WM8737_MONOUT 0x0002 /* MONOUT */
156#define WM8737_MONOUT_MASK 0x0002 /* MONOUT */
157#define WM8737_MONOUT_SHIFT 1 /* MONOUT */
158#define WM8737_MONOUT_WIDTH 1 /* MONOUT */
159#define WM8737_ADCHPD 0x0001 /* ADCHPD */
160#define WM8737_ADCHPD_MASK 0x0001 /* ADCHPD */
161#define WM8737_ADCHPD_SHIFT 0 /* ADCHPD */
162#define WM8737_ADCHPD_WIDTH 1 /* ADCHPD */
163
164/*
165 * R6 (0x06) - Power Management
166 */
167#define WM8737_VMID 0x0100 /* VMID */
168#define WM8737_VMID_MASK 0x0100 /* VMID */
169#define WM8737_VMID_SHIFT 8 /* VMID */
170#define WM8737_VMID_WIDTH 1 /* VMID */
171#define WM8737_VREF 0x0080 /* VREF */
172#define WM8737_VREF_MASK 0x0080 /* VREF */
173#define WM8737_VREF_SHIFT 7 /* VREF */
174#define WM8737_VREF_WIDTH 1 /* VREF */
175#define WM8737_AI 0x0040 /* AI */
176#define WM8737_AI_MASK 0x0040 /* AI */
177#define WM8737_AI_SHIFT 6 /* AI */
178#define WM8737_AI_WIDTH 1 /* AI */
179#define WM8737_PGL 0x0020 /* PGL */
180#define WM8737_PGL_MASK 0x0020 /* PGL */
181#define WM8737_PGL_SHIFT 5 /* PGL */
182#define WM8737_PGL_WIDTH 1 /* PGL */
183#define WM8737_PGR 0x0010 /* PGR */
184#define WM8737_PGR_MASK 0x0010 /* PGR */
185#define WM8737_PGR_SHIFT 4 /* PGR */
186#define WM8737_PGR_WIDTH 1 /* PGR */
187#define WM8737_ADL 0x0008 /* ADL */
188#define WM8737_ADL_MASK 0x0008 /* ADL */
189#define WM8737_ADL_SHIFT 3 /* ADL */
190#define WM8737_ADL_WIDTH 1 /* ADL */
191#define WM8737_ADR 0x0004 /* ADR */
192#define WM8737_ADR_MASK 0x0004 /* ADR */
193#define WM8737_ADR_SHIFT 2 /* ADR */
194#define WM8737_ADR_WIDTH 1 /* ADR */
195#define WM8737_MICBIAS_MASK 0x0003 /* MICBIAS - [1:0] */
196#define WM8737_MICBIAS_SHIFT 0 /* MICBIAS - [1:0] */
197#define WM8737_MICBIAS_WIDTH 2 /* MICBIAS - [1:0] */
198
199/*
200 * R7 (0x07) - Audio Format
201 */
202#define WM8737_SDODIS 0x0080 /* SDODIS */
203#define WM8737_SDODIS_MASK 0x0080 /* SDODIS */
204#define WM8737_SDODIS_SHIFT 7 /* SDODIS */
205#define WM8737_SDODIS_WIDTH 1 /* SDODIS */
206#define WM8737_MS 0x0040 /* MS */
207#define WM8737_MS_MASK 0x0040 /* MS */
208#define WM8737_MS_SHIFT 6 /* MS */
209#define WM8737_MS_WIDTH 1 /* MS */
210#define WM8737_LRP 0x0010 /* LRP */
211#define WM8737_LRP_MASK 0x0010 /* LRP */
212#define WM8737_LRP_SHIFT 4 /* LRP */
213#define WM8737_LRP_WIDTH 1 /* LRP */
214#define WM8737_WL_MASK 0x000C /* WL - [3:2] */
215#define WM8737_WL_SHIFT 2 /* WL - [3:2] */
216#define WM8737_WL_WIDTH 2 /* WL - [3:2] */
217#define WM8737_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */
218#define WM8737_FORMAT_SHIFT 0 /* FORMAT - [1:0] */
219#define WM8737_FORMAT_WIDTH 2 /* FORMAT - [1:0] */
220
221/*
222 * R8 (0x08) - Clocking
223 */
224#define WM8737_AUTODETECT 0x0080 /* AUTODETECT */
225#define WM8737_AUTODETECT_MASK 0x0080 /* AUTODETECT */
226#define WM8737_AUTODETECT_SHIFT 7 /* AUTODETECT */
227#define WM8737_AUTODETECT_WIDTH 1 /* AUTODETECT */
228#define WM8737_CLKDIV2 0x0040 /* CLKDIV2 */
229#define WM8737_CLKDIV2_MASK 0x0040 /* CLKDIV2 */
230#define WM8737_CLKDIV2_SHIFT 6 /* CLKDIV2 */
231#define WM8737_CLKDIV2_WIDTH 1 /* CLKDIV2 */
232#define WM8737_SR_MASK 0x003E /* SR - [5:1] */
233#define WM8737_SR_SHIFT 1 /* SR - [5:1] */
234#define WM8737_SR_WIDTH 5 /* SR - [5:1] */
235#define WM8737_USB_MODE 0x0001 /* USB MODE */
236#define WM8737_USB_MODE_MASK 0x0001 /* USB MODE */
237#define WM8737_USB_MODE_SHIFT 0 /* USB MODE */
238#define WM8737_USB_MODE_WIDTH 1 /* USB MODE */
239
240/*
241 * R9 (0x09) - MIC Preamp Control
242 */
243#define WM8737_RBYPEN 0x0008 /* RBYPEN */
244#define WM8737_RBYPEN_MASK 0x0008 /* RBYPEN */
245#define WM8737_RBYPEN_SHIFT 3 /* RBYPEN */
246#define WM8737_RBYPEN_WIDTH 1 /* RBYPEN */
247#define WM8737_LBYPEN 0x0004 /* LBYPEN */
248#define WM8737_LBYPEN_MASK 0x0004 /* LBYPEN */
249#define WM8737_LBYPEN_SHIFT 2 /* LBYPEN */
250#define WM8737_LBYPEN_WIDTH 1 /* LBYPEN */
251#define WM8737_MBCTRL_MASK 0x0003 /* MBCTRL - [1:0] */
252#define WM8737_MBCTRL_SHIFT 0 /* MBCTRL - [1:0] */
253#define WM8737_MBCTRL_WIDTH 2 /* MBCTRL - [1:0] */
254
255/*
256 * R10 (0x0A) - Misc Bias Control
257 */
258#define WM8737_VMIDSEL_MASK 0x000C /* VMIDSEL - [3:2] */
259#define WM8737_VMIDSEL_SHIFT 2 /* VMIDSEL - [3:2] */
260#define WM8737_VMIDSEL_WIDTH 2 /* VMIDSEL - [3:2] */
261#define WM8737_LINPUT1_DC_BIAS_ENABLE 0x0002 /* LINPUT1 DC BIAS ENABLE */
262#define WM8737_LINPUT1_DC_BIAS_ENABLE_MASK 0x0002 /* LINPUT1 DC BIAS ENABLE */
263#define WM8737_LINPUT1_DC_BIAS_ENABLE_SHIFT 1 /* LINPUT1 DC BIAS ENABLE */
264#define WM8737_LINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* LINPUT1 DC BIAS ENABLE */
265#define WM8737_RINPUT1_DC_BIAS_ENABLE 0x0001 /* RINPUT1 DC BIAS ENABLE */
266#define WM8737_RINPUT1_DC_BIAS_ENABLE_MASK 0x0001 /* RINPUT1 DC BIAS ENABLE */
267#define WM8737_RINPUT1_DC_BIAS_ENABLE_SHIFT 0 /* RINPUT1 DC BIAS ENABLE */
268#define WM8737_RINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* RINPUT1 DC BIAS ENABLE */
269
270/*
271 * R11 (0x0B) - Noise Gate
272 */
273#define WM8737_NGTH_MASK 0x001C /* NGTH - [4:2] */
274#define WM8737_NGTH_SHIFT 2 /* NGTH - [4:2] */
275#define WM8737_NGTH_WIDTH 3 /* NGTH - [4:2] */
276#define WM8737_NGAT 0x0001 /* NGAT */
277#define WM8737_NGAT_MASK 0x0001 /* NGAT */
278#define WM8737_NGAT_SHIFT 0 /* NGAT */
279#define WM8737_NGAT_WIDTH 1 /* NGAT */
280
281/*
282 * R12 (0x0C) - ALC1
283 */
284#define WM8737_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */
285#define WM8737_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */
286#define WM8737_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */
287#define WM8737_MAX_GAIN_MASK 0x0070 /* MAX GAIN - [6:4] */
288#define WM8737_MAX_GAIN_SHIFT 4 /* MAX GAIN - [6:4] */
289#define WM8737_MAX_GAIN_WIDTH 3 /* MAX GAIN - [6:4] */
290#define WM8737_ALCL_MASK 0x000F /* ALCL - [3:0] */
291#define WM8737_ALCL_SHIFT 0 /* ALCL - [3:0] */
292#define WM8737_ALCL_WIDTH 4 /* ALCL - [3:0] */
293
294/*
295 * R13 (0x0D) - ALC2
296 */
297#define WM8737_ALCZCE 0x0010 /* ALCZCE */
298#define WM8737_ALCZCE_MASK 0x0010 /* ALCZCE */
299#define WM8737_ALCZCE_SHIFT 4 /* ALCZCE */
300#define WM8737_ALCZCE_WIDTH 1 /* ALCZCE */
301#define WM8737_HLD_MASK 0x000F /* HLD - [3:0] */
302#define WM8737_HLD_SHIFT 0 /* HLD - [3:0] */
303#define WM8737_HLD_WIDTH 4 /* HLD - [3:0] */
304
305/*
306 * R14 (0x0E) - ALC3
307 */
308#define WM8737_DCY_MASK 0x00F0 /* DCY - [7:4] */
309#define WM8737_DCY_SHIFT 4 /* DCY - [7:4] */
310#define WM8737_DCY_WIDTH 4 /* DCY - [7:4] */
311#define WM8737_ATK_MASK 0x000F /* ATK - [3:0] */
312#define WM8737_ATK_SHIFT 0 /* ATK - [3:0] */
313#define WM8737_ATK_WIDTH 4 /* ATK - [3:0] */
314
315/*
316 * R15 (0x0F) - Reset
317 */
318#define WM8737_RESET_MASK 0x01FF /* RESET - [8:0] */
319#define WM8737_RESET_SHIFT 0 /* RESET - [8:0] */
320#define WM8737_RESET_WIDTH 9 /* RESET - [8:0] */
321
322#endif
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index aea60ef8aba7..494f2d31d75b 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -24,7 +24,6 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30 29
@@ -94,10 +93,11 @@ static const struct snd_soc_dapm_route intercon[] = {
94 93
95static int wm8741_add_widgets(struct snd_soc_codec *codec) 94static int wm8741_add_widgets(struct snd_soc_codec *codec)
96{ 95{
97 snd_soc_dapm_new_controls(codec, wm8741_dapm_widgets, 96 struct snd_soc_dapm_context *dapm = &codec->dapm;
98 ARRAY_SIZE(wm8741_dapm_widgets));
99 97
100 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 98 snd_soc_dapm_new_controls(dapm, wm8741_dapm_widgets,
99 ARRAY_SIZE(wm8741_dapm_widgets));
100 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
101 101
102 return 0; 102 return 0;
103} 103}
@@ -455,7 +455,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8741 = {
455 .resume = wm8741_resume, 455 .resume = wm8741_resume,
456 .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults), 456 .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults),
457 .reg_word_size = sizeof(u16), 457 .reg_word_size = sizeof(u16),
458 .reg_cache_default = &wm8741_reg_defaults, 458 .reg_cache_default = wm8741_reg_defaults,
459}; 459};
460 460
461#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 461#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c
index 6c924cd2cfd4..38f38fddd190 100644
--- a/sound/soc/codecs/wm8750.c
+++ b/sound/soc/codecs/wm8750.c
@@ -25,7 +25,6 @@
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h> 28#include <sound/initval.h>
30 29
31#include "wm8750.h" 30#include "wm8750.h"
@@ -53,7 +52,6 @@ static const u16 wm8750_reg[] = {
53struct wm8750_priv { 52struct wm8750_priv {
54 unsigned int sysclk; 53 unsigned int sysclk;
55 enum snd_soc_control_type control_type; 54 enum snd_soc_control_type control_type;
56 u16 reg_cache[ARRAY_SIZE(wm8750_reg)];
57}; 55};
58 56
59#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) 57#define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0)
@@ -399,10 +397,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
399 397
400static int wm8750_add_widgets(struct snd_soc_codec *codec) 398static int wm8750_add_widgets(struct snd_soc_codec *codec)
401{ 399{
402 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, 400 struct snd_soc_dapm_context *dapm = &codec->dapm;
403 ARRAY_SIZE(wm8750_dapm_widgets));
404 401
405 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 402 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
403 ARRAY_SIZE(wm8750_dapm_widgets));
404 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
406 405
407 return 0; 406 return 0;
408} 407}
@@ -615,7 +614,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
615 case SND_SOC_BIAS_PREPARE: 614 case SND_SOC_BIAS_PREPARE:
616 break; 615 break;
617 case SND_SOC_BIAS_STANDBY: 616 case SND_SOC_BIAS_STANDBY:
618 if (codec->bias_level == SND_SOC_BIAS_OFF) { 617 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
619 /* Set VMID to 5k */ 618 /* Set VMID to 5k */
620 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); 619 snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1);
621 620
@@ -630,7 +629,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec,
630 snd_soc_write(codec, WM8750_PWR1, 0x0001); 629 snd_soc_write(codec, WM8750_PWR1, 0x0001);
631 break; 630 break;
632 } 631 }
633 codec->bias_level = level; 632 codec->dapm.bias_level = level;
634 return 0; 633 return 0;
635} 634}
636 635
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index 87caae59e939..79b02ae125c5 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -45,7 +45,6 @@
45#include <sound/pcm.h> 45#include <sound/pcm.h>
46#include <sound/pcm_params.h> 46#include <sound/pcm_params.h>
47#include <sound/soc.h> 47#include <sound/soc.h>
48#include <sound/soc-dapm.h>
49#include <sound/initval.h> 48#include <sound/initval.h>
50#include <sound/tlv.h> 49#include <sound/tlv.h>
51#include <asm/div64.h> 50#include <asm/div64.h>
@@ -623,10 +622,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
623 622
624static int wm8753_add_widgets(struct snd_soc_codec *codec) 623static int wm8753_add_widgets(struct snd_soc_codec *codec)
625{ 624{
626 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, 625 struct snd_soc_dapm_context *dapm = &codec->dapm;
627 ARRAY_SIZE(wm8753_dapm_widgets));
628 626
629 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 627 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
628 ARRAY_SIZE(wm8753_dapm_widgets));
629 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
630 630
631 return 0; 631 return 0;
632} 632}
@@ -1245,7 +1245,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec,
1245 snd_soc_write(codec, WM8753_PWR1, 0x0001); 1245 snd_soc_write(codec, WM8753_PWR1, 0x0001);
1246 break; 1246 break;
1247 } 1247 }
1248 codec->bias_level = level; 1248 codec->dapm.bias_level = level;
1249 return 0; 1249 return 0;
1250} 1250}
1251 1251
@@ -1435,9 +1435,11 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec,
1435 1435
1436static void wm8753_work(struct work_struct *work) 1436static void wm8753_work(struct work_struct *work)
1437{ 1437{
1438 struct snd_soc_codec *codec = 1438 struct snd_soc_dapm_context *dapm =
1439 container_of(work, struct snd_soc_codec, delayed_work.work); 1439 container_of(work, struct snd_soc_dapm_context,
1440 wm8753_set_bias_level(codec, codec->bias_level); 1440 delayed_work.work);
1441 struct snd_soc_codec *codec = dapm->codec;
1442 wm8753_set_bias_level(codec, dapm->bias_level);
1441} 1443}
1442 1444
1443static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state) 1445static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state)
@@ -1466,41 +1468,22 @@ static int wm8753_resume(struct snd_soc_codec *codec)
1466 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1468 wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1467 1469
1468 /* charge wm8753 caps */ 1470 /* charge wm8753 caps */
1469 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 1471 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
1470 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 1472 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1471 codec->bias_level = SND_SOC_BIAS_ON; 1473 codec->dapm.bias_level = SND_SOC_BIAS_ON;
1472 schedule_delayed_work(&codec->delayed_work, 1474 schedule_delayed_work(&codec->dapm.delayed_work,
1473 msecs_to_jiffies(caps_charge)); 1475 msecs_to_jiffies(caps_charge));
1474 } 1476 }
1475 1477
1476 return 0; 1478 return 0;
1477} 1479}
1478 1480
1479/*
1480 * This function forces any delayed work to be queued and run.
1481 */
1482static int run_delayed_work(struct delayed_work *dwork)
1483{
1484 int ret;
1485
1486 /* cancel any work waiting to be queued. */
1487 ret = cancel_delayed_work(dwork);
1488
1489 /* if there was any work waiting then we run it now and
1490 * wait for it's completion */
1491 if (ret) {
1492 schedule_delayed_work(dwork, 0);
1493 flush_scheduled_work();
1494 }
1495 return ret;
1496}
1497
1498static int wm8753_probe(struct snd_soc_codec *codec) 1481static int wm8753_probe(struct snd_soc_codec *codec)
1499{ 1482{
1500 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); 1483 struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec);
1501 int ret; 1484 int ret;
1502 1485
1503 INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); 1486 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work);
1504 1487
1505 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type); 1488 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type);
1506 if (ret < 0) { 1489 if (ret < 0) {
@@ -1519,7 +1502,7 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1519 1502
1520 /* charge output caps */ 1503 /* charge output caps */
1521 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); 1504 wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE);
1522 schedule_delayed_work(&codec->delayed_work, 1505 schedule_delayed_work(&codec->dapm.delayed_work,
1523 msecs_to_jiffies(caps_charge)); 1506 msecs_to_jiffies(caps_charge));
1524 1507
1525 /* set the update bits */ 1508 /* set the update bits */
@@ -1544,7 +1527,7 @@ static int wm8753_probe(struct snd_soc_codec *codec)
1544/* power down chip */ 1527/* power down chip */
1545static int wm8753_remove(struct snd_soc_codec *codec) 1528static int wm8753_remove(struct snd_soc_codec *codec)
1546{ 1529{
1547 run_delayed_work(&codec->delayed_work); 1530 flush_delayed_work_sync(&codec->dapm.delayed_work);
1548 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); 1531 wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF);
1549 1532
1550 return 0; 1533 return 0;
diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c
new file mode 100644
index 000000000000..19b92baa9e8c
--- /dev/null
+++ b/sound/soc/codecs/wm8770.c
@@ -0,0 +1,749 @@
1/*
2 * wm8770.c -- WM8770 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@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/spi/spi.h>
20#include <linux/regulator/consumer.h>
21#include <linux/slab.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/initval.h>
27#include <sound/tlv.h>
28
29#include "wm8770.h"
30
31#define WM8770_NUM_SUPPLIES 3
32static const char *wm8770_supply_names[WM8770_NUM_SUPPLIES] = {
33 "AVDD1",
34 "AVDD2",
35 "DVDD"
36};
37
38static const u16 wm8770_reg_defs[WM8770_CACHEREGNUM] = {
39 0x7f, 0x7f, 0x7f, 0x7f,
40 0x7f, 0x7f, 0x7f, 0x7f,
41 0x7f, 0xff, 0xff, 0xff,
42 0xff, 0xff, 0xff, 0xff,
43 0xff, 0xff, 0, 0x90, 0,
44 0, 0x22, 0x22, 0x3e,
45 0xc, 0xc, 0x100, 0x189,
46 0x189, 0x8770
47};
48
49struct wm8770_priv {
50 enum snd_soc_control_type control_type;
51 struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES];
52 struct notifier_block disable_nb[WM8770_NUM_SUPPLIES];
53 struct snd_soc_codec *codec;
54 int sysclk;
55};
56
57static int vout12supply_event(struct snd_soc_dapm_widget *w,
58 struct snd_kcontrol *kcontrol, int event);
59static int vout34supply_event(struct snd_soc_dapm_widget *w,
60 struct snd_kcontrol *kcontrol, int event);
61
62/*
63 * We can't use the same notifier block for more than one supply and
64 * there's no way I can see to get from a callback to the caller
65 * except container_of().
66 */
67#define WM8770_REGULATOR_EVENT(n) \
68static int wm8770_regulator_event_##n(struct notifier_block *nb, \
69 unsigned long event, void *data) \
70{ \
71 struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \
72 disable_nb[n]); \
73 if (event & REGULATOR_EVENT_DISABLE) { \
74 wm8770->codec->cache_sync = 1; \
75 } \
76 return 0; \
77}
78
79WM8770_REGULATOR_EVENT(0)
80WM8770_REGULATOR_EVENT(1)
81WM8770_REGULATOR_EVENT(2)
82
83static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 100, 0);
84static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -12750, 50, 1);
85static const DECLARE_TLV_DB_SCALE(dac_alg_tlv, -12700, 100, 1);
86
87static const char *dac_phase_text[][2] = {
88 { "DAC1 Normal", "DAC1 Inverted" },
89 { "DAC2 Normal", "DAC2 Inverted" },
90 { "DAC3 Normal", "DAC3 Inverted" },
91 { "DAC4 Normal", "DAC4 Inverted" },
92};
93
94static const struct soc_enum dac_phase[] = {
95 SOC_ENUM_DOUBLE(WM8770_DACPHASE, 0, 1, 2, dac_phase_text[0]),
96 SOC_ENUM_DOUBLE(WM8770_DACPHASE, 2, 3, 2, dac_phase_text[1]),
97 SOC_ENUM_DOUBLE(WM8770_DACPHASE, 4, 5, 2, dac_phase_text[2]),
98 SOC_ENUM_DOUBLE(WM8770_DACPHASE, 6, 7, 2, dac_phase_text[3]),
99};
100
101static const struct snd_kcontrol_new wm8770_snd_controls[] = {
102 /* global DAC playback controls */
103 SOC_SINGLE_TLV("DAC Playback Volume", WM8770_MSDIGVOL, 0, 255, 0,
104 dac_dig_tlv),
105 SOC_SINGLE("DAC Playback Switch", WM8770_DACMUTE, 4, 1, 1),
106 SOC_SINGLE("DAC Playback ZC Switch", WM8770_DACCTRL1, 0, 1, 0),
107
108 /* global VOUT playback controls */
109 SOC_SINGLE_TLV("VOUT Playback Volume", WM8770_MSALGVOL, 0, 127, 0,
110 dac_alg_tlv),
111 SOC_SINGLE("VOUT Playback ZC Switch", WM8770_MSALGVOL, 7, 1, 0),
112
113 /* VOUT1/2/3/4 specific controls */
114 SOC_DOUBLE_R_TLV("VOUT1 Playback Volume", WM8770_VOUT1LVOL,
115 WM8770_VOUT1RVOL, 0, 127, 0, dac_alg_tlv),
116 SOC_DOUBLE_R("VOUT1 Playback ZC Switch", WM8770_VOUT1LVOL,
117 WM8770_VOUT1RVOL, 7, 1, 0),
118 SOC_DOUBLE_R_TLV("VOUT2 Playback Volume", WM8770_VOUT2LVOL,
119 WM8770_VOUT2RVOL, 0, 127, 0, dac_alg_tlv),
120 SOC_DOUBLE_R("VOUT2 Playback ZC Switch", WM8770_VOUT2LVOL,
121 WM8770_VOUT2RVOL, 7, 1, 0),
122 SOC_DOUBLE_R_TLV("VOUT3 Playback Volume", WM8770_VOUT3LVOL,
123 WM8770_VOUT3RVOL, 0, 127, 0, dac_alg_tlv),
124 SOC_DOUBLE_R("VOUT3 Playback ZC Switch", WM8770_VOUT3LVOL,
125 WM8770_VOUT3RVOL, 7, 1, 0),
126 SOC_DOUBLE_R_TLV("VOUT4 Playback Volume", WM8770_VOUT4LVOL,
127 WM8770_VOUT4RVOL, 0, 127, 0, dac_alg_tlv),
128 SOC_DOUBLE_R("VOUT4 Playback ZC Switch", WM8770_VOUT4LVOL,
129 WM8770_VOUT4RVOL, 7, 1, 0),
130
131 /* DAC1/2/3/4 specific controls */
132 SOC_DOUBLE_R_TLV("DAC1 Playback Volume", WM8770_DAC1LVOL,
133 WM8770_DAC1RVOL, 0, 255, 0, dac_dig_tlv),
134 SOC_SINGLE("DAC1 Deemphasis Switch", WM8770_DACCTRL2, 0, 1, 0),
135 SOC_ENUM("DAC1 Phase", dac_phase[0]),
136 SOC_DOUBLE_R_TLV("DAC2 Playback Volume", WM8770_DAC2LVOL,
137 WM8770_DAC2RVOL, 0, 255, 0, dac_dig_tlv),
138 SOC_SINGLE("DAC2 Deemphasis Switch", WM8770_DACCTRL2, 1, 1, 0),
139 SOC_ENUM("DAC2 Phase", dac_phase[1]),
140 SOC_DOUBLE_R_TLV("DAC3 Playback Volume", WM8770_DAC3LVOL,
141 WM8770_DAC3RVOL, 0, 255, 0, dac_dig_tlv),
142 SOC_SINGLE("DAC3 Deemphasis Switch", WM8770_DACCTRL2, 2, 1, 0),
143 SOC_ENUM("DAC3 Phase", dac_phase[2]),
144 SOC_DOUBLE_R_TLV("DAC4 Playback Volume", WM8770_DAC4LVOL,
145 WM8770_DAC4RVOL, 0, 255, 0, dac_dig_tlv),
146 SOC_SINGLE("DAC4 Deemphasis Switch", WM8770_DACCTRL2, 3, 1, 0),
147 SOC_ENUM("DAC4 Phase", dac_phase[3]),
148
149 /* ADC specific controls */
150 SOC_DOUBLE_R_TLV("Capture Volume", WM8770_ADCLCTRL, WM8770_ADCRCTRL,
151 0, 31, 0, adc_tlv),
152 SOC_DOUBLE_R("Capture Switch", WM8770_ADCLCTRL, WM8770_ADCRCTRL,
153 5, 1, 1),
154
155 /* other controls */
156 SOC_SINGLE("ADC 128x Oversampling Switch", WM8770_MSTRCTRL, 3, 1, 0),
157 SOC_SINGLE("ADC Highpass Filter Switch", WM8770_IFACECTRL, 8, 1, 1)
158};
159
160static const char *ain_text[] = {
161 "AIN1", "AIN2", "AIN3", "AIN4",
162 "AIN5", "AIN6", "AIN7", "AIN8"
163};
164
165static const struct soc_enum ain_enum =
166 SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text);
167
168static const struct snd_kcontrol_new ain_mux =
169 SOC_DAPM_ENUM("Capture Mux", ain_enum);
170
171static const struct snd_kcontrol_new vout1_mix_controls[] = {
172 SOC_DAPM_SINGLE("DAC1 Switch", WM8770_OUTMUX1, 0, 1, 0),
173 SOC_DAPM_SINGLE("AUX1 Switch", WM8770_OUTMUX1, 1, 1, 0),
174 SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 2, 1, 0)
175};
176
177static const struct snd_kcontrol_new vout2_mix_controls[] = {
178 SOC_DAPM_SINGLE("DAC2 Switch", WM8770_OUTMUX1, 3, 1, 0),
179 SOC_DAPM_SINGLE("AUX2 Switch", WM8770_OUTMUX1, 4, 1, 0),
180 SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 5, 1, 0)
181};
182
183static const struct snd_kcontrol_new vout3_mix_controls[] = {
184 SOC_DAPM_SINGLE("DAC3 Switch", WM8770_OUTMUX2, 0, 1, 0),
185 SOC_DAPM_SINGLE("AUX3 Switch", WM8770_OUTMUX2, 1, 1, 0),
186 SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 2, 1, 0)
187};
188
189static const struct snd_kcontrol_new vout4_mix_controls[] = {
190 SOC_DAPM_SINGLE("DAC4 Switch", WM8770_OUTMUX2, 3, 1, 0),
191 SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 4, 1, 0)
192};
193
194static const struct snd_soc_dapm_widget wm8770_dapm_widgets[] = {
195 SND_SOC_DAPM_INPUT("AUX1"),
196 SND_SOC_DAPM_INPUT("AUX2"),
197 SND_SOC_DAPM_INPUT("AUX3"),
198
199 SND_SOC_DAPM_INPUT("AIN1"),
200 SND_SOC_DAPM_INPUT("AIN2"),
201 SND_SOC_DAPM_INPUT("AIN3"),
202 SND_SOC_DAPM_INPUT("AIN4"),
203 SND_SOC_DAPM_INPUT("AIN5"),
204 SND_SOC_DAPM_INPUT("AIN6"),
205 SND_SOC_DAPM_INPUT("AIN7"),
206 SND_SOC_DAPM_INPUT("AIN8"),
207
208 SND_SOC_DAPM_MUX("Capture Mux", WM8770_ADCMUX, 8, 1, &ain_mux),
209
210 SND_SOC_DAPM_ADC("ADC", "Capture", WM8770_PWDNCTRL, 1, 1),
211
212 SND_SOC_DAPM_DAC("DAC1", "Playback", WM8770_PWDNCTRL, 2, 1),
213 SND_SOC_DAPM_DAC("DAC2", "Playback", WM8770_PWDNCTRL, 3, 1),
214 SND_SOC_DAPM_DAC("DAC3", "Playback", WM8770_PWDNCTRL, 4, 1),
215 SND_SOC_DAPM_DAC("DAC4", "Playback", WM8770_PWDNCTRL, 5, 1),
216
217 SND_SOC_DAPM_SUPPLY("VOUT12 Supply", SND_SOC_NOPM, 0, 0,
218 vout12supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
219 SND_SOC_DAPM_SUPPLY("VOUT34 Supply", SND_SOC_NOPM, 0, 0,
220 vout34supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
221
222 SND_SOC_DAPM_MIXER("VOUT1 Mixer", SND_SOC_NOPM, 0, 0,
223 vout1_mix_controls, ARRAY_SIZE(vout1_mix_controls)),
224 SND_SOC_DAPM_MIXER("VOUT2 Mixer", SND_SOC_NOPM, 0, 0,
225 vout2_mix_controls, ARRAY_SIZE(vout2_mix_controls)),
226 SND_SOC_DAPM_MIXER("VOUT3 Mixer", SND_SOC_NOPM, 0, 0,
227 vout3_mix_controls, ARRAY_SIZE(vout3_mix_controls)),
228 SND_SOC_DAPM_MIXER("VOUT4 Mixer", SND_SOC_NOPM, 0, 0,
229 vout4_mix_controls, ARRAY_SIZE(vout4_mix_controls)),
230
231 SND_SOC_DAPM_OUTPUT("VOUT1"),
232 SND_SOC_DAPM_OUTPUT("VOUT2"),
233 SND_SOC_DAPM_OUTPUT("VOUT3"),
234 SND_SOC_DAPM_OUTPUT("VOUT4")
235};
236
237static const struct snd_soc_dapm_route wm8770_intercon[] = {
238 { "Capture Mux", "AIN1", "AIN1" },
239 { "Capture Mux", "AIN2", "AIN2" },
240 { "Capture Mux", "AIN3", "AIN3" },
241 { "Capture Mux", "AIN4", "AIN4" },
242 { "Capture Mux", "AIN5", "AIN5" },
243 { "Capture Mux", "AIN6", "AIN6" },
244 { "Capture Mux", "AIN7", "AIN7" },
245 { "Capture Mux", "AIN8", "AIN8" },
246
247 { "ADC", NULL, "Capture Mux" },
248
249 { "VOUT1 Mixer", NULL, "VOUT12 Supply" },
250 { "VOUT1 Mixer", "DAC1 Switch", "DAC1" },
251 { "VOUT1 Mixer", "AUX1 Switch", "AUX1" },
252 { "VOUT1 Mixer", "Bypass Switch", "Capture Mux" },
253
254 { "VOUT2 Mixer", NULL, "VOUT12 Supply" },
255 { "VOUT2 Mixer", "DAC2 Switch", "DAC2" },
256 { "VOUT2 Mixer", "AUX2 Switch", "AUX2" },
257 { "VOUT2 Mixer", "Bypass Switch", "Capture Mux" },
258
259 { "VOUT3 Mixer", NULL, "VOUT34 Supply" },
260 { "VOUT3 Mixer", "DAC3 Switch", "DAC3" },
261 { "VOUT3 Mixer", "AUX3 Switch", "AUX3" },
262 { "VOUT3 Mixer", "Bypass Switch", "Capture Mux" },
263
264 { "VOUT4 Mixer", NULL, "VOUT34 Supply" },
265 { "VOUT4 Mixer", "DAC4 Switch", "DAC4" },
266 { "VOUT4 Mixer", "Bypass Switch", "Capture Mux" },
267
268 { "VOUT1", NULL, "VOUT1 Mixer" },
269 { "VOUT2", NULL, "VOUT2 Mixer" },
270 { "VOUT3", NULL, "VOUT3 Mixer" },
271 { "VOUT4", NULL, "VOUT4 Mixer" }
272};
273
274static int vout12supply_event(struct snd_soc_dapm_widget *w,
275 struct snd_kcontrol *kcontrol, int event)
276{
277 struct snd_soc_codec *codec;
278
279 codec = w->codec;
280
281 switch (event) {
282 case SND_SOC_DAPM_PRE_PMU:
283 snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0);
284 break;
285 case SND_SOC_DAPM_POST_PMD:
286 snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0x180);
287 break;
288 }
289
290 return 0;
291}
292
293static int vout34supply_event(struct snd_soc_dapm_widget *w,
294 struct snd_kcontrol *kcontrol, int event)
295{
296 struct snd_soc_codec *codec;
297
298 codec = w->codec;
299
300 switch (event) {
301 case SND_SOC_DAPM_PRE_PMU:
302 snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0);
303 break;
304 case SND_SOC_DAPM_POST_PMD:
305 snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0x180);
306 break;
307 }
308
309 return 0;
310}
311
312static int wm8770_reset(struct snd_soc_codec *codec)
313{
314 return snd_soc_write(codec, WM8770_RESET, 0);
315}
316
317static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
318{
319 struct snd_soc_codec *codec;
320 int iface, master;
321
322 codec = dai->codec;
323
324 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
325 case SND_SOC_DAIFMT_CBM_CFM:
326 master = 0x100;
327 break;
328 case SND_SOC_DAIFMT_CBS_CFS:
329 master = 0;
330 break;
331 default:
332 return -EINVAL;
333 }
334
335 iface = 0;
336 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
337 case SND_SOC_DAIFMT_I2S:
338 iface |= 0x2;
339 break;
340 case SND_SOC_DAIFMT_RIGHT_J:
341 break;
342 case SND_SOC_DAIFMT_LEFT_J:
343 iface |= 0x1;
344 break;
345 default:
346 return -EINVAL;
347 }
348
349 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
350 case SND_SOC_DAIFMT_NB_NF:
351 break;
352 case SND_SOC_DAIFMT_IB_IF:
353 iface |= 0xc;
354 break;
355 case SND_SOC_DAIFMT_IB_NF:
356 iface |= 0x8;
357 break;
358 case SND_SOC_DAIFMT_NB_IF:
359 iface |= 0x4;
360 break;
361 default:
362 return -EINVAL;
363 }
364
365 snd_soc_update_bits(codec, WM8770_IFACECTRL, 0xf, iface);
366 snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x100, master);
367
368 return 0;
369}
370
371static const int mclk_ratios[] = {
372 128,
373 192,
374 256,
375 384,
376 512,
377 768
378};
379
380static int wm8770_hw_params(struct snd_pcm_substream *substream,
381 struct snd_pcm_hw_params *params,
382 struct snd_soc_dai *dai)
383{
384 struct snd_soc_codec *codec;
385 struct wm8770_priv *wm8770;
386 int i;
387 int iface;
388 int shift;
389 int ratio;
390
391 codec = dai->codec;
392 wm8770 = snd_soc_codec_get_drvdata(codec);
393
394 iface = 0;
395 switch (params_format(params)) {
396 case SNDRV_PCM_FORMAT_S16_LE:
397 break;
398 case SNDRV_PCM_FORMAT_S20_3LE:
399 iface |= 0x10;
400 break;
401 case SNDRV_PCM_FORMAT_S24_LE:
402 iface |= 0x20;
403 break;
404 case SNDRV_PCM_FORMAT_S32_LE:
405 iface |= 0x30;
406 break;
407 }
408
409 switch (substream->stream) {
410 case SNDRV_PCM_STREAM_PLAYBACK:
411 i = 0;
412 shift = 4;
413 break;
414 case SNDRV_PCM_STREAM_CAPTURE:
415 i = 2;
416 shift = 0;
417 break;
418 default:
419 return -EINVAL;
420 }
421
422 /* Only need to set MCLK/LRCLK ratio if we're master */
423 if (snd_soc_read(codec, WM8770_MSTRCTRL) & 0x100) {
424 for (; i < ARRAY_SIZE(mclk_ratios); ++i) {
425 ratio = wm8770->sysclk / params_rate(params);
426 if (ratio == mclk_ratios[i])
427 break;
428 }
429
430 if (i == ARRAY_SIZE(mclk_ratios)) {
431 dev_err(codec->dev,
432 "Unable to configure MCLK ratio %d/%d\n",
433 wm8770->sysclk, params_rate(params));
434 return -EINVAL;
435 }
436
437 dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]);
438
439 snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x7 << shift,
440 i << shift);
441 }
442
443 snd_soc_update_bits(codec, WM8770_IFACECTRL, 0x30, iface);
444
445 return 0;
446}
447
448static int wm8770_mute(struct snd_soc_dai *dai, int mute)
449{
450 struct snd_soc_codec *codec;
451
452 codec = dai->codec;
453 return snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10,
454 !!mute << 4);
455}
456
457static int wm8770_set_sysclk(struct snd_soc_dai *dai,
458 int clk_id, unsigned int freq, int dir)
459{
460 struct snd_soc_codec *codec;
461 struct wm8770_priv *wm8770;
462
463 codec = dai->codec;
464 wm8770 = snd_soc_codec_get_drvdata(codec);
465 wm8770->sysclk = freq;
466 return 0;
467}
468
469static void wm8770_sync_cache(struct snd_soc_codec *codec)
470{
471 int i;
472 u16 *cache;
473
474 if (!codec->cache_sync)
475 return;
476
477 codec->cache_only = 0;
478 cache = codec->reg_cache;
479 for (i = 0; i < codec->driver->reg_cache_size; i++) {
480 if (i == WM8770_RESET || cache[i] == wm8770_reg_defs[i])
481 continue;
482 snd_soc_write(codec, i, cache[i]);
483 }
484 codec->cache_sync = 0;
485}
486
487static int wm8770_set_bias_level(struct snd_soc_codec *codec,
488 enum snd_soc_bias_level level)
489{
490 int ret;
491 struct wm8770_priv *wm8770;
492
493 wm8770 = snd_soc_codec_get_drvdata(codec);
494
495 switch (level) {
496 case SND_SOC_BIAS_ON:
497 break;
498 case SND_SOC_BIAS_PREPARE:
499 break;
500 case SND_SOC_BIAS_STANDBY:
501 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
502 ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
503 wm8770->supplies);
504 if (ret) {
505 dev_err(codec->dev,
506 "Failed to enable supplies: %d\n",
507 ret);
508 return ret;
509 }
510 wm8770_sync_cache(codec);
511 /* global powerup */
512 snd_soc_write(codec, WM8770_PWDNCTRL, 0);
513 }
514 break;
515 case SND_SOC_BIAS_OFF:
516 /* global powerdown */
517 snd_soc_write(codec, WM8770_PWDNCTRL, 1);
518 regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies),
519 wm8770->supplies);
520 break;
521 }
522
523 codec->dapm.bias_level = level;
524 return 0;
525}
526
527#define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
528 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
529
530static struct snd_soc_dai_ops wm8770_dai_ops = {
531 .digital_mute = wm8770_mute,
532 .hw_params = wm8770_hw_params,
533 .set_fmt = wm8770_set_fmt,
534 .set_sysclk = wm8770_set_sysclk,
535};
536
537static struct snd_soc_dai_driver wm8770_dai = {
538 .name = "wm8770-hifi",
539 .playback = {
540 .stream_name = "Playback",
541 .channels_min = 2,
542 .channels_max = 2,
543 .rates = SNDRV_PCM_RATE_8000_192000,
544 .formats = WM8770_FORMATS
545 },
546 .capture = {
547 .stream_name = "Capture",
548 .channels_min = 2,
549 .channels_max = 2,
550 .rates = SNDRV_PCM_RATE_8000_96000,
551 .formats = WM8770_FORMATS
552 },
553 .ops = &wm8770_dai_ops,
554 .symmetric_rates = 1
555};
556
557#ifdef CONFIG_PM
558static int wm8770_suspend(struct snd_soc_codec *codec, pm_message_t state)
559{
560 wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
561 return 0;
562}
563
564static int wm8770_resume(struct snd_soc_codec *codec)
565{
566 wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
567 return 0;
568}
569#else
570#define wm8770_suspend NULL
571#define wm8770_resume NULL
572#endif
573
574static int wm8770_probe(struct snd_soc_codec *codec)
575{
576 struct wm8770_priv *wm8770;
577 int ret;
578 int i;
579
580 wm8770 = snd_soc_codec_get_drvdata(codec);
581 wm8770->codec = codec;
582
583 codec->dapm.idle_bias_off = 1;
584
585 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type);
586 if (ret < 0) {
587 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
588 return ret;
589 }
590
591 for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++)
592 wm8770->supplies[i].supply = wm8770_supply_names[i];
593
594 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies),
595 wm8770->supplies);
596 if (ret) {
597 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
598 return ret;
599 }
600
601 wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0;
602 wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1;
603 wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2;
604
605 /* This should really be moved into the regulator core */
606 for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) {
607 ret = regulator_register_notifier(wm8770->supplies[i].consumer,
608 &wm8770->disable_nb[i]);
609 if (ret) {
610 dev_err(codec->dev,
611 "Failed to register regulator notifier: %d\n",
612 ret);
613 }
614 }
615
616 ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies),
617 wm8770->supplies);
618 if (ret) {
619 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
620 goto err_reg_get;
621 }
622
623 ret = wm8770_reset(codec);
624 if (ret < 0) {
625 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
626 goto err_reg_enable;
627 }
628
629 wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
630
631 /* latch the volume update bits */
632 snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100);
633 snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100);
634 snd_soc_update_bits(codec, WM8770_VOUT1RVOL, 0x100, 0x100);
635 snd_soc_update_bits(codec, WM8770_VOUT2RVOL, 0x100, 0x100);
636 snd_soc_update_bits(codec, WM8770_VOUT3RVOL, 0x100, 0x100);
637 snd_soc_update_bits(codec, WM8770_VOUT4RVOL, 0x100, 0x100);
638 snd_soc_update_bits(codec, WM8770_DAC1RVOL, 0x100, 0x100);
639 snd_soc_update_bits(codec, WM8770_DAC2RVOL, 0x100, 0x100);
640 snd_soc_update_bits(codec, WM8770_DAC3RVOL, 0x100, 0x100);
641 snd_soc_update_bits(codec, WM8770_DAC4RVOL, 0x100, 0x100);
642
643 /* mute all DACs */
644 snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10);
645
646 snd_soc_add_controls(codec, wm8770_snd_controls,
647 ARRAY_SIZE(wm8770_snd_controls));
648 snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets,
649 ARRAY_SIZE(wm8770_dapm_widgets));
650 snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon,
651 ARRAY_SIZE(wm8770_intercon));
652 return 0;
653
654err_reg_enable:
655 regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
656err_reg_get:
657 regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
658 return ret;
659}
660
661static int wm8770_remove(struct snd_soc_codec *codec)
662{
663 struct wm8770_priv *wm8770;
664 int i;
665
666 wm8770 = snd_soc_codec_get_drvdata(codec);
667 wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF);
668
669 for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i)
670 regulator_unregister_notifier(wm8770->supplies[i].consumer,
671 &wm8770->disable_nb[i]);
672 regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies);
673 return 0;
674}
675
676static struct snd_soc_codec_driver soc_codec_dev_wm8770 = {
677 .probe = wm8770_probe,
678 .remove = wm8770_remove,
679 .suspend = wm8770_suspend,
680 .resume = wm8770_resume,
681 .set_bias_level = wm8770_set_bias_level,
682 .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs),
683 .reg_word_size = sizeof (u16),
684 .reg_cache_default = wm8770_reg_defs
685};
686
687#if defined(CONFIG_SPI_MASTER)
688static int __devinit wm8770_spi_probe(struct spi_device *spi)
689{
690 struct wm8770_priv *wm8770;
691 int ret;
692
693 wm8770 = kzalloc(sizeof(struct wm8770_priv), GFP_KERNEL);
694 if (!wm8770)
695 return -ENOMEM;
696
697 wm8770->control_type = SND_SOC_SPI;
698 spi_set_drvdata(spi, wm8770);
699
700 ret = snd_soc_register_codec(&spi->dev,
701 &soc_codec_dev_wm8770, &wm8770_dai, 1);
702 if (ret < 0)
703 kfree(wm8770);
704 return ret;
705}
706
707static int __devexit wm8770_spi_remove(struct spi_device *spi)
708{
709 snd_soc_unregister_codec(&spi->dev);
710 kfree(spi_get_drvdata(spi));
711 return 0;
712}
713
714static struct spi_driver wm8770_spi_driver = {
715 .driver = {
716 .name = "wm8770",
717 .owner = THIS_MODULE,
718 },
719 .probe = wm8770_spi_probe,
720 .remove = __devexit_p(wm8770_spi_remove)
721};
722#endif
723
724static int __init wm8770_modinit(void)
725{
726 int ret = 0;
727
728#if defined(CONFIG_SPI_MASTER)
729 ret = spi_register_driver(&wm8770_spi_driver);
730 if (ret) {
731 printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n",
732 ret);
733 }
734#endif
735 return ret;
736}
737module_init(wm8770_modinit);
738
739static void __exit wm8770_exit(void)
740{
741#if defined(CONFIG_SPI_MASTER)
742 spi_unregister_driver(&wm8770_spi_driver);
743#endif
744}
745module_exit(wm8770_exit);
746
747MODULE_DESCRIPTION("ASoC WM8770 driver");
748MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
749MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8770.h b/sound/soc/codecs/wm8770.h
new file mode 100644
index 000000000000..5f1b3bda6cc8
--- /dev/null
+++ b/sound/soc/codecs/wm8770.h
@@ -0,0 +1,51 @@
1/*
2 * wm8770.h -- WM8770 ASoC driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@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 _WM8770_H
14#define _WM8770_H
15
16/* Registers */
17#define WM8770_VOUT1LVOL 0
18#define WM8770_VOUT1RVOL 0x1
19#define WM8770_VOUT2LVOL 0x2
20#define WM8770_VOUT2RVOL 0x3
21#define WM8770_VOUT3LVOL 0x4
22#define WM8770_VOUT3RVOL 0x5
23#define WM8770_VOUT4LVOL 0x6
24#define WM8770_VOUT4RVOL 0x7
25#define WM8770_MSALGVOL 0x8
26#define WM8770_DAC1LVOL 0x9
27#define WM8770_DAC1RVOL 0xa
28#define WM8770_DAC2LVOL 0xb
29#define WM8770_DAC2RVOL 0xc
30#define WM8770_DAC3LVOL 0xd
31#define WM8770_DAC3RVOL 0xe
32#define WM8770_DAC4LVOL 0xf
33#define WM8770_DAC4RVOL 0x10
34#define WM8770_MSDIGVOL 0x11
35#define WM8770_DACPHASE 0x12
36#define WM8770_DACCTRL1 0x13
37#define WM8770_DACMUTE 0x14
38#define WM8770_DACCTRL2 0x15
39#define WM8770_IFACECTRL 0x16
40#define WM8770_MSTRCTRL 0x17
41#define WM8770_PWDNCTRL 0x18
42#define WM8770_ADCLCTRL 0x19
43#define WM8770_ADCRCTRL 0x1a
44#define WM8770_ADCMUX 0x1b
45#define WM8770_OUTMUX1 0x1c
46#define WM8770_OUTMUX2 0x1d
47#define WM8770_RESET 0x31
48
49#define WM8770_CACHEREGNUM 0x20
50
51#endif
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index 0132a27140ae..8e7953b1b790 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -25,7 +25,6 @@
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h> 28#include <sound/initval.h>
30#include <sound/tlv.h> 29#include <sound/tlv.h>
31 30
@@ -306,7 +305,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
306 case SND_SOC_BIAS_PREPARE: 305 case SND_SOC_BIAS_PREPARE:
307 break; 306 break;
308 case SND_SOC_BIAS_STANDBY: 307 case SND_SOC_BIAS_STANDBY:
309 if (codec->bias_level == SND_SOC_BIAS_OFF) { 308 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
310 /* Disable the global powerdown; DAPM does the rest */ 309 /* Disable the global powerdown; DAPM does the rest */
311 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); 310 snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0);
312 } 311 }
@@ -317,7 +316,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec,
317 break; 316 break;
318 } 317 }
319 318
320 codec->bias_level = level; 319 codec->dapm.bias_level = level;
321 return 0; 320 return 0;
322} 321}
323 322
@@ -404,6 +403,7 @@ static int wm8776_resume(struct snd_soc_codec *codec)
404static int wm8776_probe(struct snd_soc_codec *codec) 403static int wm8776_probe(struct snd_soc_codec *codec)
405{ 404{
406 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec); 405 struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec);
406 struct snd_soc_dapm_context *dapm = &codec->dapm;
407 int ret = 0; 407 int ret = 0;
408 408
409 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type); 409 ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type);
@@ -427,9 +427,9 @@ static int wm8776_probe(struct snd_soc_codec *codec)
427 427
428 snd_soc_add_controls(codec, wm8776_snd_controls, 428 snd_soc_add_controls(codec, wm8776_snd_controls,
429 ARRAY_SIZE(wm8776_snd_controls)); 429 ARRAY_SIZE(wm8776_snd_controls));
430 snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets, 430 snd_soc_dapm_new_controls(dapm, wm8776_dapm_widgets,
431 ARRAY_SIZE(wm8776_dapm_widgets)); 431 ARRAY_SIZE(wm8776_dapm_widgets));
432 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); 432 snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
433 433
434 return ret; 434 return ret;
435} 435}
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 4599e8e95aa2..6dae1b40c9f7 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -23,7 +23,6 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29 28
@@ -515,7 +514,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
515 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); 514 snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0);
516 break; 515 break;
517 case SND_SOC_BIAS_STANDBY: 516 case SND_SOC_BIAS_STANDBY:
518 if (codec->bias_level == SND_SOC_BIAS_OFF) { 517 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
519 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies), 518 ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies),
520 wm8804->supplies); 519 wm8804->supplies);
521 if (ret) { 520 if (ret) {
@@ -537,7 +536,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec,
537 break; 536 break;
538 } 537 }
539 538
540 codec->bias_level = level; 539 codec->dapm.bias_level = level;
541 return 0; 540 return 0;
542} 541}
543 542
@@ -581,7 +580,7 @@ static int wm8804_probe(struct snd_soc_codec *codec)
581 wm8804 = snd_soc_codec_get_drvdata(codec); 580 wm8804 = snd_soc_codec_get_drvdata(codec);
582 wm8804->codec = codec; 581 wm8804->codec = codec;
583 582
584 codec->idle_bias_off = 1; 583 codec->dapm.idle_bias_off = 1;
585 584
586 ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type); 585 ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type);
587 if (ret < 0) { 586 if (ret < 0) {
diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c
index aca4b1ea10bb..cd0959926d12 100644
--- a/sound/soc/codecs/wm8900.c
+++ b/sound/soc/codecs/wm8900.c
@@ -30,7 +30,6 @@
30#include <sound/pcm.h> 30#include <sound/pcm.h>
31#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34#include <sound/initval.h> 33#include <sound/initval.h>
35#include <sound/tlv.h> 34#include <sound/tlv.h>
36 35
@@ -140,7 +139,6 @@
140 139
141struct wm8900_priv { 140struct wm8900_priv {
142 enum snd_soc_control_type control_type; 141 enum snd_soc_control_type control_type;
143 u16 reg_cache[WM8900_MAXREG];
144 142
145 u32 fll_in; /* FLL input frequency */ 143 u32 fll_in; /* FLL input frequency */
146 u32 fll_out; /* FLL output frequency */ 144 u32 fll_out; /* FLL output frequency */
@@ -611,10 +609,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
611 609
612static int wm8900_add_widgets(struct snd_soc_codec *codec) 610static int wm8900_add_widgets(struct snd_soc_codec *codec)
613{ 611{
614 snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets, 612 struct snd_soc_dapm_context *dapm = &codec->dapm;
615 ARRAY_SIZE(wm8900_dapm_widgets));
616 613
617 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 614 snd_soc_dapm_new_controls(dapm, wm8900_dapm_widgets,
615 ARRAY_SIZE(wm8900_dapm_widgets));
616 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
618 617
619 return 0; 618 return 0;
620} 619}
@@ -1051,7 +1050,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1051 1050
1052 case SND_SOC_BIAS_STANDBY: 1051 case SND_SOC_BIAS_STANDBY:
1053 /* Charge capacitors if initial power up */ 1052 /* Charge capacitors if initial power up */
1054 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1053 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1055 /* STARTUP_BIAS_ENA on */ 1054 /* STARTUP_BIAS_ENA on */
1056 snd_soc_write(codec, WM8900_REG_POWER1, 1055 snd_soc_write(codec, WM8900_REG_POWER1,
1057 WM8900_REG_POWER1_STARTUP_BIAS_ENA); 1056 WM8900_REG_POWER1_STARTUP_BIAS_ENA);
@@ -1119,7 +1118,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec,
1119 WM8900_REG_POWER2_SYSCLK_ENA); 1118 WM8900_REG_POWER2_SYSCLK_ENA);
1120 break; 1119 break;
1121 } 1120 }
1122 codec->bias_level = level; 1121 codec->dapm.bias_level = level;
1123 return 0; 1122 return 0;
1124} 1123}
1125 1124
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 622b60238a82..987476a5895f 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -29,9 +29,9 @@
29#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
30#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/initval.h> 32#include <sound/initval.h>
34#include <sound/wm8903.h> 33#include <sound/wm8903.h>
34#include <trace/events/asoc.h>
35 35
36#include "wm8903.h" 36#include "wm8903.h"
37 37
@@ -214,15 +214,14 @@ static u16 wm8903_reg_defaults[] = {
214 214
215struct wm8903_priv { 215struct wm8903_priv {
216 216
217 u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)];
218
219 int sysclk; 217 int sysclk;
220 int irq; 218 int irq;
221 219
222 /* Reference counts */ 220 int fs;
221 int deemph;
222
223 /* Reference count */
223 int class_w_users; 224 int class_w_users;
224 int playback_active;
225 int capture_active;
226 225
227 struct completion wseq; 226 struct completion wseq;
228 227
@@ -231,9 +230,6 @@ struct wm8903_priv {
231 int mic_short; 230 int mic_short;
232 int mic_last_report; 231 int mic_last_report;
233 int mic_delay; 232 int mic_delay;
234
235 struct snd_pcm_substream *master_substream;
236 struct snd_pcm_substream *slave_substream;
237}; 233};
238 234
239static int wm8903_volatile_register(unsigned int reg) 235static int wm8903_volatile_register(unsigned int reg)
@@ -463,6 +459,72 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol,
463 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } 459 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) }
464 460
465 461
462static int wm8903_deemph[] = { 0, 32000, 44100, 48000 };
463
464static int wm8903_set_deemph(struct snd_soc_codec *codec)
465{
466 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
467 int val, i, best;
468
469 /* If we're using deemphasis select the nearest available sample
470 * rate.
471 */
472 if (wm8903->deemph) {
473 best = 1;
474 for (i = 2; i < ARRAY_SIZE(wm8903_deemph); i++) {
475 if (abs(wm8903_deemph[i] - wm8903->fs) <
476 abs(wm8903_deemph[best] - wm8903->fs))
477 best = i;
478 }
479
480 val = best << WM8903_DEEMPH_SHIFT;
481 } else {
482 best = 0;
483 val = 0;
484 }
485
486 dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n",
487 best, wm8903_deemph[best]);
488
489 return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
490 WM8903_DEEMPH_MASK, val);
491}
492
493static int wm8903_get_deemph(struct snd_kcontrol *kcontrol,
494 struct snd_ctl_elem_value *ucontrol)
495{
496 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
497 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
498
499 ucontrol->value.enumerated.item[0] = wm8903->deemph;
500
501 return 0;
502}
503
504static int wm8903_put_deemph(struct snd_kcontrol *kcontrol,
505 struct snd_ctl_elem_value *ucontrol)
506{
507 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
508 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
509 int deemph = ucontrol->value.enumerated.item[0];
510 int ret = 0;
511
512 if (deemph > 1)
513 return -EINVAL;
514
515 mutex_lock(&codec->mutex);
516 if (wm8903->deemph != deemph) {
517 wm8903->deemph = deemph;
518
519 wm8903_set_deemph(codec);
520
521 ret = 1;
522 }
523 mutex_unlock(&codec->mutex);
524
525 return ret;
526}
527
466/* ALSA can only do steps of .01dB */ 528/* ALSA can only do steps of .01dB */
467static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); 529static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
468 530
@@ -475,6 +537,23 @@ static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0);
475static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0); 537static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0);
476static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0); 538static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);
477 539
540static const char *hpf_mode_text[] = {
541 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
542};
543
544static const struct soc_enum hpf_mode =
545 SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text);
546
547static const char *osr_text[] = {
548 "Low power", "High performance"
549};
550
551static const struct soc_enum adc_osr =
552 SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text);
553
554static const struct soc_enum dac_osr =
555 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text);
556
478static const char *drc_slope_text[] = { 557static const char *drc_slope_text[] = {
479 "1", "1/2", "1/4", "1/8", "1/16", "0" 558 "1", "1/2", "1/4", "1/8", "1/16", "0"
480}; 559};
@@ -537,13 +616,6 @@ static const char *mute_mode_text[] = {
537static const struct soc_enum mute_mode = 616static const struct soc_enum mute_mode =
538 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text); 617 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text);
539 618
540static const char *dac_deemphasis_text[] = {
541 "Disabled", "32kHz", "44.1kHz", "48kHz"
542};
543
544static const struct soc_enum dac_deemphasis =
545 SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text);
546
547static const char *companding_text[] = { 619static const char *companding_text[] = {
548 "ulaw", "alaw" 620 "ulaw", "alaw"
549}; 621};
@@ -613,6 +685,9 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1,
613 6, 1, 0), 685 6, 1, 0),
614 686
615/* ADCs */ 687/* ADCs */
688SOC_ENUM("ADC OSR", adc_osr),
689SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0),
690SOC_ENUM("HPF Mode", hpf_mode),
616SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), 691SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0),
617SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), 692SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0),
618SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), 693SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1),
@@ -642,14 +717,16 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8,
642 12, 0, digital_sidetone_tlv), 717 12, 0, digital_sidetone_tlv),
643 718
644/* DAC */ 719/* DAC */
720SOC_ENUM("DAC OSR", dac_osr),
645SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, 721SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT,
646 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), 722 WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv),
647SOC_ENUM("DAC Soft Mute Rate", soft_mute), 723SOC_ENUM("DAC Soft Mute Rate", soft_mute),
648SOC_ENUM("DAC Mute Mode", mute_mode), 724SOC_ENUM("DAC Mute Mode", mute_mode),
649SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), 725SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0),
650SOC_ENUM("DAC De-emphasis", dac_deemphasis),
651SOC_ENUM("DAC Companding Mode", dac_companding), 726SOC_ENUM("DAC Companding Mode", dac_companding),
652SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), 727SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0),
728SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0,
729 wm8903_get_deemph, wm8903_put_deemph),
653 730
654/* Headphones */ 731/* Headphones */
655SOC_DOUBLE_R("Headphone Switch", 732SOC_DOUBLE_R("Headphone Switch",
@@ -923,10 +1000,11 @@ static const struct snd_soc_dapm_route intercon[] = {
923 1000
924static int wm8903_add_widgets(struct snd_soc_codec *codec) 1001static int wm8903_add_widgets(struct snd_soc_codec *codec)
925{ 1002{
926 snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets, 1003 struct snd_soc_dapm_context *dapm = &codec->dapm;
927 ARRAY_SIZE(wm8903_dapm_widgets));
928 1004
929 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 1005 snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets,
1006 ARRAY_SIZE(wm8903_dapm_widgets));
1007 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
930 1008
931 return 0; 1009 return 0;
932} 1010}
@@ -934,7 +1012,7 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec)
934static int wm8903_set_bias_level(struct snd_soc_codec *codec, 1012static int wm8903_set_bias_level(struct snd_soc_codec *codec,
935 enum snd_soc_bias_level level) 1013 enum snd_soc_bias_level level)
936{ 1014{
937 u16 reg, reg2; 1015 u16 reg;
938 1016
939 switch (level) { 1017 switch (level) {
940 case SND_SOC_BIAS_ON: 1018 case SND_SOC_BIAS_ON:
@@ -946,7 +1024,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
946 break; 1024 break;
947 1025
948 case SND_SOC_BIAS_STANDBY: 1026 case SND_SOC_BIAS_STANDBY:
949 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1027 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
950 snd_soc_write(codec, WM8903_CLOCK_RATES_2, 1028 snd_soc_write(codec, WM8903_CLOCK_RATES_2,
951 WM8903_CLK_SYS_ENA); 1029 WM8903_CLK_SYS_ENA);
952 1030
@@ -958,23 +1036,15 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
958 wm8903_run_sequence(codec, 0); 1036 wm8903_run_sequence(codec, 0);
959 wm8903_sync_reg_cache(codec, codec->reg_cache); 1037 wm8903_sync_reg_cache(codec, codec->reg_cache);
960 1038
961 /* Enable low impedence charge pump output */
962 reg = snd_soc_read(codec,
963 WM8903_CONTROL_INTERFACE_TEST_1);
964 snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
965 reg | WM8903_TEST_KEY);
966 reg2 = snd_soc_read(codec, WM8903_CHARGE_PUMP_TEST_1);
967 snd_soc_write(codec, WM8903_CHARGE_PUMP_TEST_1,
968 reg2 | WM8903_CP_SW_KELVIN_MODE_MASK);
969 snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1,
970 reg);
971
972 /* By default no bypass paths are enabled so 1039 /* By default no bypass paths are enabled so
973 * enable Class W support. 1040 * enable Class W support.
974 */ 1041 */
975 dev_dbg(codec->dev, "Enabling Class W\n"); 1042 dev_dbg(codec->dev, "Enabling Class W\n");
976 snd_soc_write(codec, WM8903_CLASS_W_0, reg | 1043 snd_soc_update_bits(codec, WM8903_CLASS_W_0,
977 WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); 1044 WM8903_CP_DYN_FREQ |
1045 WM8903_CP_DYN_V,
1046 WM8903_CP_DYN_FREQ |
1047 WM8903_CP_DYN_V);
978 } 1048 }
979 1049
980 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); 1050 reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0);
@@ -991,7 +1061,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec,
991 break; 1061 break;
992 } 1062 }
993 1063
994 codec->bias_level = level; 1064 codec->dapm.bias_level = level;
995 1065
996 return 0; 1066 return 0;
997} 1067}
@@ -1222,58 +1292,6 @@ static struct {
1222 { 0, 0 }, 1292 { 0, 0 },
1223}; 1293};
1224 1294
1225static int wm8903_startup(struct snd_pcm_substream *substream,
1226 struct snd_soc_dai *dai)
1227{
1228 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1229 struct snd_soc_codec *codec = rtd->codec;
1230 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1231 struct snd_pcm_runtime *master_runtime;
1232
1233 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1234 wm8903->playback_active++;
1235 else
1236 wm8903->capture_active++;
1237
1238 /* The DAI has shared clocks so if we already have a playback or
1239 * capture going then constrain this substream to match it.
1240 */
1241 if (wm8903->master_substream) {
1242 master_runtime = wm8903->master_substream->runtime;
1243
1244 dev_dbg(codec->dev, "Constraining to %d bits\n",
1245 master_runtime->sample_bits);
1246
1247 snd_pcm_hw_constraint_minmax(substream->runtime,
1248 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1249 master_runtime->sample_bits,
1250 master_runtime->sample_bits);
1251
1252 wm8903->slave_substream = substream;
1253 } else
1254 wm8903->master_substream = substream;
1255
1256 return 0;
1257}
1258
1259static void wm8903_shutdown(struct snd_pcm_substream *substream,
1260 struct snd_soc_dai *dai)
1261{
1262 struct snd_soc_pcm_runtime *rtd = substream->private_data;
1263 struct snd_soc_codec *codec = rtd->codec;
1264 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1265
1266 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1267 wm8903->playback_active--;
1268 else
1269 wm8903->capture_active--;
1270
1271 if (wm8903->master_substream == substream)
1272 wm8903->master_substream = wm8903->slave_substream;
1273
1274 wm8903->slave_substream = NULL;
1275}
1276
1277static int wm8903_hw_params(struct snd_pcm_substream *substream, 1295static int wm8903_hw_params(struct snd_pcm_substream *substream,
1278 struct snd_pcm_hw_params *params, 1296 struct snd_pcm_hw_params *params,
1279 struct snd_soc_dai *dai) 1297 struct snd_soc_dai *dai)
@@ -1298,11 +1316,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1298 u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1); 1316 u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1);
1299 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); 1317 u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1);
1300 1318
1301 if (substream == wm8903->slave_substream) {
1302 dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n");
1303 return 0;
1304 }
1305
1306 /* Enable sloping stopband filter for low sample rates */ 1319 /* Enable sloping stopband filter for low sample rates */
1307 if (fs <= 24000) 1320 if (fs <= 24000)
1308 dac_digital1 |= WM8903_DAC_SB_FILT; 1321 dac_digital1 |= WM8903_DAC_SB_FILT;
@@ -1320,19 +1333,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1320 } 1333 }
1321 } 1334 }
1322 1335
1323 /* Constraints should stop us hitting this but let's make sure */
1324 if (wm8903->capture_active)
1325 switch (sample_rates[dsp_config].rate) {
1326 case 88200:
1327 case 96000:
1328 dev_err(codec->dev, "%dHz unsupported by ADC\n",
1329 fs);
1330 return -EINVAL;
1331
1332 default:
1333 break;
1334 }
1335
1336 dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate); 1336 dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate);
1337 clock1 &= ~WM8903_SAMPLE_RATE_MASK; 1337 clock1 &= ~WM8903_SAMPLE_RATE_MASK;
1338 clock1 |= sample_rates[dsp_config].value; 1338 clock1 |= sample_rates[dsp_config].value;
@@ -1428,6 +1428,9 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream,
1428 aif2 |= bclk_divs[bclk_div].div; 1428 aif2 |= bclk_divs[bclk_div].div;
1429 aif3 |= bclk / fs; 1429 aif3 |= bclk / fs;
1430 1430
1431 wm8903->fs = params_rate(params);
1432 wm8903_set_deemph(codec);
1433
1431 snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0); 1434 snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0);
1432 snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1); 1435 snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1);
1433 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); 1436 snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1);
@@ -1521,6 +1524,11 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1521 mic_report = wm8903->mic_last_report; 1524 mic_report = wm8903->mic_last_report;
1522 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); 1525 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1);
1523 1526
1527#ifndef CONFIG_SND_SOC_WM8903_MODULE
1528 if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT))
1529 trace_snd_soc_jack_irq(dev_name(codec->dev));
1530#endif
1531
1524 if (int_val & WM8903_MICSHRT_EINT) { 1532 if (int_val & WM8903_MICSHRT_EINT) {
1525 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); 1533 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol);
1526 1534
@@ -1571,8 +1579,6 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1571 SNDRV_PCM_FMTBIT_S24_LE) 1579 SNDRV_PCM_FMTBIT_S24_LE)
1572 1580
1573static struct snd_soc_dai_ops wm8903_dai_ops = { 1581static struct snd_soc_dai_ops wm8903_dai_ops = {
1574 .startup = wm8903_startup,
1575 .shutdown = wm8903_shutdown,
1576 .hw_params = wm8903_hw_params, 1582 .hw_params = wm8903_hw_params,
1577 .digital_mute = wm8903_digital_mute, 1583 .digital_mute = wm8903_digital_mute,
1578 .set_fmt = wm8903_set_dai_fmt, 1584 .set_fmt = wm8903_set_dai_fmt,
diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h
index 996435e681e5..e8490f3edd03 100644
--- a/sound/soc/codecs/wm8903.h
+++ b/sound/soc/codecs/wm8903.h
@@ -19,10 +19,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
19 struct snd_soc_jack *jack, 19 struct snd_soc_jack *jack,
20 int det, int shrt); 20 int det, int shrt);
21 21
22#define WM8903_MCLK_DIV_2 1
23#define WM8903_CLK_SYS 2
24#define WM8903_BCLK 3
25#define WM8903_LRCLK 4
26 22
27/* 23/*
28 * Register values. 24 * Register values.
@@ -98,8 +94,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
98#define WM8903_INTERRUPT_STATUS_1_MASK 0x7A 94#define WM8903_INTERRUPT_STATUS_1_MASK 0x7A
99#define WM8903_INTERRUPT_POLARITY_1 0x7B 95#define WM8903_INTERRUPT_POLARITY_1 0x7B
100#define WM8903_INTERRUPT_CONTROL 0x7E 96#define WM8903_INTERRUPT_CONTROL 0x7E
101#define WM8903_CONTROL_INTERFACE_TEST_1 0x81
102#define WM8903_CHARGE_PUMP_TEST_1 0x95
103#define WM8903_CLOCK_RATE_TEST_4 0xA4 97#define WM8903_CLOCK_RATE_TEST_4 0xA4
104#define WM8903_ANALOGUE_OUTPUT_BIAS_0 0xAC 98#define WM8903_ANALOGUE_OUTPUT_BIAS_0 0xAC
105 99
@@ -1206,25 +1200,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec,
1206#define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */ 1200#define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */
1207 1201
1208/* 1202/*
1209 * R129 (0x81) - Control Interface Test 1
1210 */
1211#define WM8903_USER_KEY 0x0002 /* USER_KEY */
1212#define WM8903_USER_KEY_MASK 0x0002 /* USER_KEY */
1213#define WM8903_USER_KEY_SHIFT 1 /* USER_KEY */
1214#define WM8903_USER_KEY_WIDTH 1 /* USER_KEY */
1215#define WM8903_TEST_KEY 0x0001 /* TEST_KEY */
1216#define WM8903_TEST_KEY_MASK 0x0001 /* TEST_KEY */
1217#define WM8903_TEST_KEY_SHIFT 0 /* TEST_KEY */
1218#define WM8903_TEST_KEY_WIDTH 1 /* TEST_KEY */
1219
1220/*
1221 * R149 (0x95) - Charge Pump Test 1
1222 */
1223#define WM8903_CP_SW_KELVIN_MODE_MASK 0x0006 /* CP_SW_KELVIN_MODE - [2:1] */
1224#define WM8903_CP_SW_KELVIN_MODE_SHIFT 1 /* CP_SW_KELVIN_MODE - [2:1] */
1225#define WM8903_CP_SW_KELVIN_MODE_WIDTH 2 /* CP_SW_KELVIN_MODE - [2:1] */
1226
1227/*
1228 * R164 (0xA4) - Clock Rate Test 4 1203 * R164 (0xA4) - Clock Rate Test 4
1229 */ 1204 */
1230#define WM8903_ADC_DIG_MIC 0x0200 /* ADC_DIG_MIC */ 1205#define WM8903_ADC_DIG_MIC 0x0200 /* ADC_DIG_MIC */
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 1ec12eff0620..9de44a4c05c0 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -24,7 +24,6 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30#include <sound/wm8904.h> 29#include <sound/wm8904.h>
@@ -1427,10 +1426,11 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = {
1427static int wm8904_add_widgets(struct snd_soc_codec *codec) 1426static int wm8904_add_widgets(struct snd_soc_codec *codec)
1428{ 1427{
1429 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 1428 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
1429 struct snd_soc_dapm_context *dapm = &codec->dapm;
1430 1430
1431 snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets, 1431 snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets,
1432 ARRAY_SIZE(wm8904_core_dapm_widgets)); 1432 ARRAY_SIZE(wm8904_core_dapm_widgets));
1433 snd_soc_dapm_add_routes(codec, core_intercon, 1433 snd_soc_dapm_add_routes(dapm, core_intercon,
1434 ARRAY_SIZE(core_intercon)); 1434 ARRAY_SIZE(core_intercon));
1435 1435
1436 switch (wm8904->devtype) { 1436 switch (wm8904->devtype) {
@@ -1442,20 +1442,20 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1442 snd_soc_add_controls(codec, wm8904_snd_controls, 1442 snd_soc_add_controls(codec, wm8904_snd_controls,
1443 ARRAY_SIZE(wm8904_snd_controls)); 1443 ARRAY_SIZE(wm8904_snd_controls));
1444 1444
1445 snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets, 1445 snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets,
1446 ARRAY_SIZE(wm8904_adc_dapm_widgets)); 1446 ARRAY_SIZE(wm8904_adc_dapm_widgets));
1447 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, 1447 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
1448 ARRAY_SIZE(wm8904_dac_dapm_widgets)); 1448 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1449 snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets, 1449 snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets,
1450 ARRAY_SIZE(wm8904_dapm_widgets)); 1450 ARRAY_SIZE(wm8904_dapm_widgets));
1451 1451
1452 snd_soc_dapm_add_routes(codec, core_intercon, 1452 snd_soc_dapm_add_routes(dapm, core_intercon,
1453 ARRAY_SIZE(core_intercon)); 1453 ARRAY_SIZE(core_intercon));
1454 snd_soc_dapm_add_routes(codec, adc_intercon, 1454 snd_soc_dapm_add_routes(dapm, adc_intercon,
1455 ARRAY_SIZE(adc_intercon)); 1455 ARRAY_SIZE(adc_intercon));
1456 snd_soc_dapm_add_routes(codec, dac_intercon, 1456 snd_soc_dapm_add_routes(dapm, dac_intercon,
1457 ARRAY_SIZE(dac_intercon)); 1457 ARRAY_SIZE(dac_intercon));
1458 snd_soc_dapm_add_routes(codec, wm8904_intercon, 1458 snd_soc_dapm_add_routes(dapm, wm8904_intercon,
1459 ARRAY_SIZE(wm8904_intercon)); 1459 ARRAY_SIZE(wm8904_intercon));
1460 break; 1460 break;
1461 1461
@@ -1463,17 +1463,17 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1463 snd_soc_add_controls(codec, wm8904_dac_snd_controls, 1463 snd_soc_add_controls(codec, wm8904_dac_snd_controls,
1464 ARRAY_SIZE(wm8904_dac_snd_controls)); 1464 ARRAY_SIZE(wm8904_dac_snd_controls));
1465 1465
1466 snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, 1466 snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets,
1467 ARRAY_SIZE(wm8904_dac_dapm_widgets)); 1467 ARRAY_SIZE(wm8904_dac_dapm_widgets));
1468 1468
1469 snd_soc_dapm_add_routes(codec, dac_intercon, 1469 snd_soc_dapm_add_routes(dapm, dac_intercon,
1470 ARRAY_SIZE(dac_intercon)); 1470 ARRAY_SIZE(dac_intercon));
1471 snd_soc_dapm_add_routes(codec, wm8912_intercon, 1471 snd_soc_dapm_add_routes(dapm, wm8912_intercon,
1472 ARRAY_SIZE(wm8912_intercon)); 1472 ARRAY_SIZE(wm8912_intercon));
1473 break; 1473 break;
1474 } 1474 }
1475 1475
1476 snd_soc_dapm_new_widgets(codec); 1476 snd_soc_dapm_new_widgets(dapm);
1477 return 0; 1477 return 0;
1478} 1478}
1479 1479
@@ -1589,7 +1589,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream,
1589 - wm8904->fs); 1589 - wm8904->fs);
1590 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { 1590 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1591 cur_val = abs((wm8904->sysclk_rate / 1591 cur_val = abs((wm8904->sysclk_rate /
1592 clk_sys_rates[i].ratio) - wm8904->fs);; 1592 clk_sys_rates[i].ratio) - wm8904->fs);
1593 if (cur_val < best_val) { 1593 if (cur_val < best_val) {
1594 best = i; 1594 best = i;
1595 best_val = cur_val; 1595 best_val = cur_val;
@@ -2138,7 +2138,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2138 break; 2138 break;
2139 2139
2140 case SND_SOC_BIAS_STANDBY: 2140 case SND_SOC_BIAS_STANDBY:
2141 if (codec->bias_level == SND_SOC_BIAS_OFF) { 2141 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
2142 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), 2142 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2143 wm8904->supplies); 2143 wm8904->supplies);
2144 if (ret != 0) { 2144 if (ret != 0) {
@@ -2197,7 +2197,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec,
2197 wm8904->supplies); 2197 wm8904->supplies);
2198 break; 2198 break;
2199 } 2199 }
2200 codec->bias_level = level; 2200 codec->dapm.bias_level = level;
2201 return 0; 2201 return 0;
2202} 2202}
2203 2203
@@ -2373,7 +2373,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2373 int ret, i; 2373 int ret, i;
2374 2374
2375 codec->cache_sync = 1; 2375 codec->cache_sync = 1;
2376 codec->idle_bias_off = 1; 2376 codec->dapm.idle_bias_off = 1;
2377 2377
2378 switch (wm8904->devtype) { 2378 switch (wm8904->devtype) {
2379 case WM8904: 2379 case WM8904:
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c
index 23086e2c976a..25580e3ee7c4 100644
--- a/sound/soc/codecs/wm8940.c
+++ b/sound/soc/codecs/wm8940.c
@@ -35,7 +35,6 @@
35#include <sound/pcm.h> 35#include <sound/pcm.h>
36#include <sound/pcm_params.h> 36#include <sound/pcm_params.h>
37#include <sound/soc.h> 37#include <sound/soc.h>
38#include <sound/soc-dapm.h>
39#include <sound/initval.h> 38#include <sound/initval.h>
40#include <sound/tlv.h> 39#include <sound/tlv.h>
41 40
@@ -43,7 +42,6 @@
43 42
44struct wm8940_priv { 43struct wm8940_priv {
45 unsigned int sysclk; 44 unsigned int sysclk;
46 u16 reg_cache[WM8940_CACHEREGNUM];
47 enum snd_soc_control_type control_type; 45 enum snd_soc_control_type control_type;
48 void *control_data; 46 void *control_data;
49}; 47};
@@ -291,13 +289,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
291 289
292static int wm8940_add_widgets(struct snd_soc_codec *codec) 290static int wm8940_add_widgets(struct snd_soc_codec *codec)
293{ 291{
292 struct snd_soc_dapm_context *dapm = &codec->dapm;
294 int ret; 293 int ret;
295 294
296 ret = snd_soc_dapm_new_controls(codec, wm8940_dapm_widgets, 295 ret = snd_soc_dapm_new_controls(dapm, wm8940_dapm_widgets,
297 ARRAY_SIZE(wm8940_dapm_widgets)); 296 ARRAY_SIZE(wm8940_dapm_widgets));
298 if (ret) 297 if (ret)
299 goto error_ret; 298 goto error_ret;
300 ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 299 ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
301 if (ret) 300 if (ret)
302 goto error_ret; 301 goto error_ret;
303 302
@@ -735,7 +734,6 @@ static int wm8940_probe(struct snd_soc_codec *codec)
735 return ret; 734 return ret;
736 735
737 return ret; 736 return ret;
738;
739} 737}
740 738
741static int wm8940_remove(struct snd_soc_codec *codec) 739static int wm8940_remove(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c
index 2ac35b0be86a..7167dfc96aa7 100644
--- a/sound/soc/codecs/wm8955.c
+++ b/sound/soc/codecs/wm8955.c
@@ -23,7 +23,6 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29#include <sound/wm8955.h> 28#include <sound/wm8955.h>
@@ -576,13 +575,14 @@ static const struct snd_soc_dapm_route wm8955_intercon[] = {
576 575
577static int wm8955_add_widgets(struct snd_soc_codec *codec) 576static int wm8955_add_widgets(struct snd_soc_codec *codec)
578{ 577{
578 struct snd_soc_dapm_context *dapm = &codec->dapm;
579
579 snd_soc_add_controls(codec, wm8955_snd_controls, 580 snd_soc_add_controls(codec, wm8955_snd_controls,
580 ARRAY_SIZE(wm8955_snd_controls)); 581 ARRAY_SIZE(wm8955_snd_controls));
581 582
582 snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets, 583 snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets,
583 ARRAY_SIZE(wm8955_dapm_widgets)); 584 ARRAY_SIZE(wm8955_dapm_widgets));
584 585 snd_soc_dapm_add_routes(dapm, wm8955_intercon,
585 snd_soc_dapm_add_routes(codec, wm8955_intercon,
586 ARRAY_SIZE(wm8955_intercon)); 586 ARRAY_SIZE(wm8955_intercon));
587 587
588 return 0; 588 return 0;
@@ -786,7 +786,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
786 break; 786 break;
787 787
788 case SND_SOC_BIAS_STANDBY: 788 case SND_SOC_BIAS_STANDBY:
789 if (codec->bias_level == SND_SOC_BIAS_OFF) { 789 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
790 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies), 790 ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies),
791 wm8955->supplies); 791 wm8955->supplies);
792 if (ret != 0) { 792 if (ret != 0) {
@@ -850,7 +850,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec,
850 wm8955->supplies); 850 wm8955->supplies);
851 break; 851 break;
852 } 852 }
853 codec->bias_level = level; 853 codec->dapm.bias_level = level;
854 return 0; 854 return 0;
855} 855}
856 856
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index ff6ff2f529d2..4393394b7bc1 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -20,7 +20,6 @@
20#include <sound/pcm.h> 20#include <sound/pcm.h>
21#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/initval.h> 23#include <sound/initval.h>
25#include <sound/tlv.h> 24#include <sound/tlv.h>
26#include <sound/wm8960.h> 25#include <sound/wm8960.h>
@@ -72,7 +71,6 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = {
72}; 71};
73 72
74struct wm8960_priv { 73struct wm8960_priv {
75 u16 reg_cache[WM8960_CACHEREGNUM];
76 enum snd_soc_control_type control_type; 74 enum snd_soc_control_type control_type;
77 void *control_data; 75 void *control_data;
78 int (*set_bias_level)(struct snd_soc_codec *, 76 int (*set_bias_level)(struct snd_soc_codec *,
@@ -389,27 +387,28 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
389{ 387{
390 struct wm8960_data *pdata = codec->dev->platform_data; 388 struct wm8960_data *pdata = codec->dev->platform_data;
391 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); 389 struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
390 struct snd_soc_dapm_context *dapm = &codec->dapm;
392 struct snd_soc_dapm_widget *w; 391 struct snd_soc_dapm_widget *w;
393 392
394 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets, 393 snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets,
395 ARRAY_SIZE(wm8960_dapm_widgets)); 394 ARRAY_SIZE(wm8960_dapm_widgets));
396 395
397 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 396 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
398 397
399 /* In capless mode OUT3 is used to provide VMID for the 398 /* In capless mode OUT3 is used to provide VMID for the
400 * headphone outputs, otherwise it is used as a mono mixer. 399 * headphone outputs, otherwise it is used as a mono mixer.
401 */ 400 */
402 if (pdata && pdata->capless) { 401 if (pdata && pdata->capless) {
403 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_capless, 402 snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_capless,
404 ARRAY_SIZE(wm8960_dapm_widgets_capless)); 403 ARRAY_SIZE(wm8960_dapm_widgets_capless));
405 404
406 snd_soc_dapm_add_routes(codec, audio_paths_capless, 405 snd_soc_dapm_add_routes(dapm, audio_paths_capless,
407 ARRAY_SIZE(audio_paths_capless)); 406 ARRAY_SIZE(audio_paths_capless));
408 } else { 407 } else {
409 snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_out3, 408 snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_out3,
410 ARRAY_SIZE(wm8960_dapm_widgets_out3)); 409 ARRAY_SIZE(wm8960_dapm_widgets_out3));
411 410
412 snd_soc_dapm_add_routes(codec, audio_paths_out3, 411 snd_soc_dapm_add_routes(dapm, audio_paths_out3,
413 ARRAY_SIZE(audio_paths_out3)); 412 ARRAY_SIZE(audio_paths_out3));
414 } 413 }
415 414
@@ -418,7 +417,9 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
418 * list each time to find the desired power state do so now 417 * list each time to find the desired power state do so now
419 * and save the result. 418 * and save the result.
420 */ 419 */
421 list_for_each_entry(w, &codec->dapm_widgets, list) { 420 list_for_each_entry(w, &codec->card->widgets, list) {
421 if (w->dapm != &codec->dapm)
422 continue;
422 if (strcmp(w->name, "LOUT1 PGA") == 0) 423 if (strcmp(w->name, "LOUT1 PGA") == 0)
423 wm8960->lout1 = w; 424 wm8960->lout1 = w;
424 if (strcmp(w->name, "ROUT1 PGA") == 0) 425 if (strcmp(w->name, "ROUT1 PGA") == 0)
@@ -573,7 +574,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
573 break; 574 break;
574 575
575 case SND_SOC_BIAS_STANDBY: 576 case SND_SOC_BIAS_STANDBY:
576 if (codec->bias_level == SND_SOC_BIAS_OFF) { 577 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
577 /* Enable anti-pop features */ 578 /* Enable anti-pop features */
578 snd_soc_write(codec, WM8960_APOP1, 579 snd_soc_write(codec, WM8960_APOP1,
579 WM8960_POBCTRL | WM8960_SOFT_ST | 580 WM8960_POBCTRL | WM8960_SOFT_ST |
@@ -611,7 +612,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec,
611 break; 612 break;
612 } 613 }
613 614
614 codec->bias_level = level; 615 codec->dapm.bias_level = level;
615 616
616 return 0; 617 return 0;
617} 618}
@@ -627,7 +628,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
627 break; 628 break;
628 629
629 case SND_SOC_BIAS_PREPARE: 630 case SND_SOC_BIAS_PREPARE:
630 switch (codec->bias_level) { 631 switch (codec->dapm.bias_level) {
631 case SND_SOC_BIAS_STANDBY: 632 case SND_SOC_BIAS_STANDBY:
632 /* Enable anti pop mode */ 633 /* Enable anti pop mode */
633 snd_soc_update_bits(codec, WM8960_APOP1, 634 snd_soc_update_bits(codec, WM8960_APOP1,
@@ -682,7 +683,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
682 break; 683 break;
683 684
684 case SND_SOC_BIAS_STANDBY: 685 case SND_SOC_BIAS_STANDBY:
685 switch (codec->bias_level) { 686 switch (codec->dapm.bias_level) {
686 case SND_SOC_BIAS_PREPARE: 687 case SND_SOC_BIAS_PREPARE:
687 /* Disable HP discharge */ 688 /* Disable HP discharge */
688 snd_soc_update_bits(codec, WM8960_APOP2, 689 snd_soc_update_bits(codec, WM8960_APOP2,
@@ -706,7 +707,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec,
706 break; 707 break;
707 } 708 }
708 709
709 codec->bias_level = level; 710 codec->dapm.bias_level = level;
710 711
711 return 0; 712 return 0;
712} 713}
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 8340485c9851..55252e7d02c9 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -23,7 +23,6 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29 28
@@ -290,7 +289,6 @@ static u16 wm8961_reg_defaults[] = {
290struct wm8961_priv { 289struct wm8961_priv {
291 enum snd_soc_control_type control_type; 290 enum snd_soc_control_type control_type;
292 int sysclk; 291 int sysclk;
293 u16 reg_cache[WM8961_MAX_REGISTER];
294}; 292};
295 293
296static int wm8961_volatile_register(unsigned int reg) 294static int wm8961_volatile_register(unsigned int reg)
@@ -882,7 +880,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
882 break; 880 break;
883 881
884 case SND_SOC_BIAS_PREPARE: 882 case SND_SOC_BIAS_PREPARE:
885 if (codec->bias_level == SND_SOC_BIAS_STANDBY) { 883 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
886 /* Enable bias generation */ 884 /* Enable bias generation */
887 reg = snd_soc_read(codec, WM8961_ANTI_POP); 885 reg = snd_soc_read(codec, WM8961_ANTI_POP);
888 reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN; 886 reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN;
@@ -897,7 +895,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
897 break; 895 break;
898 896
899 case SND_SOC_BIAS_STANDBY: 897 case SND_SOC_BIAS_STANDBY:
900 if (codec->bias_level == SND_SOC_BIAS_PREPARE) { 898 if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) {
901 /* VREF off */ 899 /* VREF off */
902 reg = snd_soc_read(codec, WM8961_PWR_MGMT_1); 900 reg = snd_soc_read(codec, WM8961_PWR_MGMT_1);
903 reg &= ~WM8961_VREF; 901 reg &= ~WM8961_VREF;
@@ -919,7 +917,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec,
919 break; 917 break;
920 } 918 }
921 919
922 codec->bias_level = level; 920 codec->dapm.bias_level = level;
923 921
924 return 0; 922 return 0;
925} 923}
@@ -959,6 +957,7 @@ static struct snd_soc_dai_driver wm8961_dai = {
959 957
960static int wm8961_probe(struct snd_soc_codec *codec) 958static int wm8961_probe(struct snd_soc_codec *codec)
961{ 959{
960 struct snd_soc_dapm_context *dapm = &codec->dapm;
962 int ret = 0; 961 int ret = 0;
963 u16 reg; 962 u16 reg;
964 963
@@ -1024,9 +1023,9 @@ static int wm8961_probe(struct snd_soc_codec *codec)
1024 1023
1025 snd_soc_add_controls(codec, wm8961_snd_controls, 1024 snd_soc_add_controls(codec, wm8961_snd_controls,
1026 ARRAY_SIZE(wm8961_snd_controls)); 1025 ARRAY_SIZE(wm8961_snd_controls));
1027 snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets, 1026 snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets,
1028 ARRAY_SIZE(wm8961_dapm_widgets)); 1027 ARRAY_SIZE(wm8961_dapm_widgets));
1029 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 1028 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
1030 1029
1031 return 0; 1030 return 0;
1032} 1031}
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 7c421cc837bd..b9cb1fcf8c92 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -29,10 +29,10 @@
29#include <sound/pcm.h> 29#include <sound/pcm.h>
30#include <sound/pcm_params.h> 30#include <sound/pcm_params.h>
31#include <sound/soc.h> 31#include <sound/soc.h>
32#include <sound/soc-dapm.h>
33#include <sound/initval.h> 32#include <sound/initval.h>
34#include <sound/tlv.h> 33#include <sound/tlv.h>
35#include <sound/wm8962.h> 34#include <sound/wm8962.h>
35#include <trace/events/asoc.h>
36 36
37#include "wm8962.h" 37#include "wm8962.h"
38 38
@@ -1956,7 +1956,7 @@ static int wm8962_readable_register(unsigned int reg)
1956 1956
1957static int wm8962_reset(struct snd_soc_codec *codec) 1957static int wm8962_reset(struct snd_soc_codec *codec)
1958{ 1958{
1959 return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0); 1959 return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243);
1960} 1960}
1961 1961
1962static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); 1962static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0);
@@ -2677,6 +2677,7 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = {
2677static int wm8962_add_widgets(struct snd_soc_codec *codec) 2677static int wm8962_add_widgets(struct snd_soc_codec *codec)
2678{ 2678{
2679 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); 2679 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev);
2680 struct snd_soc_dapm_context *dapm = &codec->dapm;
2680 2681
2681 snd_soc_add_controls(codec, wm8962_snd_controls, 2682 snd_soc_add_controls(codec, wm8962_snd_controls,
2682 ARRAY_SIZE(wm8962_snd_controls)); 2683 ARRAY_SIZE(wm8962_snd_controls));
@@ -2688,26 +2689,26 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec)
2688 ARRAY_SIZE(wm8962_spk_stereo_controls)); 2689 ARRAY_SIZE(wm8962_spk_stereo_controls));
2689 2690
2690 2691
2691 snd_soc_dapm_new_controls(codec, wm8962_dapm_widgets, 2692 snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets,
2692 ARRAY_SIZE(wm8962_dapm_widgets)); 2693 ARRAY_SIZE(wm8962_dapm_widgets));
2693 if (pdata && pdata->spk_mono) 2694 if (pdata && pdata->spk_mono)
2694 snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_mono_widgets, 2695 snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets,
2695 ARRAY_SIZE(wm8962_dapm_spk_mono_widgets)); 2696 ARRAY_SIZE(wm8962_dapm_spk_mono_widgets));
2696 else 2697 else
2697 snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_stereo_widgets, 2698 snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_stereo_widgets,
2698 ARRAY_SIZE(wm8962_dapm_spk_stereo_widgets)); 2699 ARRAY_SIZE(wm8962_dapm_spk_stereo_widgets));
2699 2700
2700 snd_soc_dapm_add_routes(codec, wm8962_intercon, 2701 snd_soc_dapm_add_routes(dapm, wm8962_intercon,
2701 ARRAY_SIZE(wm8962_intercon)); 2702 ARRAY_SIZE(wm8962_intercon));
2702 if (pdata && pdata->spk_mono) 2703 if (pdata && pdata->spk_mono)
2703 snd_soc_dapm_add_routes(codec, wm8962_spk_mono_intercon, 2704 snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon,
2704 ARRAY_SIZE(wm8962_spk_mono_intercon)); 2705 ARRAY_SIZE(wm8962_spk_mono_intercon));
2705 else 2706 else
2706 snd_soc_dapm_add_routes(codec, wm8962_spk_stereo_intercon, 2707 snd_soc_dapm_add_routes(dapm, wm8962_spk_stereo_intercon,
2707 ARRAY_SIZE(wm8962_spk_stereo_intercon)); 2708 ARRAY_SIZE(wm8962_spk_stereo_intercon));
2708 2709
2709 2710
2710 snd_soc_dapm_disable_pin(codec, "Beep"); 2711 snd_soc_dapm_disable_pin(dapm, "Beep");
2711 2712
2712 return 0; 2713 return 0;
2713} 2714}
@@ -2814,7 +2815,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
2814 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); 2815 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec);
2815 int ret; 2816 int ret;
2816 2817
2817 if (level == codec->bias_level) 2818 if (level == codec->dapm.bias_level)
2818 return 0; 2819 return 0;
2819 2820
2820 switch (level) { 2821 switch (level) {
@@ -2828,7 +2829,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
2828 break; 2829 break;
2829 2830
2830 case SND_SOC_BIAS_STANDBY: 2831 case SND_SOC_BIAS_STANDBY:
2831 if (codec->bias_level == SND_SOC_BIAS_OFF) { 2832 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
2832 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), 2833 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies),
2833 wm8962->supplies); 2834 wm8962->supplies);
2834 if (ret != 0) { 2835 if (ret != 0) {
@@ -2878,7 +2879,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec,
2878 wm8962->supplies); 2879 wm8962->supplies);
2879 break; 2880 break;
2880 } 2881 }
2881 codec->bias_level = level; 2882 codec->dapm.bias_level = level;
2882 return 0; 2883 return 0;
2883} 2884}
2884 2885
@@ -3348,6 +3349,12 @@ static irqreturn_t wm8962_irq(int irq, void *data)
3348 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { 3349 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) {
3349 dev_dbg(codec->dev, "Microphone event detected\n"); 3350 dev_dbg(codec->dev, "Microphone event detected\n");
3350 3351
3352#ifndef CONFIG_SND_SOC_WM8962_MODULE
3353 trace_snd_soc_jack_irq(dev_name(codec->dev));
3354#endif
3355
3356 pm_wakeup_event(codec->dev, 300);
3357
3351 schedule_delayed_work(&wm8962->mic_work, 3358 schedule_delayed_work(&wm8962->mic_work,
3352 msecs_to_jiffies(250)); 3359 msecs_to_jiffies(250));
3353 } 3360 }
@@ -3433,6 +3440,7 @@ static void wm8962_beep_work(struct work_struct *work)
3433 struct wm8962_priv *wm8962 = 3440 struct wm8962_priv *wm8962 =
3434 container_of(work, struct wm8962_priv, beep_work); 3441 container_of(work, struct wm8962_priv, beep_work);
3435 struct snd_soc_codec *codec = wm8962->codec; 3442 struct snd_soc_codec *codec = wm8962->codec;
3443 struct snd_soc_dapm_context *dapm = &codec->dapm;
3436 int i; 3444 int i;
3437 int reg = 0; 3445 int reg = 0;
3438 int best = 0; 3446 int best = 0;
@@ -3449,16 +3457,16 @@ static void wm8962_beep_work(struct work_struct *work)
3449 3457
3450 reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT); 3458 reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT);
3451 3459
3452 snd_soc_dapm_enable_pin(codec, "Beep"); 3460 snd_soc_dapm_enable_pin(dapm, "Beep");
3453 } else { 3461 } else {
3454 dev_dbg(codec->dev, "Disabling beep\n"); 3462 dev_dbg(codec->dev, "Disabling beep\n");
3455 snd_soc_dapm_disable_pin(codec, "Beep"); 3463 snd_soc_dapm_disable_pin(dapm, "Beep");
3456 } 3464 }
3457 3465
3458 snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, 3466 snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1,
3459 WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg); 3467 WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg);
3460 3468
3461 snd_soc_dapm_sync(codec); 3469 snd_soc_dapm_sync(dapm);
3462} 3470}
3463 3471
3464/* For usability define a way of injecting beep events for the device - 3472/* For usability define a way of injecting beep events for the device -
@@ -3706,7 +3714,7 @@ static int wm8962_probe(struct snd_soc_codec *codec)
3706 INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); 3714 INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work);
3707 3715
3708 codec->cache_sync = 1; 3716 codec->cache_sync = 1;
3709 codec->idle_bias_off = 1; 3717 codec->dapm.idle_bias_off = 1;
3710 3718
3711 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); 3719 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C);
3712 if (ret != 0) { 3720 if (ret != 0) {
@@ -3865,7 +3873,6 @@ err_enable:
3865err_get: 3873err_get:
3866 regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); 3874 regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies);
3867err: 3875err:
3868 kfree(wm8962);
3869 return ret; 3876 return ret;
3870} 3877}
3871 3878
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c
index 9f18db6e167c..572bb80627a4 100644
--- a/sound/soc/codecs/wm8971.c
+++ b/sound/soc/codecs/wm8971.c
@@ -25,7 +25,6 @@
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h> 28#include <sound/initval.h>
30 29
31#include "wm8971.h" 30#include "wm8971.h"
@@ -333,10 +332,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
333 332
334static int wm8971_add_widgets(struct snd_soc_codec *codec) 333static int wm8971_add_widgets(struct snd_soc_codec *codec)
335{ 334{
336 snd_soc_dapm_new_controls(codec, wm8971_dapm_widgets, 335 struct snd_soc_dapm_context *dapm = &codec->dapm;
337 ARRAY_SIZE(wm8971_dapm_widgets));
338 336
339 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 337 snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets,
338 ARRAY_SIZE(wm8971_dapm_widgets));
339 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
340 340
341 return 0; 341 return 0;
342} 342}
@@ -553,7 +553,7 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec,
553 snd_soc_write(codec, WM8971_PWR1, 0x0001); 553 snd_soc_write(codec, WM8971_PWR1, 0x0001);
554 break; 554 break;
555 } 555 }
556 codec->bias_level = level; 556 codec->dapm.bias_level = level;
557 return 0; 557 return 0;
558} 558}
559 559
@@ -590,9 +590,11 @@ static struct snd_soc_dai_driver wm8971_dai = {
590 590
591static void wm8971_work(struct work_struct *work) 591static void wm8971_work(struct work_struct *work)
592{ 592{
593 struct snd_soc_codec *codec = 593 struct snd_soc_dapm_context *dapm =
594 container_of(work, struct snd_soc_codec, delayed_work.work); 594 container_of(work, struct snd_soc_dapm_context,
595 wm8971_set_bias_level(codec, codec->bias_level); 595 delayed_work.work);
596 struct snd_soc_codec *codec = dapm->codec;
597 wm8971_set_bias_level(codec, codec->dapm.bias_level);
596} 598}
597 599
598static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state) 600static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state)
@@ -620,11 +622,11 @@ static int wm8971_resume(struct snd_soc_codec *codec)
620 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 622 wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
621 623
622 /* charge wm8971 caps */ 624 /* charge wm8971 caps */
623 if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { 625 if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) {
624 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; 626 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
625 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0); 627 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
626 codec->bias_level = SND_SOC_BIAS_ON; 628 codec->dapm.bias_level = SND_SOC_BIAS_ON;
627 queue_delayed_work(wm8971_workq, &codec->delayed_work, 629 queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
628 msecs_to_jiffies(1000)); 630 msecs_to_jiffies(1000));
629 } 631 }
630 632
@@ -643,7 +645,7 @@ static int wm8971_probe(struct snd_soc_codec *codec)
643 return ret; 645 return ret;
644 } 646 }
645 647
646 INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work); 648 INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work);
647 wm8971_workq = create_workqueue("wm8971"); 649 wm8971_workq = create_workqueue("wm8971");
648 if (wm8971_workq == NULL) 650 if (wm8971_workq == NULL)
649 return -ENOMEM; 651 return -ENOMEM;
@@ -653,8 +655,8 @@ static int wm8971_probe(struct snd_soc_codec *codec)
653 /* charge output caps - set vmid to 5k for quick power up */ 655 /* charge output caps - set vmid to 5k for quick power up */
654 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; 656 reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e;
655 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0); 657 snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0);
656 codec->bias_level = SND_SOC_BIAS_STANDBY; 658 codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
657 queue_delayed_work(wm8971_workq, &codec->delayed_work, 659 queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work,
658 msecs_to_jiffies(1000)); 660 msecs_to_jiffies(1000));
659 661
660 /* set the update bits */ 662 /* set the update bits */
diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c
index b4363f6d19b3..ca646a822444 100644
--- a/sound/soc/codecs/wm8974.c
+++ b/sound/soc/codecs/wm8974.c
@@ -23,7 +23,6 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29 28
@@ -52,7 +51,6 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = {
52 51
53struct wm8974_priv { 52struct wm8974_priv {
54 enum snd_soc_control_type control_type; 53 enum snd_soc_control_type control_type;
55 u16 reg_cache[WM8974_CACHEREGNUM];
56}; 54};
57 55
58#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0) 56#define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0)
@@ -274,10 +272,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
274 272
275static int wm8974_add_widgets(struct snd_soc_codec *codec) 273static int wm8974_add_widgets(struct snd_soc_codec *codec)
276{ 274{
277 snd_soc_dapm_new_controls(codec, wm8974_dapm_widgets, 275 struct snd_soc_dapm_context *dapm = &codec->dapm;
278 ARRAY_SIZE(wm8974_dapm_widgets));
279 276
280 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 277 snd_soc_dapm_new_controls(dapm, wm8974_dapm_widgets,
278 ARRAY_SIZE(wm8974_dapm_widgets));
279 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
281 280
282 return 0; 281 return 0;
283} 282}
@@ -530,7 +529,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
530 case SND_SOC_BIAS_STANDBY: 529 case SND_SOC_BIAS_STANDBY:
531 power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; 530 power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN;
532 531
533 if (codec->bias_level == SND_SOC_BIAS_OFF) { 532 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
534 /* Initial cap charge at VMID 5k */ 533 /* Initial cap charge at VMID 5k */
535 snd_soc_write(codec, WM8974_POWER1, power1 | 0x3); 534 snd_soc_write(codec, WM8974_POWER1, power1 | 0x3);
536 mdelay(100); 535 mdelay(100);
@@ -547,7 +546,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec,
547 break; 546 break;
548 } 547 }
549 548
550 codec->bias_level = level; 549 codec->dapm.bias_level = level;
551 return 0; 550 return 0;
552} 551}
553 552
diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c
index 13b979a71a7c..4bbc3442703f 100644
--- a/sound/soc/codecs/wm8978.c
+++ b/sound/soc/codecs/wm8978.c
@@ -24,7 +24,6 @@
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/tlv.h> 28#include <sound/tlv.h>
30#include <asm/div64.h> 29#include <asm/div64.h>
@@ -60,7 +59,6 @@ struct wm8978_priv {
60 unsigned int f_opclk; 59 unsigned int f_opclk;
61 int mclk_idx; 60 int mclk_idx;
62 enum wm8978_sysclk_src sysclk; 61 enum wm8978_sysclk_src sysclk;
63 u16 reg_cache[WM8978_CACHEREGNUM];
64}; 62};
65 63
66static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"}; 64static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"};
@@ -355,11 +353,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
355 353
356static int wm8978_add_widgets(struct snd_soc_codec *codec) 354static int wm8978_add_widgets(struct snd_soc_codec *codec)
357{ 355{
358 snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets, 356 struct snd_soc_dapm_context *dapm = &codec->dapm;
359 ARRAY_SIZE(wm8978_dapm_widgets));
360 357
358 snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets,
359 ARRAY_SIZE(wm8978_dapm_widgets));
361 /* set up the WM8978 audio map */ 360 /* set up the WM8978 audio map */
362 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 361 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
363 362
364 return 0; 363 return 0;
365} 364}
@@ -837,7 +836,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec,
837 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */ 836 /* bit 3: enable bias, bit 2: enable I/O tie off buffer */
838 power1 |= 0xc; 837 power1 |= 0xc;
839 838
840 if (codec->bias_level == SND_SOC_BIAS_OFF) { 839 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
841 /* Initial cap charge at VMID 5k */ 840 /* Initial cap charge at VMID 5k */
842 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, 841 snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1,
843 power1 | 0x3); 842 power1 | 0x3);
@@ -857,7 +856,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec,
857 856
858 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1); 857 dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1);
859 858
860 codec->bias_level = level; 859 codec->dapm.bias_level = level;
861 return 0; 860 return 0;
862} 861}
863 862
diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c
index fd2e7cca1228..bae510acdec8 100644
--- a/sound/soc/codecs/wm8985.c
+++ b/sound/soc/codecs/wm8985.c
@@ -26,7 +26,6 @@
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/initval.h> 29#include <sound/initval.h>
31#include <sound/tlv.h> 30#include <sound/tlv.h>
32 31
@@ -533,10 +532,11 @@ static int eqmode_put(struct snd_kcontrol *kcontrol,
533 532
534static int wm8985_add_widgets(struct snd_soc_codec *codec) 533static int wm8985_add_widgets(struct snd_soc_codec *codec)
535{ 534{
536 snd_soc_dapm_new_controls(codec, wm8985_dapm_widgets, 535 struct snd_soc_dapm_context *dapm = &codec->dapm;
537 ARRAY_SIZE(wm8985_dapm_widgets));
538 536
539 snd_soc_dapm_add_routes(codec, audio_map, 537 snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets,
538 ARRAY_SIZE(wm8985_dapm_widgets));
539 snd_soc_dapm_add_routes(dapm, audio_map,
540 ARRAY_SIZE(audio_map)); 540 ARRAY_SIZE(audio_map));
541 return 0; 541 return 0;
542} 542}
@@ -879,7 +879,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
879 1 << WM8985_VMIDSEL_SHIFT); 879 1 << WM8985_VMIDSEL_SHIFT);
880 break; 880 break;
881 case SND_SOC_BIAS_STANDBY: 881 case SND_SOC_BIAS_STANDBY:
882 if (codec->bias_level == SND_SOC_BIAS_OFF) { 882 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
883 ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies), 883 ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies),
884 wm8985->supplies); 884 wm8985->supplies);
885 if (ret) { 885 if (ret) {
@@ -939,7 +939,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec,
939 break; 939 break;
940 } 940 }
941 941
942 codec->bias_level = level; 942 codec->dapm.bias_level = level;
943 return 0; 943 return 0;
944} 944}
945 945
diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c
index d7f259711970..d7170f1381aa 100644
--- a/sound/soc/codecs/wm8988.c
+++ b/sound/soc/codecs/wm8988.c
@@ -25,7 +25,6 @@
25#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
26#include <sound/tlv.h> 26#include <sound/tlv.h>
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/initval.h> 28#include <sound/initval.h>
30 29
31#include "wm8988.h" 30#include "wm8988.h"
@@ -54,7 +53,6 @@ struct wm8988_priv {
54 unsigned int sysclk; 53 unsigned int sysclk;
55 enum snd_soc_control_type control_type; 54 enum snd_soc_control_type control_type;
56 struct snd_pcm_hw_constraint_list *sysclk_constraints; 55 struct snd_pcm_hw_constraint_list *sysclk_constraints;
57 u16 reg_cache[WM8988_NUM_REG];
58}; 56};
59 57
60 58
@@ -677,7 +675,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
677 break; 675 break;
678 676
679 case SND_SOC_BIAS_STANDBY: 677 case SND_SOC_BIAS_STANDBY:
680 if (codec->bias_level == SND_SOC_BIAS_OFF) { 678 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
681 /* VREF, VMID=2x5k */ 679 /* VREF, VMID=2x5k */
682 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); 680 snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1);
683 681
@@ -693,7 +691,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec,
693 snd_soc_write(codec, WM8988_PWR1, 0x0000); 691 snd_soc_write(codec, WM8988_PWR1, 0x0000);
694 break; 692 break;
695 } 693 }
696 codec->bias_level = level; 694 codec->dapm.bias_level = level;
697 return 0; 695 return 0;
698} 696}
699 697
@@ -759,6 +757,7 @@ static int wm8988_resume(struct snd_soc_codec *codec)
759static int wm8988_probe(struct snd_soc_codec *codec) 757static int wm8988_probe(struct snd_soc_codec *codec)
760{ 758{
761 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); 759 struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec);
760 struct snd_soc_dapm_context *dapm = &codec->dapm;
762 int ret = 0; 761 int ret = 0;
763 u16 reg; 762 u16 reg;
764 763
@@ -790,9 +789,9 @@ static int wm8988_probe(struct snd_soc_codec *codec)
790 789
791 snd_soc_add_controls(codec, wm8988_snd_controls, 790 snd_soc_add_controls(codec, wm8988_snd_controls,
792 ARRAY_SIZE(wm8988_snd_controls)); 791 ARRAY_SIZE(wm8988_snd_controls));
793 snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets, 792 snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets,
794 ARRAY_SIZE(wm8988_dapm_widgets)); 793 ARRAY_SIZE(wm8988_dapm_widgets));
795 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 794 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
796 795
797 return 0; 796 return 0;
798} 797}
diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c
index 264828e4e67c..5c87a634fc04 100644
--- a/sound/soc/codecs/wm8990.c
+++ b/sound/soc/codecs/wm8990.c
@@ -23,7 +23,6 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29#include <asm/div64.h> 28#include <asm/div64.h>
@@ -914,11 +913,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
914 913
915static int wm8990_add_widgets(struct snd_soc_codec *codec) 914static int wm8990_add_widgets(struct snd_soc_codec *codec)
916{ 915{
917 snd_soc_dapm_new_controls(codec, wm8990_dapm_widgets, 916 struct snd_soc_dapm_context *dapm = &codec->dapm;
918 ARRAY_SIZE(wm8990_dapm_widgets));
919 917
918 snd_soc_dapm_new_controls(dapm, wm8990_dapm_widgets,
919 ARRAY_SIZE(wm8990_dapm_widgets));
920 /* set up the WM8990 audio map */ 920 /* set up the WM8990 audio map */
921 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 921 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
922 922
923 return 0; 923 return 0;
924} 924}
@@ -1170,7 +1170,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1170 break; 1170 break;
1171 1171
1172 case SND_SOC_BIAS_STANDBY: 1172 case SND_SOC_BIAS_STANDBY:
1173 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1173 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1174 /* Enable all output discharge bits */ 1174 /* Enable all output discharge bits */
1175 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | 1175 snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE |
1176 WM8990_DIS_RLINE | WM8990_DIS_OUT3 | 1176 WM8990_DIS_RLINE | WM8990_DIS_OUT3 |
@@ -1266,7 +1266,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec,
1266 break; 1266 break;
1267 } 1267 }
1268 1268
1269 codec->bias_level = level; 1269 codec->dapm.bias_level = level;
1270 return 0; 1270 return 0;
1271} 1271}
1272 1272
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 589e3fa24734..18c0d9ce7c32 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -24,7 +24,6 @@
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/tlv.h> 25#include <sound/tlv.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 27#include <sound/initval.h>
29#include <sound/wm8993.h> 28#include <sound/wm8993.h>
30 29
@@ -226,7 +225,6 @@ static struct {
226 225
227struct wm8993_priv { 226struct wm8993_priv {
228 struct wm_hubs_data hubs_data; 227 struct wm_hubs_data hubs_data;
229 u16 reg_cache[WM8993_REGISTER_COUNT];
230 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; 228 struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES];
231 struct wm8993_platform_data pdata; 229 struct wm8993_platform_data pdata;
232 enum snd_soc_control_type control_type; 230 enum snd_soc_control_type control_type;
@@ -735,6 +733,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol,
735 0); 733 0);
736 } 734 }
737 wm8993->class_w_users++; 735 wm8993->class_w_users++;
736 wm8993->hubs_data.class_w = true;
738 } 737 }
739 738
740 /* Implement the change */ 739 /* Implement the change */
@@ -751,6 +750,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol,
751 WM8993_CP_DYN_V); 750 WM8993_CP_DYN_V);
752 } 751 }
753 wm8993->class_w_users--; 752 wm8993->class_w_users--;
753 wm8993->hubs_data.class_w = false;
754 } 754 }
755 755
756 dev_dbg(codec->dev, "Indirect DAC use count now %d\n", 756 dev_dbg(codec->dev, "Indirect DAC use count now %d\n",
@@ -968,7 +968,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
968 break; 968 break;
969 969
970 case SND_SOC_BIAS_STANDBY: 970 case SND_SOC_BIAS_STANDBY:
971 if (codec->bias_level == SND_SOC_BIAS_OFF) { 971 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
972 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), 972 ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies),
973 wm8993->supplies); 973 wm8993->supplies);
974 if (ret != 0) 974 if (ret != 0)
@@ -1029,6 +1029,12 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1029 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, 1029 WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA,
1030 0); 1030 0);
1031 1031
1032 snd_soc_update_bits(codec, WM8993_ANTIPOP2,
1033 WM8993_STARTUP_BIAS_ENA |
1034 WM8993_VMID_BUF_ENA |
1035 WM8993_VMID_RAMP_MASK |
1036 WM8993_BIAS_SRC, 0);
1037
1032#ifdef CONFIG_REGULATOR 1038#ifdef CONFIG_REGULATOR
1033 /* Post 2.6.34 we will be able to get a callback when 1039 /* Post 2.6.34 we will be able to get a callback when
1034 * the regulators are disabled which we can use but 1040 * the regulators are disabled which we can use but
@@ -1043,7 +1049,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec,
1043 break; 1049 break;
1044 } 1050 }
1045 1051
1046 codec->bias_level = level; 1052 codec->dapm.bias_level = level;
1047 1053
1048 return 0; 1054 return 0;
1049} 1055}
@@ -1225,7 +1231,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream,
1225 - wm8993->fs); 1231 - wm8993->fs);
1226 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { 1232 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) {
1227 cur_val = abs((wm8993->sysclk_rate / 1233 cur_val = abs((wm8993->sysclk_rate /
1228 clk_sys_rates[i].ratio) - wm8993->fs);; 1234 clk_sys_rates[i].ratio) - wm8993->fs);
1229 if (cur_val < best_val) { 1235 if (cur_val < best_val) {
1230 best = i; 1236 best = i;
1231 best_val = cur_val; 1237 best_val = cur_val;
@@ -1422,6 +1428,7 @@ static struct snd_soc_dai_driver wm8993_dai = {
1422static int wm8993_probe(struct snd_soc_codec *codec) 1428static int wm8993_probe(struct snd_soc_codec *codec)
1423{ 1429{
1424 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); 1430 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec);
1431 struct snd_soc_dapm_context *dapm = &codec->dapm;
1425 int ret, i, val; 1432 int ret, i, val;
1426 1433
1427 wm8993->hubs_data.hp_startup_mode = 1; 1434 wm8993->hubs_data.hp_startup_mode = 1;
@@ -1503,11 +1510,11 @@ static int wm8993_probe(struct snd_soc_codec *codec)
1503 ARRAY_SIZE(wm8993_eq_controls)); 1510 ARRAY_SIZE(wm8993_eq_controls));
1504 } 1511 }
1505 1512
1506 snd_soc_dapm_new_controls(codec, wm8993_dapm_widgets, 1513 snd_soc_dapm_new_controls(dapm, wm8993_dapm_widgets,
1507 ARRAY_SIZE(wm8993_dapm_widgets)); 1514 ARRAY_SIZE(wm8993_dapm_widgets));
1508 wm_hubs_add_analogue_controls(codec); 1515 wm_hubs_add_analogue_controls(codec);
1509 1516
1510 snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); 1517 snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));
1511 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, 1518 wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff,
1512 wm8993->pdata.lineout2_diff); 1519 wm8993->pdata.lineout2_diff);
1513 1520
diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c
new file mode 100644
index 000000000000..68e9b024dd48
--- /dev/null
+++ b/sound/soc/codecs/wm8994-tables.c
@@ -0,0 +1,3147 @@
1#include "wm8994.h"
2
3const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = {
4 { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */
5 { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */
6 { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */
7 { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */
8 { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */
9 { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */
10 { 0x003F, 0x003F }, /* R6 - Power Management (6) */
11 { 0x0000, 0x0000 }, /* R7 */
12 { 0x0000, 0x0000 }, /* R8 */
13 { 0x0000, 0x0000 }, /* R9 */
14 { 0x0000, 0x0000 }, /* R10 */
15 { 0x0000, 0x0000 }, /* R11 */
16 { 0x0000, 0x0000 }, /* R12 */
17 { 0x0000, 0x0000 }, /* R13 */
18 { 0x0000, 0x0000 }, /* R14 */
19 { 0x0000, 0x0000 }, /* R15 */
20 { 0x0000, 0x0000 }, /* R16 */
21 { 0x0000, 0x0000 }, /* R17 */
22 { 0x0000, 0x0000 }, /* R18 */
23 { 0x0000, 0x0000 }, /* R19 */
24 { 0x0000, 0x0000 }, /* R20 */
25 { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */
26 { 0x0000, 0x0000 }, /* R22 */
27 { 0x0000, 0x0000 }, /* R23 */
28 { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */
29 { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */
30 { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */
31 { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */
32 { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */
33 { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */
34 { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */
35 { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */
36 { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */
37 { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */
38 { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */
39 { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */
40 { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */
41 { 0x003F, 0x003F }, /* R37 - ClassD */
42 { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */
43 { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */
44 { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */
45 { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */
46 { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */
47 { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */
48 { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */
49 { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */
50 { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */
51 { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */
52 { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */
53 { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */
54 { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */
55 { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */
56 { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */
57 { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */
58 { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */
59 { 0x00C1, 0x00C1 }, /* R55 - Additional Control */
60 { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */
61 { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */
62 { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
63 { 0x000F, 0x000F }, /* R59 - LDO 1 */
64 { 0x0007, 0x0007 }, /* R60 - LDO 2 */
65 { 0x0000, 0x0000 }, /* R61 */
66 { 0x0000, 0x0000 }, /* R62 */
67 { 0x0000, 0x0000 }, /* R63 */
68 { 0x0000, 0x0000 }, /* R64 */
69 { 0x0000, 0x0000 }, /* R65 */
70 { 0x0000, 0x0000 }, /* R66 */
71 { 0x0000, 0x0000 }, /* R67 */
72 { 0x0000, 0x0000 }, /* R68 */
73 { 0x0000, 0x0000 }, /* R69 */
74 { 0x0000, 0x0000 }, /* R70 */
75 { 0x0000, 0x0000 }, /* R71 */
76 { 0x0000, 0x0000 }, /* R72 */
77 { 0x0000, 0x0000 }, /* R73 */
78 { 0x0000, 0x0000 }, /* R74 */
79 { 0x0000, 0x0000 }, /* R75 */
80 { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */
81 { 0x0000, 0x0000 }, /* R77 */
82 { 0x0000, 0x0000 }, /* R78 */
83 { 0x0000, 0x0000 }, /* R79 */
84 { 0x0000, 0x0000 }, /* R80 */
85 { 0x0301, 0x0301 }, /* R81 - Class W (1) */
86 { 0x0000, 0x0000 }, /* R82 */
87 { 0x0000, 0x0000 }, /* R83 */
88 { 0x333F, 0x333F }, /* R84 - DC Servo (1) */
89 { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */
90 { 0x0000, 0x0000 }, /* R86 */
91 { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */
92 { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */
93 { 0x0000, 0x0000 }, /* R89 */
94 { 0x0000, 0x0000 }, /* R90 */
95 { 0x0000, 0x0000 }, /* R91 */
96 { 0x0000, 0x0000 }, /* R92 */
97 { 0x0000, 0x0000 }, /* R93 */
98 { 0x0000, 0x0000 }, /* R94 */
99 { 0x0000, 0x0000 }, /* R95 */
100 { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */
101 { 0x0000, 0x0000 }, /* R97 */
102 { 0x0000, 0x0000 }, /* R98 */
103 { 0x0000, 0x0000 }, /* R99 */
104 { 0x0000, 0x0000 }, /* R100 */
105 { 0x0000, 0x0000 }, /* R101 */
106 { 0x0000, 0x0000 }, /* R102 */
107 { 0x0000, 0x0000 }, /* R103 */
108 { 0x0000, 0x0000 }, /* R104 */
109 { 0x0000, 0x0000 }, /* R105 */
110 { 0x0000, 0x0000 }, /* R106 */
111 { 0x0000, 0x0000 }, /* R107 */
112 { 0x0000, 0x0000 }, /* R108 */
113 { 0x0000, 0x0000 }, /* R109 */
114 { 0x0000, 0x0000 }, /* R110 */
115 { 0x0000, 0x0000 }, /* R111 */
116 { 0x0000, 0x0000 }, /* R112 */
117 { 0x0000, 0x0000 }, /* R113 */
118 { 0x0000, 0x0000 }, /* R114 */
119 { 0x0000, 0x0000 }, /* R115 */
120 { 0x0000, 0x0000 }, /* R116 */
121 { 0x0000, 0x0000 }, /* R117 */
122 { 0x0000, 0x0000 }, /* R118 */
123 { 0x0000, 0x0000 }, /* R119 */
124 { 0x0000, 0x0000 }, /* R120 */
125 { 0x0000, 0x0000 }, /* R121 */
126 { 0x0000, 0x0000 }, /* R122 */
127 { 0x0000, 0x0000 }, /* R123 */
128 { 0x0000, 0x0000 }, /* R124 */
129 { 0x0000, 0x0000 }, /* R125 */
130 { 0x0000, 0x0000 }, /* R126 */
131 { 0x0000, 0x0000 }, /* R127 */
132 { 0x0000, 0x0000 }, /* R128 */
133 { 0x0000, 0x0000 }, /* R129 */
134 { 0x0000, 0x0000 }, /* R130 */
135 { 0x0000, 0x0000 }, /* R131 */
136 { 0x0000, 0x0000 }, /* R132 */
137 { 0x0000, 0x0000 }, /* R133 */
138 { 0x0000, 0x0000 }, /* R134 */
139 { 0x0000, 0x0000 }, /* R135 */
140 { 0x0000, 0x0000 }, /* R136 */
141 { 0x0000, 0x0000 }, /* R137 */
142 { 0x0000, 0x0000 }, /* R138 */
143 { 0x0000, 0x0000 }, /* R139 */
144 { 0x0000, 0x0000 }, /* R140 */
145 { 0x0000, 0x0000 }, /* R141 */
146 { 0x0000, 0x0000 }, /* R142 */
147 { 0x0000, 0x0000 }, /* R143 */
148 { 0x0000, 0x0000 }, /* R144 */
149 { 0x0000, 0x0000 }, /* R145 */
150 { 0x0000, 0x0000 }, /* R146 */
151 { 0x0000, 0x0000 }, /* R147 */
152 { 0x0000, 0x0000 }, /* R148 */
153 { 0x0000, 0x0000 }, /* R149 */
154 { 0x0000, 0x0000 }, /* R150 */
155 { 0x0000, 0x0000 }, /* R151 */
156 { 0x0000, 0x0000 }, /* R152 */
157 { 0x0000, 0x0000 }, /* R153 */
158 { 0x0000, 0x0000 }, /* R154 */
159 { 0x0000, 0x0000 }, /* R155 */
160 { 0x0000, 0x0000 }, /* R156 */
161 { 0x0000, 0x0000 }, /* R157 */
162 { 0x0000, 0x0000 }, /* R158 */
163 { 0x0000, 0x0000 }, /* R159 */
164 { 0x0000, 0x0000 }, /* R160 */
165 { 0x0000, 0x0000 }, /* R161 */
166 { 0x0000, 0x0000 }, /* R162 */
167 { 0x0000, 0x0000 }, /* R163 */
168 { 0x0000, 0x0000 }, /* R164 */
169 { 0x0000, 0x0000 }, /* R165 */
170 { 0x0000, 0x0000 }, /* R166 */
171 { 0x0000, 0x0000 }, /* R167 */
172 { 0x0000, 0x0000 }, /* R168 */
173 { 0x0000, 0x0000 }, /* R169 */
174 { 0x0000, 0x0000 }, /* R170 */
175 { 0x0000, 0x0000 }, /* R171 */
176 { 0x0000, 0x0000 }, /* R172 */
177 { 0x0000, 0x0000 }, /* R173 */
178 { 0x0000, 0x0000 }, /* R174 */
179 { 0x0000, 0x0000 }, /* R175 */
180 { 0x0000, 0x0000 }, /* R176 */
181 { 0x0000, 0x0000 }, /* R177 */
182 { 0x0000, 0x0000 }, /* R178 */
183 { 0x0000, 0x0000 }, /* R179 */
184 { 0x0000, 0x0000 }, /* R180 */
185 { 0x0000, 0x0000 }, /* R181 */
186 { 0x0000, 0x0000 }, /* R182 */
187 { 0x0000, 0x0000 }, /* R183 */
188 { 0x0000, 0x0000 }, /* R184 */
189 { 0x0000, 0x0000 }, /* R185 */
190 { 0x0000, 0x0000 }, /* R186 */
191 { 0x0000, 0x0000 }, /* R187 */
192 { 0x0000, 0x0000 }, /* R188 */
193 { 0x0000, 0x0000 }, /* R189 */
194 { 0x0000, 0x0000 }, /* R190 */
195 { 0x0000, 0x0000 }, /* R191 */
196 { 0x0000, 0x0000 }, /* R192 */
197 { 0x0000, 0x0000 }, /* R193 */
198 { 0x0000, 0x0000 }, /* R194 */
199 { 0x0000, 0x0000 }, /* R195 */
200 { 0x0000, 0x0000 }, /* R196 */
201 { 0x0000, 0x0000 }, /* R197 */
202 { 0x0000, 0x0000 }, /* R198 */
203 { 0x0000, 0x0000 }, /* R199 */
204 { 0x0000, 0x0000 }, /* R200 */
205 { 0x0000, 0x0000 }, /* R201 */
206 { 0x0000, 0x0000 }, /* R202 */
207 { 0x0000, 0x0000 }, /* R203 */
208 { 0x0000, 0x0000 }, /* R204 */
209 { 0x0000, 0x0000 }, /* R205 */
210 { 0x0000, 0x0000 }, /* R206 */
211 { 0x0000, 0x0000 }, /* R207 */
212 { 0x0000, 0x0000 }, /* R208 */
213 { 0x0000, 0x0000 }, /* R209 */
214 { 0x0000, 0x0000 }, /* R210 */
215 { 0x0000, 0x0000 }, /* R211 */
216 { 0x0000, 0x0000 }, /* R212 */
217 { 0x0000, 0x0000 }, /* R213 */
218 { 0x0000, 0x0000 }, /* R214 */
219 { 0x0000, 0x0000 }, /* R215 */
220 { 0x0000, 0x0000 }, /* R216 */
221 { 0x0000, 0x0000 }, /* R217 */
222 { 0x0000, 0x0000 }, /* R218 */
223 { 0x0000, 0x0000 }, /* R219 */
224 { 0x0000, 0x0000 }, /* R220 */
225 { 0x0000, 0x0000 }, /* R221 */
226 { 0x0000, 0x0000 }, /* R222 */
227 { 0x0000, 0x0000 }, /* R223 */
228 { 0x0000, 0x0000 }, /* R224 */
229 { 0x0000, 0x0000 }, /* R225 */
230 { 0x0000, 0x0000 }, /* R226 */
231 { 0x0000, 0x0000 }, /* R227 */
232 { 0x0000, 0x0000 }, /* R228 */
233 { 0x0000, 0x0000 }, /* R229 */
234 { 0x0000, 0x0000 }, /* R230 */
235 { 0x0000, 0x0000 }, /* R231 */
236 { 0x0000, 0x0000 }, /* R232 */
237 { 0x0000, 0x0000 }, /* R233 */
238 { 0x0000, 0x0000 }, /* R234 */
239 { 0x0000, 0x0000 }, /* R235 */
240 { 0x0000, 0x0000 }, /* R236 */
241 { 0x0000, 0x0000 }, /* R237 */
242 { 0x0000, 0x0000 }, /* R238 */
243 { 0x0000, 0x0000 }, /* R239 */
244 { 0x0000, 0x0000 }, /* R240 */
245 { 0x0000, 0x0000 }, /* R241 */
246 { 0x0000, 0x0000 }, /* R242 */
247 { 0x0000, 0x0000 }, /* R243 */
248 { 0x0000, 0x0000 }, /* R244 */
249 { 0x0000, 0x0000 }, /* R245 */
250 { 0x0000, 0x0000 }, /* R246 */
251 { 0x0000, 0x0000 }, /* R247 */
252 { 0x0000, 0x0000 }, /* R248 */
253 { 0x0000, 0x0000 }, /* R249 */
254 { 0x0000, 0x0000 }, /* R250 */
255 { 0x0000, 0x0000 }, /* R251 */
256 { 0x0000, 0x0000 }, /* R252 */
257 { 0x0000, 0x0000 }, /* R253 */
258 { 0x0000, 0x0000 }, /* R254 */
259 { 0x0000, 0x0000 }, /* R255 */
260 { 0x000F, 0x0000 }, /* R256 - Chip Revision */
261 { 0x0074, 0x0074 }, /* R257 - Control Interface */
262 { 0x0000, 0x0000 }, /* R258 */
263 { 0x0000, 0x0000 }, /* R259 */
264 { 0x0000, 0x0000 }, /* R260 */
265 { 0x0000, 0x0000 }, /* R261 */
266 { 0x0000, 0x0000 }, /* R262 */
267 { 0x0000, 0x0000 }, /* R263 */
268 { 0x0000, 0x0000 }, /* R264 */
269 { 0x0000, 0x0000 }, /* R265 */
270 { 0x0000, 0x0000 }, /* R266 */
271 { 0x0000, 0x0000 }, /* R267 */
272 { 0x0000, 0x0000 }, /* R268 */
273 { 0x0000, 0x0000 }, /* R269 */
274 { 0x0000, 0x0000 }, /* R270 */
275 { 0x0000, 0x0000 }, /* R271 */
276 { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */
277 { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
278 { 0x0000, 0x0000 }, /* R274 */
279 { 0x0000, 0x0000 }, /* R275 */
280 { 0x0000, 0x0000 }, /* R276 */
281 { 0x0000, 0x0000 }, /* R277 */
282 { 0x0000, 0x0000 }, /* R278 */
283 { 0x0000, 0x0000 }, /* R279 */
284 { 0x0000, 0x0000 }, /* R280 */
285 { 0x0000, 0x0000 }, /* R281 */
286 { 0x0000, 0x0000 }, /* R282 */
287 { 0x0000, 0x0000 }, /* R283 */
288 { 0x0000, 0x0000 }, /* R284 */
289 { 0x0000, 0x0000 }, /* R285 */
290 { 0x0000, 0x0000 }, /* R286 */
291 { 0x0000, 0x0000 }, /* R287 */
292 { 0x0000, 0x0000 }, /* R288 */
293 { 0x0000, 0x0000 }, /* R289 */
294 { 0x0000, 0x0000 }, /* R290 */
295 { 0x0000, 0x0000 }, /* R291 */
296 { 0x0000, 0x0000 }, /* R292 */
297 { 0x0000, 0x0000 }, /* R293 */
298 { 0x0000, 0x0000 }, /* R294 */
299 { 0x0000, 0x0000 }, /* R295 */
300 { 0x0000, 0x0000 }, /* R296 */
301 { 0x0000, 0x0000 }, /* R297 */
302 { 0x0000, 0x0000 }, /* R298 */
303 { 0x0000, 0x0000 }, /* R299 */
304 { 0x0000, 0x0000 }, /* R300 */
305 { 0x0000, 0x0000 }, /* R301 */
306 { 0x0000, 0x0000 }, /* R302 */
307 { 0x0000, 0x0000 }, /* R303 */
308 { 0x0000, 0x0000 }, /* R304 */
309 { 0x0000, 0x0000 }, /* R305 */
310 { 0x0000, 0x0000 }, /* R306 */
311 { 0x0000, 0x0000 }, /* R307 */
312 { 0x0000, 0x0000 }, /* R308 */
313 { 0x0000, 0x0000 }, /* R309 */
314 { 0x0000, 0x0000 }, /* R310 */
315 { 0x0000, 0x0000 }, /* R311 */
316 { 0x0000, 0x0000 }, /* R312 */
317 { 0x0000, 0x0000 }, /* R313 */
318 { 0x0000, 0x0000 }, /* R314 */
319 { 0x0000, 0x0000 }, /* R315 */
320 { 0x0000, 0x0000 }, /* R316 */
321 { 0x0000, 0x0000 }, /* R317 */
322 { 0x0000, 0x0000 }, /* R318 */
323 { 0x0000, 0x0000 }, /* R319 */
324 { 0x0000, 0x0000 }, /* R320 */
325 { 0x0000, 0x0000 }, /* R321 */
326 { 0x0000, 0x0000 }, /* R322 */
327 { 0x0000, 0x0000 }, /* R323 */
328 { 0x0000, 0x0000 }, /* R324 */
329 { 0x0000, 0x0000 }, /* R325 */
330 { 0x0000, 0x0000 }, /* R326 */
331 { 0x0000, 0x0000 }, /* R327 */
332 { 0x0000, 0x0000 }, /* R328 */
333 { 0x0000, 0x0000 }, /* R329 */
334 { 0x0000, 0x0000 }, /* R330 */
335 { 0x0000, 0x0000 }, /* R331 */
336 { 0x0000, 0x0000 }, /* R332 */
337 { 0x0000, 0x0000 }, /* R333 */
338 { 0x0000, 0x0000 }, /* R334 */
339 { 0x0000, 0x0000 }, /* R335 */
340 { 0x0000, 0x0000 }, /* R336 */
341 { 0x0000, 0x0000 }, /* R337 */
342 { 0x0000, 0x0000 }, /* R338 */
343 { 0x0000, 0x0000 }, /* R339 */
344 { 0x0000, 0x0000 }, /* R340 */
345 { 0x0000, 0x0000 }, /* R341 */
346 { 0x0000, 0x0000 }, /* R342 */
347 { 0x0000, 0x0000 }, /* R343 */
348 { 0x0000, 0x0000 }, /* R344 */
349 { 0x0000, 0x0000 }, /* R345 */
350 { 0x0000, 0x0000 }, /* R346 */
351 { 0x0000, 0x0000 }, /* R347 */
352 { 0x0000, 0x0000 }, /* R348 */
353 { 0x0000, 0x0000 }, /* R349 */
354 { 0x0000, 0x0000 }, /* R350 */
355 { 0x0000, 0x0000 }, /* R351 */
356 { 0x0000, 0x0000 }, /* R352 */
357 { 0x0000, 0x0000 }, /* R353 */
358 { 0x0000, 0x0000 }, /* R354 */
359 { 0x0000, 0x0000 }, /* R355 */
360 { 0x0000, 0x0000 }, /* R356 */
361 { 0x0000, 0x0000 }, /* R357 */
362 { 0x0000, 0x0000 }, /* R358 */
363 { 0x0000, 0x0000 }, /* R359 */
364 { 0x0000, 0x0000 }, /* R360 */
365 { 0x0000, 0x0000 }, /* R361 */
366 { 0x0000, 0x0000 }, /* R362 */
367 { 0x0000, 0x0000 }, /* R363 */
368 { 0x0000, 0x0000 }, /* R364 */
369 { 0x0000, 0x0000 }, /* R365 */
370 { 0x0000, 0x0000 }, /* R366 */
371 { 0x0000, 0x0000 }, /* R367 */
372 { 0x0000, 0x0000 }, /* R368 */
373 { 0x0000, 0x0000 }, /* R369 */
374 { 0x0000, 0x0000 }, /* R370 */
375 { 0x0000, 0x0000 }, /* R371 */
376 { 0x0000, 0x0000 }, /* R372 */
377 { 0x0000, 0x0000 }, /* R373 */
378 { 0x0000, 0x0000 }, /* R374 */
379 { 0x0000, 0x0000 }, /* R375 */
380 { 0x0000, 0x0000 }, /* R376 */
381 { 0x0000, 0x0000 }, /* R377 */
382 { 0x0000, 0x0000 }, /* R378 */
383 { 0x0000, 0x0000 }, /* R379 */
384 { 0x0000, 0x0000 }, /* R380 */
385 { 0x0000, 0x0000 }, /* R381 */
386 { 0x0000, 0x0000 }, /* R382 */
387 { 0x0000, 0x0000 }, /* R383 */
388 { 0x0000, 0x0000 }, /* R384 */
389 { 0x0000, 0x0000 }, /* R385 */
390 { 0x0000, 0x0000 }, /* R386 */
391 { 0x0000, 0x0000 }, /* R387 */
392 { 0x0000, 0x0000 }, /* R388 */
393 { 0x0000, 0x0000 }, /* R389 */
394 { 0x0000, 0x0000 }, /* R390 */
395 { 0x0000, 0x0000 }, /* R391 */
396 { 0x0000, 0x0000 }, /* R392 */
397 { 0x0000, 0x0000 }, /* R393 */
398 { 0x0000, 0x0000 }, /* R394 */
399 { 0x0000, 0x0000 }, /* R395 */
400 { 0x0000, 0x0000 }, /* R396 */
401 { 0x0000, 0x0000 }, /* R397 */
402 { 0x0000, 0x0000 }, /* R398 */
403 { 0x0000, 0x0000 }, /* R399 */
404 { 0x0000, 0x0000 }, /* R400 */
405 { 0x0000, 0x0000 }, /* R401 */
406 { 0x0000, 0x0000 }, /* R402 */
407 { 0x0000, 0x0000 }, /* R403 */
408 { 0x0000, 0x0000 }, /* R404 */
409 { 0x0000, 0x0000 }, /* R405 */
410 { 0x0000, 0x0000 }, /* R406 */
411 { 0x0000, 0x0000 }, /* R407 */
412 { 0x0000, 0x0000 }, /* R408 */
413 { 0x0000, 0x0000 }, /* R409 */
414 { 0x0000, 0x0000 }, /* R410 */
415 { 0x0000, 0x0000 }, /* R411 */
416 { 0x0000, 0x0000 }, /* R412 */
417 { 0x0000, 0x0000 }, /* R413 */
418 { 0x0000, 0x0000 }, /* R414 */
419 { 0x0000, 0x0000 }, /* R415 */
420 { 0x0000, 0x0000 }, /* R416 */
421 { 0x0000, 0x0000 }, /* R417 */
422 { 0x0000, 0x0000 }, /* R418 */
423 { 0x0000, 0x0000 }, /* R419 */
424 { 0x0000, 0x0000 }, /* R420 */
425 { 0x0000, 0x0000 }, /* R421 */
426 { 0x0000, 0x0000 }, /* R422 */
427 { 0x0000, 0x0000 }, /* R423 */
428 { 0x0000, 0x0000 }, /* R424 */
429 { 0x0000, 0x0000 }, /* R425 */
430 { 0x0000, 0x0000 }, /* R426 */
431 { 0x0000, 0x0000 }, /* R427 */
432 { 0x0000, 0x0000 }, /* R428 */
433 { 0x0000, 0x0000 }, /* R429 */
434 { 0x0000, 0x0000 }, /* R430 */
435 { 0x0000, 0x0000 }, /* R431 */
436 { 0x0000, 0x0000 }, /* R432 */
437 { 0x0000, 0x0000 }, /* R433 */
438 { 0x0000, 0x0000 }, /* R434 */
439 { 0x0000, 0x0000 }, /* R435 */
440 { 0x0000, 0x0000 }, /* R436 */
441 { 0x0000, 0x0000 }, /* R437 */
442 { 0x0000, 0x0000 }, /* R438 */
443 { 0x0000, 0x0000 }, /* R439 */
444 { 0x0000, 0x0000 }, /* R440 */
445 { 0x0000, 0x0000 }, /* R441 */
446 { 0x0000, 0x0000 }, /* R442 */
447 { 0x0000, 0x0000 }, /* R443 */
448 { 0x0000, 0x0000 }, /* R444 */
449 { 0x0000, 0x0000 }, /* R445 */
450 { 0x0000, 0x0000 }, /* R446 */
451 { 0x0000, 0x0000 }, /* R447 */
452 { 0x0000, 0x0000 }, /* R448 */
453 { 0x0000, 0x0000 }, /* R449 */
454 { 0x0000, 0x0000 }, /* R450 */
455 { 0x0000, 0x0000 }, /* R451 */
456 { 0x0000, 0x0000 }, /* R452 */
457 { 0x0000, 0x0000 }, /* R453 */
458 { 0x0000, 0x0000 }, /* R454 */
459 { 0x0000, 0x0000 }, /* R455 */
460 { 0x0000, 0x0000 }, /* R456 */
461 { 0x0000, 0x0000 }, /* R457 */
462 { 0x0000, 0x0000 }, /* R458 */
463 { 0x0000, 0x0000 }, /* R459 */
464 { 0x0000, 0x0000 }, /* R460 */
465 { 0x0000, 0x0000 }, /* R461 */
466 { 0x0000, 0x0000 }, /* R462 */
467 { 0x0000, 0x0000 }, /* R463 */
468 { 0x0000, 0x0000 }, /* R464 */
469 { 0x0000, 0x0000 }, /* R465 */
470 { 0x0000, 0x0000 }, /* R466 */
471 { 0x0000, 0x0000 }, /* R467 */
472 { 0x0000, 0x0000 }, /* R468 */
473 { 0x0000, 0x0000 }, /* R469 */
474 { 0x0000, 0x0000 }, /* R470 */
475 { 0x0000, 0x0000 }, /* R471 */
476 { 0x0000, 0x0000 }, /* R472 */
477 { 0x0000, 0x0000 }, /* R473 */
478 { 0x0000, 0x0000 }, /* R474 */
479 { 0x0000, 0x0000 }, /* R475 */
480 { 0x0000, 0x0000 }, /* R476 */
481 { 0x0000, 0x0000 }, /* R477 */
482 { 0x0000, 0x0000 }, /* R478 */
483 { 0x0000, 0x0000 }, /* R479 */
484 { 0x0000, 0x0000 }, /* R480 */
485 { 0x0000, 0x0000 }, /* R481 */
486 { 0x0000, 0x0000 }, /* R482 */
487 { 0x0000, 0x0000 }, /* R483 */
488 { 0x0000, 0x0000 }, /* R484 */
489 { 0x0000, 0x0000 }, /* R485 */
490 { 0x0000, 0x0000 }, /* R486 */
491 { 0x0000, 0x0000 }, /* R487 */
492 { 0x0000, 0x0000 }, /* R488 */
493 { 0x0000, 0x0000 }, /* R489 */
494 { 0x0000, 0x0000 }, /* R490 */
495 { 0x0000, 0x0000 }, /* R491 */
496 { 0x0000, 0x0000 }, /* R492 */
497 { 0x0000, 0x0000 }, /* R493 */
498 { 0x0000, 0x0000 }, /* R494 */
499 { 0x0000, 0x0000 }, /* R495 */
500 { 0x0000, 0x0000 }, /* R496 */
501 { 0x0000, 0x0000 }, /* R497 */
502 { 0x0000, 0x0000 }, /* R498 */
503 { 0x0000, 0x0000 }, /* R499 */
504 { 0x0000, 0x0000 }, /* R500 */
505 { 0x0000, 0x0000 }, /* R501 */
506 { 0x0000, 0x0000 }, /* R502 */
507 { 0x0000, 0x0000 }, /* R503 */
508 { 0x0000, 0x0000 }, /* R504 */
509 { 0x0000, 0x0000 }, /* R505 */
510 { 0x0000, 0x0000 }, /* R506 */
511 { 0x0000, 0x0000 }, /* R507 */
512 { 0x0000, 0x0000 }, /* R508 */
513 { 0x0000, 0x0000 }, /* R509 */
514 { 0x0000, 0x0000 }, /* R510 */
515 { 0x0000, 0x0000 }, /* R511 */
516 { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */
517 { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */
518 { 0x0000, 0x0000 }, /* R514 */
519 { 0x0000, 0x0000 }, /* R515 */
520 { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */
521 { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */
522 { 0x0000, 0x0000 }, /* R518 */
523 { 0x0000, 0x0000 }, /* R519 */
524 { 0x001F, 0x001F }, /* R520 - Clocking (1) */
525 { 0x0777, 0x0777 }, /* R521 - Clocking (2) */
526 { 0x0000, 0x0000 }, /* R522 */
527 { 0x0000, 0x0000 }, /* R523 */
528 { 0x0000, 0x0000 }, /* R524 */
529 { 0x0000, 0x0000 }, /* R525 */
530 { 0x0000, 0x0000 }, /* R526 */
531 { 0x0000, 0x0000 }, /* R527 */
532 { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */
533 { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */
534 { 0x000F, 0x0000 }, /* R530 - Rate Status */
535 { 0x0000, 0x0000 }, /* R531 */
536 { 0x0000, 0x0000 }, /* R532 */
537 { 0x0000, 0x0000 }, /* R533 */
538 { 0x0000, 0x0000 }, /* R534 */
539 { 0x0000, 0x0000 }, /* R535 */
540 { 0x0000, 0x0000 }, /* R536 */
541 { 0x0000, 0x0000 }, /* R537 */
542 { 0x0000, 0x0000 }, /* R538 */
543 { 0x0000, 0x0000 }, /* R539 */
544 { 0x0000, 0x0000 }, /* R540 */
545 { 0x0000, 0x0000 }, /* R541 */
546 { 0x0000, 0x0000 }, /* R542 */
547 { 0x0000, 0x0000 }, /* R543 */
548 { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */
549 { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */
550 { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */
551 { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */
552 { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */
553 { 0x0000, 0x0000 }, /* R549 */
554 { 0x0000, 0x0000 }, /* R550 */
555 { 0x0000, 0x0000 }, /* R551 */
556 { 0x0000, 0x0000 }, /* R552 */
557 { 0x0000, 0x0000 }, /* R553 */
558 { 0x0000, 0x0000 }, /* R554 */
559 { 0x0000, 0x0000 }, /* R555 */
560 { 0x0000, 0x0000 }, /* R556 */
561 { 0x0000, 0x0000 }, /* R557 */
562 { 0x0000, 0x0000 }, /* R558 */
563 { 0x0000, 0x0000 }, /* R559 */
564 { 0x0000, 0x0000 }, /* R560 */
565 { 0x0000, 0x0000 }, /* R561 */
566 { 0x0000, 0x0000 }, /* R562 */
567 { 0x0000, 0x0000 }, /* R563 */
568 { 0x0000, 0x0000 }, /* R564 */
569 { 0x0000, 0x0000 }, /* R565 */
570 { 0x0000, 0x0000 }, /* R566 */
571 { 0x0000, 0x0000 }, /* R567 */
572 { 0x0000, 0x0000 }, /* R568 */
573 { 0x0000, 0x0000 }, /* R569 */
574 { 0x0000, 0x0000 }, /* R570 */
575 { 0x0000, 0x0000 }, /* R571 */
576 { 0x0000, 0x0000 }, /* R572 */
577 { 0x0000, 0x0000 }, /* R573 */
578 { 0x0000, 0x0000 }, /* R574 */
579 { 0x0000, 0x0000 }, /* R575 */
580 { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */
581 { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */
582 { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */
583 { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */
584 { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */
585 { 0x0000, 0x0000 }, /* R581 */
586 { 0x0000, 0x0000 }, /* R582 */
587 { 0x0000, 0x0000 }, /* R583 */
588 { 0x0000, 0x0000 }, /* R584 */
589 { 0x0000, 0x0000 }, /* R585 */
590 { 0x0000, 0x0000 }, /* R586 */
591 { 0x0000, 0x0000 }, /* R587 */
592 { 0x0000, 0x0000 }, /* R588 */
593 { 0x0000, 0x0000 }, /* R589 */
594 { 0x0000, 0x0000 }, /* R590 */
595 { 0x0000, 0x0000 }, /* R591 */
596 { 0x0000, 0x0000 }, /* R592 */
597 { 0x0000, 0x0000 }, /* R593 */
598 { 0x0000, 0x0000 }, /* R594 */
599 { 0x0000, 0x0000 }, /* R595 */
600 { 0x0000, 0x0000 }, /* R596 */
601 { 0x0000, 0x0000 }, /* R597 */
602 { 0x0000, 0x0000 }, /* R598 */
603 { 0x0000, 0x0000 }, /* R599 */
604 { 0x0000, 0x0000 }, /* R600 */
605 { 0x0000, 0x0000 }, /* R601 */
606 { 0x0000, 0x0000 }, /* R602 */
607 { 0x0000, 0x0000 }, /* R603 */
608 { 0x0000, 0x0000 }, /* R604 */
609 { 0x0000, 0x0000 }, /* R605 */
610 { 0x0000, 0x0000 }, /* R606 */
611 { 0x0000, 0x0000 }, /* R607 */
612 { 0x0000, 0x0000 }, /* R608 */
613 { 0x0000, 0x0000 }, /* R609 */
614 { 0x0000, 0x0000 }, /* R610 */
615 { 0x0000, 0x0000 }, /* R611 */
616 { 0x0000, 0x0000 }, /* R612 */
617 { 0x0000, 0x0000 }, /* R613 */
618 { 0x0000, 0x0000 }, /* R614 */
619 { 0x0000, 0x0000 }, /* R615 */
620 { 0x0000, 0x0000 }, /* R616 */
621 { 0x0000, 0x0000 }, /* R617 */
622 { 0x0000, 0x0000 }, /* R618 */
623 { 0x0000, 0x0000 }, /* R619 */
624 { 0x0000, 0x0000 }, /* R620 */
625 { 0x0000, 0x0000 }, /* R621 */
626 { 0x0000, 0x0000 }, /* R622 */
627 { 0x0000, 0x0000 }, /* R623 */
628 { 0x0000, 0x0000 }, /* R624 */
629 { 0x0000, 0x0000 }, /* R625 */
630 { 0x0000, 0x0000 }, /* R626 */
631 { 0x0000, 0x0000 }, /* R627 */
632 { 0x0000, 0x0000 }, /* R628 */
633 { 0x0000, 0x0000 }, /* R629 */
634 { 0x0000, 0x0000 }, /* R630 */
635 { 0x0000, 0x0000 }, /* R631 */
636 { 0x0000, 0x0000 }, /* R632 */
637 { 0x0000, 0x0000 }, /* R633 */
638 { 0x0000, 0x0000 }, /* R634 */
639 { 0x0000, 0x0000 }, /* R635 */
640 { 0x0000, 0x0000 }, /* R636 */
641 { 0x0000, 0x0000 }, /* R637 */
642 { 0x0000, 0x0000 }, /* R638 */
643 { 0x0000, 0x0000 }, /* R639 */
644 { 0x0000, 0x0000 }, /* R640 */
645 { 0x0000, 0x0000 }, /* R641 */
646 { 0x0000, 0x0000 }, /* R642 */
647 { 0x0000, 0x0000 }, /* R643 */
648 { 0x0000, 0x0000 }, /* R644 */
649 { 0x0000, 0x0000 }, /* R645 */
650 { 0x0000, 0x0000 }, /* R646 */
651 { 0x0000, 0x0000 }, /* R647 */
652 { 0x0000, 0x0000 }, /* R648 */
653 { 0x0000, 0x0000 }, /* R649 */
654 { 0x0000, 0x0000 }, /* R650 */
655 { 0x0000, 0x0000 }, /* R651 */
656 { 0x0000, 0x0000 }, /* R652 */
657 { 0x0000, 0x0000 }, /* R653 */
658 { 0x0000, 0x0000 }, /* R654 */
659 { 0x0000, 0x0000 }, /* R655 */
660 { 0x0000, 0x0000 }, /* R656 */
661 { 0x0000, 0x0000 }, /* R657 */
662 { 0x0000, 0x0000 }, /* R658 */
663 { 0x0000, 0x0000 }, /* R659 */
664 { 0x0000, 0x0000 }, /* R660 */
665 { 0x0000, 0x0000 }, /* R661 */
666 { 0x0000, 0x0000 }, /* R662 */
667 { 0x0000, 0x0000 }, /* R663 */
668 { 0x0000, 0x0000 }, /* R664 */
669 { 0x0000, 0x0000 }, /* R665 */
670 { 0x0000, 0x0000 }, /* R666 */
671 { 0x0000, 0x0000 }, /* R667 */
672 { 0x0000, 0x0000 }, /* R668 */
673 { 0x0000, 0x0000 }, /* R669 */
674 { 0x0000, 0x0000 }, /* R670 */
675 { 0x0000, 0x0000 }, /* R671 */
676 { 0x0000, 0x0000 }, /* R672 */
677 { 0x0000, 0x0000 }, /* R673 */
678 { 0x0000, 0x0000 }, /* R674 */
679 { 0x0000, 0x0000 }, /* R675 */
680 { 0x0000, 0x0000 }, /* R676 */
681 { 0x0000, 0x0000 }, /* R677 */
682 { 0x0000, 0x0000 }, /* R678 */
683 { 0x0000, 0x0000 }, /* R679 */
684 { 0x0000, 0x0000 }, /* R680 */
685 { 0x0000, 0x0000 }, /* R681 */
686 { 0x0000, 0x0000 }, /* R682 */
687 { 0x0000, 0x0000 }, /* R683 */
688 { 0x0000, 0x0000 }, /* R684 */
689 { 0x0000, 0x0000 }, /* R685 */
690 { 0x0000, 0x0000 }, /* R686 */
691 { 0x0000, 0x0000 }, /* R687 */
692 { 0x0000, 0x0000 }, /* R688 */
693 { 0x0000, 0x0000 }, /* R689 */
694 { 0x0000, 0x0000 }, /* R690 */
695 { 0x0000, 0x0000 }, /* R691 */
696 { 0x0000, 0x0000 }, /* R692 */
697 { 0x0000, 0x0000 }, /* R693 */
698 { 0x0000, 0x0000 }, /* R694 */
699 { 0x0000, 0x0000 }, /* R695 */
700 { 0x0000, 0x0000 }, /* R696 */
701 { 0x0000, 0x0000 }, /* R697 */
702 { 0x0000, 0x0000 }, /* R698 */
703 { 0x0000, 0x0000 }, /* R699 */
704 { 0x0000, 0x0000 }, /* R700 */
705 { 0x0000, 0x0000 }, /* R701 */
706 { 0x0000, 0x0000 }, /* R702 */
707 { 0x0000, 0x0000 }, /* R703 */
708 { 0x0000, 0x0000 }, /* R704 */
709 { 0x0000, 0x0000 }, /* R705 */
710 { 0x0000, 0x0000 }, /* R706 */
711 { 0x0000, 0x0000 }, /* R707 */
712 { 0x0000, 0x0000 }, /* R708 */
713 { 0x0000, 0x0000 }, /* R709 */
714 { 0x0000, 0x0000 }, /* R710 */
715 { 0x0000, 0x0000 }, /* R711 */
716 { 0x0000, 0x0000 }, /* R712 */
717 { 0x0000, 0x0000 }, /* R713 */
718 { 0x0000, 0x0000 }, /* R714 */
719 { 0x0000, 0x0000 }, /* R715 */
720 { 0x0000, 0x0000 }, /* R716 */
721 { 0x0000, 0x0000 }, /* R717 */
722 { 0x0000, 0x0000 }, /* R718 */
723 { 0x0000, 0x0000 }, /* R719 */
724 { 0x0000, 0x0000 }, /* R720 */
725 { 0x0000, 0x0000 }, /* R721 */
726 { 0x0000, 0x0000 }, /* R722 */
727 { 0x0000, 0x0000 }, /* R723 */
728 { 0x0000, 0x0000 }, /* R724 */
729 { 0x0000, 0x0000 }, /* R725 */
730 { 0x0000, 0x0000 }, /* R726 */
731 { 0x0000, 0x0000 }, /* R727 */
732 { 0x0000, 0x0000 }, /* R728 */
733 { 0x0000, 0x0000 }, /* R729 */
734 { 0x0000, 0x0000 }, /* R730 */
735 { 0x0000, 0x0000 }, /* R731 */
736 { 0x0000, 0x0000 }, /* R732 */
737 { 0x0000, 0x0000 }, /* R733 */
738 { 0x0000, 0x0000 }, /* R734 */
739 { 0x0000, 0x0000 }, /* R735 */
740 { 0x0000, 0x0000 }, /* R736 */
741 { 0x0000, 0x0000 }, /* R737 */
742 { 0x0000, 0x0000 }, /* R738 */
743 { 0x0000, 0x0000 }, /* R739 */
744 { 0x0000, 0x0000 }, /* R740 */
745 { 0x0000, 0x0000 }, /* R741 */
746 { 0x0000, 0x0000 }, /* R742 */
747 { 0x0000, 0x0000 }, /* R743 */
748 { 0x0000, 0x0000 }, /* R744 */
749 { 0x0000, 0x0000 }, /* R745 */
750 { 0x0000, 0x0000 }, /* R746 */
751 { 0x0000, 0x0000 }, /* R747 */
752 { 0x0000, 0x0000 }, /* R748 */
753 { 0x0000, 0x0000 }, /* R749 */
754 { 0x0000, 0x0000 }, /* R750 */
755 { 0x0000, 0x0000 }, /* R751 */
756 { 0x0000, 0x0000 }, /* R752 */
757 { 0x0000, 0x0000 }, /* R753 */
758 { 0x0000, 0x0000 }, /* R754 */
759 { 0x0000, 0x0000 }, /* R755 */
760 { 0x0000, 0x0000 }, /* R756 */
761 { 0x0000, 0x0000 }, /* R757 */
762 { 0x0000, 0x0000 }, /* R758 */
763 { 0x0000, 0x0000 }, /* R759 */
764 { 0x0000, 0x0000 }, /* R760 */
765 { 0x0000, 0x0000 }, /* R761 */
766 { 0x0000, 0x0000 }, /* R762 */
767 { 0x0000, 0x0000 }, /* R763 */
768 { 0x0000, 0x0000 }, /* R764 */
769 { 0x0000, 0x0000 }, /* R765 */
770 { 0x0000, 0x0000 }, /* R766 */
771 { 0x0000, 0x0000 }, /* R767 */
772 { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */
773 { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */
774 { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */
775 { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */
776 { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */
777 { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */
778 { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */
779 { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */
780 { 0x0000, 0x0000 }, /* R776 */
781 { 0x0000, 0x0000 }, /* R777 */
782 { 0x0000, 0x0000 }, /* R778 */
783 { 0x0000, 0x0000 }, /* R779 */
784 { 0x0000, 0x0000 }, /* R780 */
785 { 0x0000, 0x0000 }, /* R781 */
786 { 0x0000, 0x0000 }, /* R782 */
787 { 0x0000, 0x0000 }, /* R783 */
788 { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */
789 { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */
790 { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */
791 { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */
792 { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */
793 { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */
794 { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */
795 { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */
796 { 0x0000, 0x0000 }, /* R792 */
797 { 0x0000, 0x0000 }, /* R793 */
798 { 0x0000, 0x0000 }, /* R794 */
799 { 0x0000, 0x0000 }, /* R795 */
800 { 0x0000, 0x0000 }, /* R796 */
801 { 0x0000, 0x0000 }, /* R797 */
802 { 0x0000, 0x0000 }, /* R798 */
803 { 0x0000, 0x0000 }, /* R799 */
804 { 0x0000, 0x0000 }, /* R800 */
805 { 0x0000, 0x0000 }, /* R801 */
806 { 0x0000, 0x0000 }, /* R802 */
807 { 0x0000, 0x0000 }, /* R803 */
808 { 0x0000, 0x0000 }, /* R804 */
809 { 0x0000, 0x0000 }, /* R805 */
810 { 0x0000, 0x0000 }, /* R806 */
811 { 0x0000, 0x0000 }, /* R807 */
812 { 0x0000, 0x0000 }, /* R808 */
813 { 0x0000, 0x0000 }, /* R809 */
814 { 0x0000, 0x0000 }, /* R810 */
815 { 0x0000, 0x0000 }, /* R811 */
816 { 0x0000, 0x0000 }, /* R812 */
817 { 0x0000, 0x0000 }, /* R813 */
818 { 0x0000, 0x0000 }, /* R814 */
819 { 0x0000, 0x0000 }, /* R815 */
820 { 0x0000, 0x0000 }, /* R816 */
821 { 0x0000, 0x0000 }, /* R817 */
822 { 0x0000, 0x0000 }, /* R818 */
823 { 0x0000, 0x0000 }, /* R819 */
824 { 0x0000, 0x0000 }, /* R820 */
825 { 0x0000, 0x0000 }, /* R821 */
826 { 0x0000, 0x0000 }, /* R822 */
827 { 0x0000, 0x0000 }, /* R823 */
828 { 0x0000, 0x0000 }, /* R824 */
829 { 0x0000, 0x0000 }, /* R825 */
830 { 0x0000, 0x0000 }, /* R826 */
831 { 0x0000, 0x0000 }, /* R827 */
832 { 0x0000, 0x0000 }, /* R828 */
833 { 0x0000, 0x0000 }, /* R829 */
834 { 0x0000, 0x0000 }, /* R830 */
835 { 0x0000, 0x0000 }, /* R831 */
836 { 0x0000, 0x0000 }, /* R832 */
837 { 0x0000, 0x0000 }, /* R833 */
838 { 0x0000, 0x0000 }, /* R834 */
839 { 0x0000, 0x0000 }, /* R835 */
840 { 0x0000, 0x0000 }, /* R836 */
841 { 0x0000, 0x0000 }, /* R837 */
842 { 0x0000, 0x0000 }, /* R838 */
843 { 0x0000, 0x0000 }, /* R839 */
844 { 0x0000, 0x0000 }, /* R840 */
845 { 0x0000, 0x0000 }, /* R841 */
846 { 0x0000, 0x0000 }, /* R842 */
847 { 0x0000, 0x0000 }, /* R843 */
848 { 0x0000, 0x0000 }, /* R844 */
849 { 0x0000, 0x0000 }, /* R845 */
850 { 0x0000, 0x0000 }, /* R846 */
851 { 0x0000, 0x0000 }, /* R847 */
852 { 0x0000, 0x0000 }, /* R848 */
853 { 0x0000, 0x0000 }, /* R849 */
854 { 0x0000, 0x0000 }, /* R850 */
855 { 0x0000, 0x0000 }, /* R851 */
856 { 0x0000, 0x0000 }, /* R852 */
857 { 0x0000, 0x0000 }, /* R853 */
858 { 0x0000, 0x0000 }, /* R854 */
859 { 0x0000, 0x0000 }, /* R855 */
860 { 0x0000, 0x0000 }, /* R856 */
861 { 0x0000, 0x0000 }, /* R857 */
862 { 0x0000, 0x0000 }, /* R858 */
863 { 0x0000, 0x0000 }, /* R859 */
864 { 0x0000, 0x0000 }, /* R860 */
865 { 0x0000, 0x0000 }, /* R861 */
866 { 0x0000, 0x0000 }, /* R862 */
867 { 0x0000, 0x0000 }, /* R863 */
868 { 0x0000, 0x0000 }, /* R864 */
869 { 0x0000, 0x0000 }, /* R865 */
870 { 0x0000, 0x0000 }, /* R866 */
871 { 0x0000, 0x0000 }, /* R867 */
872 { 0x0000, 0x0000 }, /* R868 */
873 { 0x0000, 0x0000 }, /* R869 */
874 { 0x0000, 0x0000 }, /* R870 */
875 { 0x0000, 0x0000 }, /* R871 */
876 { 0x0000, 0x0000 }, /* R872 */
877 { 0x0000, 0x0000 }, /* R873 */
878 { 0x0000, 0x0000 }, /* R874 */
879 { 0x0000, 0x0000 }, /* R875 */
880 { 0x0000, 0x0000 }, /* R876 */
881 { 0x0000, 0x0000 }, /* R877 */
882 { 0x0000, 0x0000 }, /* R878 */
883 { 0x0000, 0x0000 }, /* R879 */
884 { 0x0000, 0x0000 }, /* R880 */
885 { 0x0000, 0x0000 }, /* R881 */
886 { 0x0000, 0x0000 }, /* R882 */
887 { 0x0000, 0x0000 }, /* R883 */
888 { 0x0000, 0x0000 }, /* R884 */
889 { 0x0000, 0x0000 }, /* R885 */
890 { 0x0000, 0x0000 }, /* R886 */
891 { 0x0000, 0x0000 }, /* R887 */
892 { 0x0000, 0x0000 }, /* R888 */
893 { 0x0000, 0x0000 }, /* R889 */
894 { 0x0000, 0x0000 }, /* R890 */
895 { 0x0000, 0x0000 }, /* R891 */
896 { 0x0000, 0x0000 }, /* R892 */
897 { 0x0000, 0x0000 }, /* R893 */
898 { 0x0000, 0x0000 }, /* R894 */
899 { 0x0000, 0x0000 }, /* R895 */
900 { 0x0000, 0x0000 }, /* R896 */
901 { 0x0000, 0x0000 }, /* R897 */
902 { 0x0000, 0x0000 }, /* R898 */
903 { 0x0000, 0x0000 }, /* R899 */
904 { 0x0000, 0x0000 }, /* R900 */
905 { 0x0000, 0x0000 }, /* R901 */
906 { 0x0000, 0x0000 }, /* R902 */
907 { 0x0000, 0x0000 }, /* R903 */
908 { 0x0000, 0x0000 }, /* R904 */
909 { 0x0000, 0x0000 }, /* R905 */
910 { 0x0000, 0x0000 }, /* R906 */
911 { 0x0000, 0x0000 }, /* R907 */
912 { 0x0000, 0x0000 }, /* R908 */
913 { 0x0000, 0x0000 }, /* R909 */
914 { 0x0000, 0x0000 }, /* R910 */
915 { 0x0000, 0x0000 }, /* R911 */
916 { 0x0000, 0x0000 }, /* R912 */
917 { 0x0000, 0x0000 }, /* R913 */
918 { 0x0000, 0x0000 }, /* R914 */
919 { 0x0000, 0x0000 }, /* R915 */
920 { 0x0000, 0x0000 }, /* R916 */
921 { 0x0000, 0x0000 }, /* R917 */
922 { 0x0000, 0x0000 }, /* R918 */
923 { 0x0000, 0x0000 }, /* R919 */
924 { 0x0000, 0x0000 }, /* R920 */
925 { 0x0000, 0x0000 }, /* R921 */
926 { 0x0000, 0x0000 }, /* R922 */
927 { 0x0000, 0x0000 }, /* R923 */
928 { 0x0000, 0x0000 }, /* R924 */
929 { 0x0000, 0x0000 }, /* R925 */
930 { 0x0000, 0x0000 }, /* R926 */
931 { 0x0000, 0x0000 }, /* R927 */
932 { 0x0000, 0x0000 }, /* R928 */
933 { 0x0000, 0x0000 }, /* R929 */
934 { 0x0000, 0x0000 }, /* R930 */
935 { 0x0000, 0x0000 }, /* R931 */
936 { 0x0000, 0x0000 }, /* R932 */
937 { 0x0000, 0x0000 }, /* R933 */
938 { 0x0000, 0x0000 }, /* R934 */
939 { 0x0000, 0x0000 }, /* R935 */
940 { 0x0000, 0x0000 }, /* R936 */
941 { 0x0000, 0x0000 }, /* R937 */
942 { 0x0000, 0x0000 }, /* R938 */
943 { 0x0000, 0x0000 }, /* R939 */
944 { 0x0000, 0x0000 }, /* R940 */
945 { 0x0000, 0x0000 }, /* R941 */
946 { 0x0000, 0x0000 }, /* R942 */
947 { 0x0000, 0x0000 }, /* R943 */
948 { 0x0000, 0x0000 }, /* R944 */
949 { 0x0000, 0x0000 }, /* R945 */
950 { 0x0000, 0x0000 }, /* R946 */
951 { 0x0000, 0x0000 }, /* R947 */
952 { 0x0000, 0x0000 }, /* R948 */
953 { 0x0000, 0x0000 }, /* R949 */
954 { 0x0000, 0x0000 }, /* R950 */
955 { 0x0000, 0x0000 }, /* R951 */
956 { 0x0000, 0x0000 }, /* R952 */
957 { 0x0000, 0x0000 }, /* R953 */
958 { 0x0000, 0x0000 }, /* R954 */
959 { 0x0000, 0x0000 }, /* R955 */
960 { 0x0000, 0x0000 }, /* R956 */
961 { 0x0000, 0x0000 }, /* R957 */
962 { 0x0000, 0x0000 }, /* R958 */
963 { 0x0000, 0x0000 }, /* R959 */
964 { 0x0000, 0x0000 }, /* R960 */
965 { 0x0000, 0x0000 }, /* R961 */
966 { 0x0000, 0x0000 }, /* R962 */
967 { 0x0000, 0x0000 }, /* R963 */
968 { 0x0000, 0x0000 }, /* R964 */
969 { 0x0000, 0x0000 }, /* R965 */
970 { 0x0000, 0x0000 }, /* R966 */
971 { 0x0000, 0x0000 }, /* R967 */
972 { 0x0000, 0x0000 }, /* R968 */
973 { 0x0000, 0x0000 }, /* R969 */
974 { 0x0000, 0x0000 }, /* R970 */
975 { 0x0000, 0x0000 }, /* R971 */
976 { 0x0000, 0x0000 }, /* R972 */
977 { 0x0000, 0x0000 }, /* R973 */
978 { 0x0000, 0x0000 }, /* R974 */
979 { 0x0000, 0x0000 }, /* R975 */
980 { 0x0000, 0x0000 }, /* R976 */
981 { 0x0000, 0x0000 }, /* R977 */
982 { 0x0000, 0x0000 }, /* R978 */
983 { 0x0000, 0x0000 }, /* R979 */
984 { 0x0000, 0x0000 }, /* R980 */
985 { 0x0000, 0x0000 }, /* R981 */
986 { 0x0000, 0x0000 }, /* R982 */
987 { 0x0000, 0x0000 }, /* R983 */
988 { 0x0000, 0x0000 }, /* R984 */
989 { 0x0000, 0x0000 }, /* R985 */
990 { 0x0000, 0x0000 }, /* R986 */
991 { 0x0000, 0x0000 }, /* R987 */
992 { 0x0000, 0x0000 }, /* R988 */
993 { 0x0000, 0x0000 }, /* R989 */
994 { 0x0000, 0x0000 }, /* R990 */
995 { 0x0000, 0x0000 }, /* R991 */
996 { 0x0000, 0x0000 }, /* R992 */
997 { 0x0000, 0x0000 }, /* R993 */
998 { 0x0000, 0x0000 }, /* R994 */
999 { 0x0000, 0x0000 }, /* R995 */
1000 { 0x0000, 0x0000 }, /* R996 */
1001 { 0x0000, 0x0000 }, /* R997 */
1002 { 0x0000, 0x0000 }, /* R998 */
1003 { 0x0000, 0x0000 }, /* R999 */
1004 { 0x0000, 0x0000 }, /* R1000 */
1005 { 0x0000, 0x0000 }, /* R1001 */
1006 { 0x0000, 0x0000 }, /* R1002 */
1007 { 0x0000, 0x0000 }, /* R1003 */
1008 { 0x0000, 0x0000 }, /* R1004 */
1009 { 0x0000, 0x0000 }, /* R1005 */
1010 { 0x0000, 0x0000 }, /* R1006 */
1011 { 0x0000, 0x0000 }, /* R1007 */
1012 { 0x0000, 0x0000 }, /* R1008 */
1013 { 0x0000, 0x0000 }, /* R1009 */
1014 { 0x0000, 0x0000 }, /* R1010 */
1015 { 0x0000, 0x0000 }, /* R1011 */
1016 { 0x0000, 0x0000 }, /* R1012 */
1017 { 0x0000, 0x0000 }, /* R1013 */
1018 { 0x0000, 0x0000 }, /* R1014 */
1019 { 0x0000, 0x0000 }, /* R1015 */
1020 { 0x0000, 0x0000 }, /* R1016 */
1021 { 0x0000, 0x0000 }, /* R1017 */
1022 { 0x0000, 0x0000 }, /* R1018 */
1023 { 0x0000, 0x0000 }, /* R1019 */
1024 { 0x0000, 0x0000 }, /* R1020 */
1025 { 0x0000, 0x0000 }, /* R1021 */
1026 { 0x0000, 0x0000 }, /* R1022 */
1027 { 0x0000, 0x0000 }, /* R1023 */
1028 { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */
1029 { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */
1030 { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */
1031 { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */
1032 { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */
1033 { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */
1034 { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */
1035 { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */
1036 { 0x0000, 0x0000 }, /* R1032 */
1037 { 0x0000, 0x0000 }, /* R1033 */
1038 { 0x0000, 0x0000 }, /* R1034 */
1039 { 0x0000, 0x0000 }, /* R1035 */
1040 { 0x0000, 0x0000 }, /* R1036 */
1041 { 0x0000, 0x0000 }, /* R1037 */
1042 { 0x0000, 0x0000 }, /* R1038 */
1043 { 0x0000, 0x0000 }, /* R1039 */
1044 { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */
1045 { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */
1046 { 0x0000, 0x0000 }, /* R1042 */
1047 { 0x0000, 0x0000 }, /* R1043 */
1048 { 0x0000, 0x0000 }, /* R1044 */
1049 { 0x0000, 0x0000 }, /* R1045 */
1050 { 0x0000, 0x0000 }, /* R1046 */
1051 { 0x0000, 0x0000 }, /* R1047 */
1052 { 0x0000, 0x0000 }, /* R1048 */
1053 { 0x0000, 0x0000 }, /* R1049 */
1054 { 0x0000, 0x0000 }, /* R1050 */
1055 { 0x0000, 0x0000 }, /* R1051 */
1056 { 0x0000, 0x0000 }, /* R1052 */
1057 { 0x0000, 0x0000 }, /* R1053 */
1058 { 0x0000, 0x0000 }, /* R1054 */
1059 { 0x0000, 0x0000 }, /* R1055 */
1060 { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */
1061 { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */
1062 { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */
1063 { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */
1064 { 0x0000, 0x0000 }, /* R1060 */
1065 { 0x0000, 0x0000 }, /* R1061 */
1066 { 0x0000, 0x0000 }, /* R1062 */
1067 { 0x0000, 0x0000 }, /* R1063 */
1068 { 0x0000, 0x0000 }, /* R1064 */
1069 { 0x0000, 0x0000 }, /* R1065 */
1070 { 0x0000, 0x0000 }, /* R1066 */
1071 { 0x0000, 0x0000 }, /* R1067 */
1072 { 0x0000, 0x0000 }, /* R1068 */
1073 { 0x0000, 0x0000 }, /* R1069 */
1074 { 0x0000, 0x0000 }, /* R1070 */
1075 { 0x0000, 0x0000 }, /* R1071 */
1076 { 0x0000, 0x0000 }, /* R1072 */
1077 { 0x0000, 0x0000 }, /* R1073 */
1078 { 0x0000, 0x0000 }, /* R1074 */
1079 { 0x0000, 0x0000 }, /* R1075 */
1080 { 0x0000, 0x0000 }, /* R1076 */
1081 { 0x0000, 0x0000 }, /* R1077 */
1082 { 0x0000, 0x0000 }, /* R1078 */
1083 { 0x0000, 0x0000 }, /* R1079 */
1084 { 0x0000, 0x0000 }, /* R1080 */
1085 { 0x0000, 0x0000 }, /* R1081 */
1086 { 0x0000, 0x0000 }, /* R1082 */
1087 { 0x0000, 0x0000 }, /* R1083 */
1088 { 0x0000, 0x0000 }, /* R1084 */
1089 { 0x0000, 0x0000 }, /* R1085 */
1090 { 0x0000, 0x0000 }, /* R1086 */
1091 { 0x0000, 0x0000 }, /* R1087 */
1092 { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */
1093 { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */
1094 { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */
1095 { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */
1096 { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */
1097 { 0x0000, 0x0000 }, /* R1093 */
1098 { 0x0000, 0x0000 }, /* R1094 */
1099 { 0x0000, 0x0000 }, /* R1095 */
1100 { 0x0000, 0x0000 }, /* R1096 */
1101 { 0x0000, 0x0000 }, /* R1097 */
1102 { 0x0000, 0x0000 }, /* R1098 */
1103 { 0x0000, 0x0000 }, /* R1099 */
1104 { 0x0000, 0x0000 }, /* R1100 */
1105 { 0x0000, 0x0000 }, /* R1101 */
1106 { 0x0000, 0x0000 }, /* R1102 */
1107 { 0x0000, 0x0000 }, /* R1103 */
1108 { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */
1109 { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */
1110 { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */
1111 { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */
1112 { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */
1113 { 0x0000, 0x0000 }, /* R1109 */
1114 { 0x0000, 0x0000 }, /* R1110 */
1115 { 0x0000, 0x0000 }, /* R1111 */
1116 { 0x0000, 0x0000 }, /* R1112 */
1117 { 0x0000, 0x0000 }, /* R1113 */
1118 { 0x0000, 0x0000 }, /* R1114 */
1119 { 0x0000, 0x0000 }, /* R1115 */
1120 { 0x0000, 0x0000 }, /* R1116 */
1121 { 0x0000, 0x0000 }, /* R1117 */
1122 { 0x0000, 0x0000 }, /* R1118 */
1123 { 0x0000, 0x0000 }, /* R1119 */
1124 { 0x0000, 0x0000 }, /* R1120 */
1125 { 0x0000, 0x0000 }, /* R1121 */
1126 { 0x0000, 0x0000 }, /* R1122 */
1127 { 0x0000, 0x0000 }, /* R1123 */
1128 { 0x0000, 0x0000 }, /* R1124 */
1129 { 0x0000, 0x0000 }, /* R1125 */
1130 { 0x0000, 0x0000 }, /* R1126 */
1131 { 0x0000, 0x0000 }, /* R1127 */
1132 { 0x0000, 0x0000 }, /* R1128 */
1133 { 0x0000, 0x0000 }, /* R1129 */
1134 { 0x0000, 0x0000 }, /* R1130 */
1135 { 0x0000, 0x0000 }, /* R1131 */
1136 { 0x0000, 0x0000 }, /* R1132 */
1137 { 0x0000, 0x0000 }, /* R1133 */
1138 { 0x0000, 0x0000 }, /* R1134 */
1139 { 0x0000, 0x0000 }, /* R1135 */
1140 { 0x0000, 0x0000 }, /* R1136 */
1141 { 0x0000, 0x0000 }, /* R1137 */
1142 { 0x0000, 0x0000 }, /* R1138 */
1143 { 0x0000, 0x0000 }, /* R1139 */
1144 { 0x0000, 0x0000 }, /* R1140 */
1145 { 0x0000, 0x0000 }, /* R1141 */
1146 { 0x0000, 0x0000 }, /* R1142 */
1147 { 0x0000, 0x0000 }, /* R1143 */
1148 { 0x0000, 0x0000 }, /* R1144 */
1149 { 0x0000, 0x0000 }, /* R1145 */
1150 { 0x0000, 0x0000 }, /* R1146 */
1151 { 0x0000, 0x0000 }, /* R1147 */
1152 { 0x0000, 0x0000 }, /* R1148 */
1153 { 0x0000, 0x0000 }, /* R1149 */
1154 { 0x0000, 0x0000 }, /* R1150 */
1155 { 0x0000, 0x0000 }, /* R1151 */
1156 { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
1157 { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
1158 { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
1159 { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
1160 { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
1161 { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
1162 { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
1163 { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
1164 { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
1165 { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
1166 { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
1167 { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
1168 { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
1169 { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
1170 { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
1171 { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
1172 { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
1173 { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
1174 { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
1175 { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
1176 { 0x0000, 0x0000 }, /* R1172 */
1177 { 0x0000, 0x0000 }, /* R1173 */
1178 { 0x0000, 0x0000 }, /* R1174 */
1179 { 0x0000, 0x0000 }, /* R1175 */
1180 { 0x0000, 0x0000 }, /* R1176 */
1181 { 0x0000, 0x0000 }, /* R1177 */
1182 { 0x0000, 0x0000 }, /* R1178 */
1183 { 0x0000, 0x0000 }, /* R1179 */
1184 { 0x0000, 0x0000 }, /* R1180 */
1185 { 0x0000, 0x0000 }, /* R1181 */
1186 { 0x0000, 0x0000 }, /* R1182 */
1187 { 0x0000, 0x0000 }, /* R1183 */
1188 { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
1189 { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
1190 { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
1191 { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
1192 { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
1193 { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
1194 { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
1195 { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
1196 { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
1197 { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
1198 { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
1199 { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
1200 { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
1201 { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
1202 { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
1203 { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
1204 { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
1205 { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
1206 { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
1207 { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
1208 { 0x0000, 0x0000 }, /* R1204 */
1209 { 0x0000, 0x0000 }, /* R1205 */
1210 { 0x0000, 0x0000 }, /* R1206 */
1211 { 0x0000, 0x0000 }, /* R1207 */
1212 { 0x0000, 0x0000 }, /* R1208 */
1213 { 0x0000, 0x0000 }, /* R1209 */
1214 { 0x0000, 0x0000 }, /* R1210 */
1215 { 0x0000, 0x0000 }, /* R1211 */
1216 { 0x0000, 0x0000 }, /* R1212 */
1217 { 0x0000, 0x0000 }, /* R1213 */
1218 { 0x0000, 0x0000 }, /* R1214 */
1219 { 0x0000, 0x0000 }, /* R1215 */
1220 { 0x0000, 0x0000 }, /* R1216 */
1221 { 0x0000, 0x0000 }, /* R1217 */
1222 { 0x0000, 0x0000 }, /* R1218 */
1223 { 0x0000, 0x0000 }, /* R1219 */
1224 { 0x0000, 0x0000 }, /* R1220 */
1225 { 0x0000, 0x0000 }, /* R1221 */
1226 { 0x0000, 0x0000 }, /* R1222 */
1227 { 0x0000, 0x0000 }, /* R1223 */
1228 { 0x0000, 0x0000 }, /* R1224 */
1229 { 0x0000, 0x0000 }, /* R1225 */
1230 { 0x0000, 0x0000 }, /* R1226 */
1231 { 0x0000, 0x0000 }, /* R1227 */
1232 { 0x0000, 0x0000 }, /* R1228 */
1233 { 0x0000, 0x0000 }, /* R1229 */
1234 { 0x0000, 0x0000 }, /* R1230 */
1235 { 0x0000, 0x0000 }, /* R1231 */
1236 { 0x0000, 0x0000 }, /* R1232 */
1237 { 0x0000, 0x0000 }, /* R1233 */
1238 { 0x0000, 0x0000 }, /* R1234 */
1239 { 0x0000, 0x0000 }, /* R1235 */
1240 { 0x0000, 0x0000 }, /* R1236 */
1241 { 0x0000, 0x0000 }, /* R1237 */
1242 { 0x0000, 0x0000 }, /* R1238 */
1243 { 0x0000, 0x0000 }, /* R1239 */
1244 { 0x0000, 0x0000 }, /* R1240 */
1245 { 0x0000, 0x0000 }, /* R1241 */
1246 { 0x0000, 0x0000 }, /* R1242 */
1247 { 0x0000, 0x0000 }, /* R1243 */
1248 { 0x0000, 0x0000 }, /* R1244 */
1249 { 0x0000, 0x0000 }, /* R1245 */
1250 { 0x0000, 0x0000 }, /* R1246 */
1251 { 0x0000, 0x0000 }, /* R1247 */
1252 { 0x0000, 0x0000 }, /* R1248 */
1253 { 0x0000, 0x0000 }, /* R1249 */
1254 { 0x0000, 0x0000 }, /* R1250 */
1255 { 0x0000, 0x0000 }, /* R1251 */
1256 { 0x0000, 0x0000 }, /* R1252 */
1257 { 0x0000, 0x0000 }, /* R1253 */
1258 { 0x0000, 0x0000 }, /* R1254 */
1259 { 0x0000, 0x0000 }, /* R1255 */
1260 { 0x0000, 0x0000 }, /* R1256 */
1261 { 0x0000, 0x0000 }, /* R1257 */
1262 { 0x0000, 0x0000 }, /* R1258 */
1263 { 0x0000, 0x0000 }, /* R1259 */
1264 { 0x0000, 0x0000 }, /* R1260 */
1265 { 0x0000, 0x0000 }, /* R1261 */
1266 { 0x0000, 0x0000 }, /* R1262 */
1267 { 0x0000, 0x0000 }, /* R1263 */
1268 { 0x0000, 0x0000 }, /* R1264 */
1269 { 0x0000, 0x0000 }, /* R1265 */
1270 { 0x0000, 0x0000 }, /* R1266 */
1271 { 0x0000, 0x0000 }, /* R1267 */
1272 { 0x0000, 0x0000 }, /* R1268 */
1273 { 0x0000, 0x0000 }, /* R1269 */
1274 { 0x0000, 0x0000 }, /* R1270 */
1275 { 0x0000, 0x0000 }, /* R1271 */
1276 { 0x0000, 0x0000 }, /* R1272 */
1277 { 0x0000, 0x0000 }, /* R1273 */
1278 { 0x0000, 0x0000 }, /* R1274 */
1279 { 0x0000, 0x0000 }, /* R1275 */
1280 { 0x0000, 0x0000 }, /* R1276 */
1281 { 0x0000, 0x0000 }, /* R1277 */
1282 { 0x0000, 0x0000 }, /* R1278 */
1283 { 0x0000, 0x0000 }, /* R1279 */
1284 { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */
1285 { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */
1286 { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */
1287 { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */
1288 { 0x0000, 0x0000 }, /* R1284 */
1289 { 0x0000, 0x0000 }, /* R1285 */
1290 { 0x0000, 0x0000 }, /* R1286 */
1291 { 0x0000, 0x0000 }, /* R1287 */
1292 { 0x0000, 0x0000 }, /* R1288 */
1293 { 0x0000, 0x0000 }, /* R1289 */
1294 { 0x0000, 0x0000 }, /* R1290 */
1295 { 0x0000, 0x0000 }, /* R1291 */
1296 { 0x0000, 0x0000 }, /* R1292 */
1297 { 0x0000, 0x0000 }, /* R1293 */
1298 { 0x0000, 0x0000 }, /* R1294 */
1299 { 0x0000, 0x0000 }, /* R1295 */
1300 { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */
1301 { 0x0000, 0x0000 }, /* R1297 */
1302 { 0x0000, 0x0000 }, /* R1298 */
1303 { 0x0000, 0x0000 }, /* R1299 */
1304 { 0x0000, 0x0000 }, /* R1300 */
1305 { 0x0000, 0x0000 }, /* R1301 */
1306 { 0x0000, 0x0000 }, /* R1302 */
1307 { 0x0000, 0x0000 }, /* R1303 */
1308 { 0x0000, 0x0000 }, /* R1304 */
1309 { 0x0000, 0x0000 }, /* R1305 */
1310 { 0x0000, 0x0000 }, /* R1306 */
1311 { 0x0000, 0x0000 }, /* R1307 */
1312 { 0x0000, 0x0000 }, /* R1308 */
1313 { 0x0000, 0x0000 }, /* R1309 */
1314 { 0x0000, 0x0000 }, /* R1310 */
1315 { 0x0000, 0x0000 }, /* R1311 */
1316 { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */
1317 { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */
1318 { 0x0000, 0x0000 }, /* R1314 */
1319 { 0x0000, 0x0000 }, /* R1315 */
1320 { 0x0000, 0x0000 }, /* R1316 */
1321 { 0x0000, 0x0000 }, /* R1317 */
1322 { 0x0000, 0x0000 }, /* R1318 */
1323 { 0x0000, 0x0000 }, /* R1319 */
1324 { 0x0000, 0x0000 }, /* R1320 */
1325 { 0x0000, 0x0000 }, /* R1321 */
1326 { 0x0000, 0x0000 }, /* R1322 */
1327 { 0x0000, 0x0000 }, /* R1323 */
1328 { 0x0000, 0x0000 }, /* R1324 */
1329 { 0x0000, 0x0000 }, /* R1325 */
1330 { 0x0000, 0x0000 }, /* R1326 */
1331 { 0x0000, 0x0000 }, /* R1327 */
1332 { 0x0000, 0x0000 }, /* R1328 */
1333 { 0x0000, 0x0000 }, /* R1329 */
1334 { 0x0000, 0x0000 }, /* R1330 */
1335 { 0x0000, 0x0000 }, /* R1331 */
1336 { 0x0000, 0x0000 }, /* R1332 */
1337 { 0x0000, 0x0000 }, /* R1333 */
1338 { 0x0000, 0x0000 }, /* R1334 */
1339 { 0x0000, 0x0000 }, /* R1335 */
1340 { 0x0000, 0x0000 }, /* R1336 */
1341 { 0x0000, 0x0000 }, /* R1337 */
1342 { 0x0000, 0x0000 }, /* R1338 */
1343 { 0x0000, 0x0000 }, /* R1339 */
1344 { 0x0000, 0x0000 }, /* R1340 */
1345 { 0x0000, 0x0000 }, /* R1341 */
1346 { 0x0000, 0x0000 }, /* R1342 */
1347 { 0x0000, 0x0000 }, /* R1343 */
1348 { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */
1349 { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */
1350 { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */
1351 { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */
1352 { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */
1353 { 0x0000, 0x0000 }, /* R1349 */
1354 { 0x0000, 0x0000 }, /* R1350 */
1355 { 0x0000, 0x0000 }, /* R1351 */
1356 { 0x0000, 0x0000 }, /* R1352 */
1357 { 0x0000, 0x0000 }, /* R1353 */
1358 { 0x0000, 0x0000 }, /* R1354 */
1359 { 0x0000, 0x0000 }, /* R1355 */
1360 { 0x0000, 0x0000 }, /* R1356 */
1361 { 0x0000, 0x0000 }, /* R1357 */
1362 { 0x0000, 0x0000 }, /* R1358 */
1363 { 0x0000, 0x0000 }, /* R1359 */
1364 { 0x0000, 0x0000 }, /* R1360 */
1365 { 0x0000, 0x0000 }, /* R1361 */
1366 { 0x0000, 0x0000 }, /* R1362 */
1367 { 0x0000, 0x0000 }, /* R1363 */
1368 { 0x0000, 0x0000 }, /* R1364 */
1369 { 0x0000, 0x0000 }, /* R1365 */
1370 { 0x0000, 0x0000 }, /* R1366 */
1371 { 0x0000, 0x0000 }, /* R1367 */
1372 { 0x0000, 0x0000 }, /* R1368 */
1373 { 0x0000, 0x0000 }, /* R1369 */
1374 { 0x0000, 0x0000 }, /* R1370 */
1375 { 0x0000, 0x0000 }, /* R1371 */
1376 { 0x0000, 0x0000 }, /* R1372 */
1377 { 0x0000, 0x0000 }, /* R1373 */
1378 { 0x0000, 0x0000 }, /* R1374 */
1379 { 0x0000, 0x0000 }, /* R1375 */
1380 { 0x0000, 0x0000 }, /* R1376 */
1381 { 0x0000, 0x0000 }, /* R1377 */
1382 { 0x0000, 0x0000 }, /* R1378 */
1383 { 0x0000, 0x0000 }, /* R1379 */
1384 { 0x0000, 0x0000 }, /* R1380 */
1385 { 0x0000, 0x0000 }, /* R1381 */
1386 { 0x0000, 0x0000 }, /* R1382 */
1387 { 0x0000, 0x0000 }, /* R1383 */
1388 { 0x0000, 0x0000 }, /* R1384 */
1389 { 0x0000, 0x0000 }, /* R1385 */
1390 { 0x0000, 0x0000 }, /* R1386 */
1391 { 0x0000, 0x0000 }, /* R1387 */
1392 { 0x0000, 0x0000 }, /* R1388 */
1393 { 0x0000, 0x0000 }, /* R1389 */
1394 { 0x0000, 0x0000 }, /* R1390 */
1395 { 0x0000, 0x0000 }, /* R1391 */
1396 { 0x0000, 0x0000 }, /* R1392 */
1397 { 0x0000, 0x0000 }, /* R1393 */
1398 { 0x0000, 0x0000 }, /* R1394 */
1399 { 0x0000, 0x0000 }, /* R1395 */
1400 { 0x0000, 0x0000 }, /* R1396 */
1401 { 0x0000, 0x0000 }, /* R1397 */
1402 { 0x0000, 0x0000 }, /* R1398 */
1403 { 0x0000, 0x0000 }, /* R1399 */
1404 { 0x0000, 0x0000 }, /* R1400 */
1405 { 0x0000, 0x0000 }, /* R1401 */
1406 { 0x0000, 0x0000 }, /* R1402 */
1407 { 0x0000, 0x0000 }, /* R1403 */
1408 { 0x0000, 0x0000 }, /* R1404 */
1409 { 0x0000, 0x0000 }, /* R1405 */
1410 { 0x0000, 0x0000 }, /* R1406 */
1411 { 0x0000, 0x0000 }, /* R1407 */
1412 { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */
1413 { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */
1414 { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */
1415 { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */
1416 { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */
1417 { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */
1418 { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */
1419 { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */
1420 { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */
1421 { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */
1422 { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */
1423 { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */
1424 { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */
1425 { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */
1426 { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */
1427 { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */
1428 { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */
1429 { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */
1430 { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */
1431 { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */
1432 { 0x0000, 0x0000 }, /* R1428 */
1433 { 0x0000, 0x0000 }, /* R1429 */
1434 { 0x0000, 0x0000 }, /* R1430 */
1435 { 0x0000, 0x0000 }, /* R1431 */
1436 { 0x0000, 0x0000 }, /* R1432 */
1437 { 0x0000, 0x0000 }, /* R1433 */
1438 { 0x0000, 0x0000 }, /* R1434 */
1439 { 0x0000, 0x0000 }, /* R1435 */
1440 { 0x0000, 0x0000 }, /* R1436 */
1441 { 0x0000, 0x0000 }, /* R1437 */
1442 { 0x0000, 0x0000 }, /* R1438 */
1443 { 0x0000, 0x0000 }, /* R1439 */
1444 { 0x0000, 0x0000 }, /* R1440 */
1445 { 0x0000, 0x0000 }, /* R1441 */
1446 { 0x0000, 0x0000 }, /* R1442 */
1447 { 0x0000, 0x0000 }, /* R1443 */
1448 { 0x0000, 0x0000 }, /* R1444 */
1449 { 0x0000, 0x0000 }, /* R1445 */
1450 { 0x0000, 0x0000 }, /* R1446 */
1451 { 0x0000, 0x0000 }, /* R1447 */
1452 { 0x0000, 0x0000 }, /* R1448 */
1453 { 0x0000, 0x0000 }, /* R1449 */
1454 { 0x0000, 0x0000 }, /* R1450 */
1455 { 0x0000, 0x0000 }, /* R1451 */
1456 { 0x0000, 0x0000 }, /* R1452 */
1457 { 0x0000, 0x0000 }, /* R1453 */
1458 { 0x0000, 0x0000 }, /* R1454 */
1459 { 0x0000, 0x0000 }, /* R1455 */
1460 { 0x0000, 0x0000 }, /* R1456 */
1461 { 0x0000, 0x0000 }, /* R1457 */
1462 { 0x0000, 0x0000 }, /* R1458 */
1463 { 0x0000, 0x0000 }, /* R1459 */
1464 { 0x0000, 0x0000 }, /* R1460 */
1465 { 0x0000, 0x0000 }, /* R1461 */
1466 { 0x0000, 0x0000 }, /* R1462 */
1467 { 0x0000, 0x0000 }, /* R1463 */
1468 { 0x0000, 0x0000 }, /* R1464 */
1469 { 0x0000, 0x0000 }, /* R1465 */
1470 { 0x0000, 0x0000 }, /* R1466 */
1471 { 0x0000, 0x0000 }, /* R1467 */
1472 { 0x0000, 0x0000 }, /* R1468 */
1473 { 0x0000, 0x0000 }, /* R1469 */
1474 { 0x0000, 0x0000 }, /* R1470 */
1475 { 0x0000, 0x0000 }, /* R1471 */
1476 { 0x0000, 0x0000 }, /* R1472 */
1477 { 0x0000, 0x0000 }, /* R1473 */
1478 { 0x0000, 0x0000 }, /* R1474 */
1479 { 0x0000, 0x0000 }, /* R1475 */
1480 { 0x0000, 0x0000 }, /* R1476 */
1481 { 0x0000, 0x0000 }, /* R1477 */
1482 { 0x0000, 0x0000 }, /* R1478 */
1483 { 0x0000, 0x0000 }, /* R1479 */
1484 { 0x0000, 0x0000 }, /* R1480 */
1485 { 0x0000, 0x0000 }, /* R1481 */
1486 { 0x0000, 0x0000 }, /* R1482 */
1487 { 0x0000, 0x0000 }, /* R1483 */
1488 { 0x0000, 0x0000 }, /* R1484 */
1489 { 0x0000, 0x0000 }, /* R1485 */
1490 { 0x0000, 0x0000 }, /* R1486 */
1491 { 0x0000, 0x0000 }, /* R1487 */
1492 { 0x0000, 0x0000 }, /* R1488 */
1493 { 0x0000, 0x0000 }, /* R1489 */
1494 { 0x0000, 0x0000 }, /* R1490 */
1495 { 0x0000, 0x0000 }, /* R1491 */
1496 { 0x0000, 0x0000 }, /* R1492 */
1497 { 0x0000, 0x0000 }, /* R1493 */
1498 { 0x0000, 0x0000 }, /* R1494 */
1499 { 0x0000, 0x0000 }, /* R1495 */
1500 { 0x0000, 0x0000 }, /* R1496 */
1501 { 0x0000, 0x0000 }, /* R1497 */
1502 { 0x0000, 0x0000 }, /* R1498 */
1503 { 0x0000, 0x0000 }, /* R1499 */
1504 { 0x0000, 0x0000 }, /* R1500 */
1505 { 0x0000, 0x0000 }, /* R1501 */
1506 { 0x0000, 0x0000 }, /* R1502 */
1507 { 0x0000, 0x0000 }, /* R1503 */
1508 { 0x0000, 0x0000 }, /* R1504 */
1509 { 0x0000, 0x0000 }, /* R1505 */
1510 { 0x0000, 0x0000 }, /* R1506 */
1511 { 0x0000, 0x0000 }, /* R1507 */
1512 { 0x0000, 0x0000 }, /* R1508 */
1513 { 0x0000, 0x0000 }, /* R1509 */
1514 { 0x0000, 0x0000 }, /* R1510 */
1515 { 0x0000, 0x0000 }, /* R1511 */
1516 { 0x0000, 0x0000 }, /* R1512 */
1517 { 0x0000, 0x0000 }, /* R1513 */
1518 { 0x0000, 0x0000 }, /* R1514 */
1519 { 0x0000, 0x0000 }, /* R1515 */
1520 { 0x0000, 0x0000 }, /* R1516 */
1521 { 0x0000, 0x0000 }, /* R1517 */
1522 { 0x0000, 0x0000 }, /* R1518 */
1523 { 0x0000, 0x0000 }, /* R1519 */
1524 { 0x0000, 0x0000 }, /* R1520 */
1525 { 0x0000, 0x0000 }, /* R1521 */
1526 { 0x0000, 0x0000 }, /* R1522 */
1527 { 0x0000, 0x0000 }, /* R1523 */
1528 { 0x0000, 0x0000 }, /* R1524 */
1529 { 0x0000, 0x0000 }, /* R1525 */
1530 { 0x0000, 0x0000 }, /* R1526 */
1531 { 0x0000, 0x0000 }, /* R1527 */
1532 { 0x0000, 0x0000 }, /* R1528 */
1533 { 0x0000, 0x0000 }, /* R1529 */
1534 { 0x0000, 0x0000 }, /* R1530 */
1535 { 0x0000, 0x0000 }, /* R1531 */
1536 { 0x0000, 0x0000 }, /* R1532 */
1537 { 0x0000, 0x0000 }, /* R1533 */
1538 { 0x0000, 0x0000 }, /* R1534 */
1539 { 0x0000, 0x0000 }, /* R1535 */
1540 { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */
1541 { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */
1542 { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */
1543 { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */
1544 { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */
1545 { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */
1546 { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
1547 { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
1548 { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
1549 { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
1550 { 0x0000, 0x0000 }, /* R1546 */
1551 { 0x0000, 0x0000 }, /* R1547 */
1552 { 0x0000, 0x0000 }, /* R1548 */
1553 { 0x0000, 0x0000 }, /* R1549 */
1554 { 0x0000, 0x0000 }, /* R1550 */
1555 { 0x0000, 0x0000 }, /* R1551 */
1556 { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */
1557 { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */
1558 { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */
1559 { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */
1560 { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */
1561 { 0x0000, 0x0000 }, /* R1557 */
1562 { 0x0000, 0x0000 }, /* R1558 */
1563 { 0x0000, 0x0000 }, /* R1559 */
1564 { 0x0000, 0x0000 }, /* R1560 */
1565 { 0x0000, 0x0000 }, /* R1561 */
1566 { 0x0000, 0x0000 }, /* R1562 */
1567 { 0x0000, 0x0000 }, /* R1563 */
1568 { 0x0000, 0x0000 }, /* R1564 */
1569 { 0x0000, 0x0000 }, /* R1565 */
1570 { 0x0000, 0x0000 }, /* R1566 */
1571 { 0x0000, 0x0000 }, /* R1567 */
1572 { 0x0003, 0x0003 }, /* R1568 - Oversampling */
1573 { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
1574};
1575
1576const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = {
1577 0x8994, /* R0 - Software Reset */
1578 0x0000, /* R1 - Power Management (1) */
1579 0x6000, /* R2 - Power Management (2) */
1580 0x0000, /* R3 - Power Management (3) */
1581 0x0000, /* R4 - Power Management (4) */
1582 0x0000, /* R5 - Power Management (5) */
1583 0x0000, /* R6 - Power Management (6) */
1584 0x0000, /* R7 */
1585 0x0000, /* R8 */
1586 0x0000, /* R9 */
1587 0x0000, /* R10 */
1588 0x0000, /* R11 */
1589 0x0000, /* R12 */
1590 0x0000, /* R13 */
1591 0x0000, /* R14 */
1592 0x0000, /* R15 */
1593 0x0000, /* R16 */
1594 0x0000, /* R17 */
1595 0x0000, /* R18 */
1596 0x0000, /* R19 */
1597 0x0000, /* R20 */
1598 0x0000, /* R21 - Input Mixer (1) */
1599 0x0000, /* R22 */
1600 0x0000, /* R23 */
1601 0x008B, /* R24 - Left Line Input 1&2 Volume */
1602 0x008B, /* R25 - Left Line Input 3&4 Volume */
1603 0x008B, /* R26 - Right Line Input 1&2 Volume */
1604 0x008B, /* R27 - Right Line Input 3&4 Volume */
1605 0x006D, /* R28 - Left Output Volume */
1606 0x006D, /* R29 - Right Output Volume */
1607 0x0066, /* R30 - Line Outputs Volume */
1608 0x0020, /* R31 - HPOUT2 Volume */
1609 0x0079, /* R32 - Left OPGA Volume */
1610 0x0079, /* R33 - Right OPGA Volume */
1611 0x0003, /* R34 - SPKMIXL Attenuation */
1612 0x0003, /* R35 - SPKMIXR Attenuation */
1613 0x0011, /* R36 - SPKOUT Mixers */
1614 0x0140, /* R37 - ClassD */
1615 0x0079, /* R38 - Speaker Volume Left */
1616 0x0079, /* R39 - Speaker Volume Right */
1617 0x0000, /* R40 - Input Mixer (2) */
1618 0x0000, /* R41 - Input Mixer (3) */
1619 0x0000, /* R42 - Input Mixer (4) */
1620 0x0000, /* R43 - Input Mixer (5) */
1621 0x0000, /* R44 - Input Mixer (6) */
1622 0x0000, /* R45 - Output Mixer (1) */
1623 0x0000, /* R46 - Output Mixer (2) */
1624 0x0000, /* R47 - Output Mixer (3) */
1625 0x0000, /* R48 - Output Mixer (4) */
1626 0x0000, /* R49 - Output Mixer (5) */
1627 0x0000, /* R50 - Output Mixer (6) */
1628 0x0000, /* R51 - HPOUT2 Mixer */
1629 0x0000, /* R52 - Line Mixer (1) */
1630 0x0000, /* R53 - Line Mixer (2) */
1631 0x0000, /* R54 - Speaker Mixer */
1632 0x0000, /* R55 - Additional Control */
1633 0x0000, /* R56 - AntiPOP (1) */
1634 0x0000, /* R57 - AntiPOP (2) */
1635 0x0000, /* R58 - MICBIAS */
1636 0x000D, /* R59 - LDO 1 */
1637 0x0003, /* R60 - LDO 2 */
1638 0x0000, /* R61 */
1639 0x0000, /* R62 */
1640 0x0000, /* R63 */
1641 0x0000, /* R64 */
1642 0x0000, /* R65 */
1643 0x0000, /* R66 */
1644 0x0000, /* R67 */
1645 0x0000, /* R68 */
1646 0x0000, /* R69 */
1647 0x0000, /* R70 */
1648 0x0000, /* R71 */
1649 0x0000, /* R72 */
1650 0x0000, /* R73 */
1651 0x0000, /* R74 */
1652 0x0000, /* R75 */
1653 0x1F25, /* R76 - Charge Pump (1) */
1654 0x0000, /* R77 */
1655 0x0000, /* R78 */
1656 0x0000, /* R79 */
1657 0x0000, /* R80 */
1658 0x0004, /* R81 - Class W (1) */
1659 0x0000, /* R82 */
1660 0x0000, /* R83 */
1661 0x0000, /* R84 - DC Servo (1) */
1662 0x054A, /* R85 - DC Servo (2) */
1663 0x0000, /* R86 */
1664 0x0000, /* R87 - DC Servo (4) */
1665 0x0000, /* R88 - DC Servo Readback */
1666 0x0000, /* R89 */
1667 0x0000, /* R90 */
1668 0x0000, /* R91 */
1669 0x0000, /* R92 */
1670 0x0000, /* R93 */
1671 0x0000, /* R94 */
1672 0x0000, /* R95 */
1673 0x0000, /* R96 - Analogue HP (1) */
1674 0x0000, /* R97 */
1675 0x0000, /* R98 */
1676 0x0000, /* R99 */
1677 0x0000, /* R100 */
1678 0x0000, /* R101 */
1679 0x0000, /* R102 */
1680 0x0000, /* R103 */
1681 0x0000, /* R104 */
1682 0x0000, /* R105 */
1683 0x0000, /* R106 */
1684 0x0000, /* R107 */
1685 0x0000, /* R108 */
1686 0x0000, /* R109 */
1687 0x0000, /* R110 */
1688 0x0000, /* R111 */
1689 0x0000, /* R112 */
1690 0x0000, /* R113 */
1691 0x0000, /* R114 */
1692 0x0000, /* R115 */
1693 0x0000, /* R116 */
1694 0x0000, /* R117 */
1695 0x0000, /* R118 */
1696 0x0000, /* R119 */
1697 0x0000, /* R120 */
1698 0x0000, /* R121 */
1699 0x0000, /* R122 */
1700 0x0000, /* R123 */
1701 0x0000, /* R124 */
1702 0x0000, /* R125 */
1703 0x0000, /* R126 */
1704 0x0000, /* R127 */
1705 0x0000, /* R128 */
1706 0x0000, /* R129 */
1707 0x0000, /* R130 */
1708 0x0000, /* R131 */
1709 0x0000, /* R132 */
1710 0x0000, /* R133 */
1711 0x0000, /* R134 */
1712 0x0000, /* R135 */
1713 0x0000, /* R136 */
1714 0x0000, /* R137 */
1715 0x0000, /* R138 */
1716 0x0000, /* R139 */
1717 0x0000, /* R140 */
1718 0x0000, /* R141 */
1719 0x0000, /* R142 */
1720 0x0000, /* R143 */
1721 0x0000, /* R144 */
1722 0x0000, /* R145 */
1723 0x0000, /* R146 */
1724 0x0000, /* R147 */
1725 0x0000, /* R148 */
1726 0x0000, /* R149 */
1727 0x0000, /* R150 */
1728 0x0000, /* R151 */
1729 0x0000, /* R152 */
1730 0x0000, /* R153 */
1731 0x0000, /* R154 */
1732 0x0000, /* R155 */
1733 0x0000, /* R156 */
1734 0x0000, /* R157 */
1735 0x0000, /* R158 */
1736 0x0000, /* R159 */
1737 0x0000, /* R160 */
1738 0x0000, /* R161 */
1739 0x0000, /* R162 */
1740 0x0000, /* R163 */
1741 0x0000, /* R164 */
1742 0x0000, /* R165 */
1743 0x0000, /* R166 */
1744 0x0000, /* R167 */
1745 0x0000, /* R168 */
1746 0x0000, /* R169 */
1747 0x0000, /* R170 */
1748 0x0000, /* R171 */
1749 0x0000, /* R172 */
1750 0x0000, /* R173 */
1751 0x0000, /* R174 */
1752 0x0000, /* R175 */
1753 0x0000, /* R176 */
1754 0x0000, /* R177 */
1755 0x0000, /* R178 */
1756 0x0000, /* R179 */
1757 0x0000, /* R180 */
1758 0x0000, /* R181 */
1759 0x0000, /* R182 */
1760 0x0000, /* R183 */
1761 0x0000, /* R184 */
1762 0x0000, /* R185 */
1763 0x0000, /* R186 */
1764 0x0000, /* R187 */
1765 0x0000, /* R188 */
1766 0x0000, /* R189 */
1767 0x0000, /* R190 */
1768 0x0000, /* R191 */
1769 0x0000, /* R192 */
1770 0x0000, /* R193 */
1771 0x0000, /* R194 */
1772 0x0000, /* R195 */
1773 0x0000, /* R196 */
1774 0x0000, /* R197 */
1775 0x0000, /* R198 */
1776 0x0000, /* R199 */
1777 0x0000, /* R200 */
1778 0x0000, /* R201 */
1779 0x0000, /* R202 */
1780 0x0000, /* R203 */
1781 0x0000, /* R204 */
1782 0x0000, /* R205 */
1783 0x0000, /* R206 */
1784 0x0000, /* R207 */
1785 0x0000, /* R208 */
1786 0x0000, /* R209 */
1787 0x0000, /* R210 */
1788 0x0000, /* R211 */
1789 0x0000, /* R212 */
1790 0x0000, /* R213 */
1791 0x0000, /* R214 */
1792 0x0000, /* R215 */
1793 0x0000, /* R216 */
1794 0x0000, /* R217 */
1795 0x0000, /* R218 */
1796 0x0000, /* R219 */
1797 0x0000, /* R220 */
1798 0x0000, /* R221 */
1799 0x0000, /* R222 */
1800 0x0000, /* R223 */
1801 0x0000, /* R224 */
1802 0x0000, /* R225 */
1803 0x0000, /* R226 */
1804 0x0000, /* R227 */
1805 0x0000, /* R228 */
1806 0x0000, /* R229 */
1807 0x0000, /* R230 */
1808 0x0000, /* R231 */
1809 0x0000, /* R232 */
1810 0x0000, /* R233 */
1811 0x0000, /* R234 */
1812 0x0000, /* R235 */
1813 0x0000, /* R236 */
1814 0x0000, /* R237 */
1815 0x0000, /* R238 */
1816 0x0000, /* R239 */
1817 0x0000, /* R240 */
1818 0x0000, /* R241 */
1819 0x0000, /* R242 */
1820 0x0000, /* R243 */
1821 0x0000, /* R244 */
1822 0x0000, /* R245 */
1823 0x0000, /* R246 */
1824 0x0000, /* R247 */
1825 0x0000, /* R248 */
1826 0x0000, /* R249 */
1827 0x0000, /* R250 */
1828 0x0000, /* R251 */
1829 0x0000, /* R252 */
1830 0x0000, /* R253 */
1831 0x0000, /* R254 */
1832 0x0000, /* R255 */
1833 0x0003, /* R256 - Chip Revision */
1834 0x8004, /* R257 - Control Interface */
1835 0x0000, /* R258 */
1836 0x0000, /* R259 */
1837 0x0000, /* R260 */
1838 0x0000, /* R261 */
1839 0x0000, /* R262 */
1840 0x0000, /* R263 */
1841 0x0000, /* R264 */
1842 0x0000, /* R265 */
1843 0x0000, /* R266 */
1844 0x0000, /* R267 */
1845 0x0000, /* R268 */
1846 0x0000, /* R269 */
1847 0x0000, /* R270 */
1848 0x0000, /* R271 */
1849 0x0000, /* R272 - Write Sequencer Ctrl (1) */
1850 0x0000, /* R273 - Write Sequencer Ctrl (2) */
1851 0x0000, /* R274 */
1852 0x0000, /* R275 */
1853 0x0000, /* R276 */
1854 0x0000, /* R277 */
1855 0x0000, /* R278 */
1856 0x0000, /* R279 */
1857 0x0000, /* R280 */
1858 0x0000, /* R281 */
1859 0x0000, /* R282 */
1860 0x0000, /* R283 */
1861 0x0000, /* R284 */
1862 0x0000, /* R285 */
1863 0x0000, /* R286 */
1864 0x0000, /* R287 */
1865 0x0000, /* R288 */
1866 0x0000, /* R289 */
1867 0x0000, /* R290 */
1868 0x0000, /* R291 */
1869 0x0000, /* R292 */
1870 0x0000, /* R293 */
1871 0x0000, /* R294 */
1872 0x0000, /* R295 */
1873 0x0000, /* R296 */
1874 0x0000, /* R297 */
1875 0x0000, /* R298 */
1876 0x0000, /* R299 */
1877 0x0000, /* R300 */
1878 0x0000, /* R301 */
1879 0x0000, /* R302 */
1880 0x0000, /* R303 */
1881 0x0000, /* R304 */
1882 0x0000, /* R305 */
1883 0x0000, /* R306 */
1884 0x0000, /* R307 */
1885 0x0000, /* R308 */
1886 0x0000, /* R309 */
1887 0x0000, /* R310 */
1888 0x0000, /* R311 */
1889 0x0000, /* R312 */
1890 0x0000, /* R313 */
1891 0x0000, /* R314 */
1892 0x0000, /* R315 */
1893 0x0000, /* R316 */
1894 0x0000, /* R317 */
1895 0x0000, /* R318 */
1896 0x0000, /* R319 */
1897 0x0000, /* R320 */
1898 0x0000, /* R321 */
1899 0x0000, /* R322 */
1900 0x0000, /* R323 */
1901 0x0000, /* R324 */
1902 0x0000, /* R325 */
1903 0x0000, /* R326 */
1904 0x0000, /* R327 */
1905 0x0000, /* R328 */
1906 0x0000, /* R329 */
1907 0x0000, /* R330 */
1908 0x0000, /* R331 */
1909 0x0000, /* R332 */
1910 0x0000, /* R333 */
1911 0x0000, /* R334 */
1912 0x0000, /* R335 */
1913 0x0000, /* R336 */
1914 0x0000, /* R337 */
1915 0x0000, /* R338 */
1916 0x0000, /* R339 */
1917 0x0000, /* R340 */
1918 0x0000, /* R341 */
1919 0x0000, /* R342 */
1920 0x0000, /* R343 */
1921 0x0000, /* R344 */
1922 0x0000, /* R345 */
1923 0x0000, /* R346 */
1924 0x0000, /* R347 */
1925 0x0000, /* R348 */
1926 0x0000, /* R349 */
1927 0x0000, /* R350 */
1928 0x0000, /* R351 */
1929 0x0000, /* R352 */
1930 0x0000, /* R353 */
1931 0x0000, /* R354 */
1932 0x0000, /* R355 */
1933 0x0000, /* R356 */
1934 0x0000, /* R357 */
1935 0x0000, /* R358 */
1936 0x0000, /* R359 */
1937 0x0000, /* R360 */
1938 0x0000, /* R361 */
1939 0x0000, /* R362 */
1940 0x0000, /* R363 */
1941 0x0000, /* R364 */
1942 0x0000, /* R365 */
1943 0x0000, /* R366 */
1944 0x0000, /* R367 */
1945 0x0000, /* R368 */
1946 0x0000, /* R369 */
1947 0x0000, /* R370 */
1948 0x0000, /* R371 */
1949 0x0000, /* R372 */
1950 0x0000, /* R373 */
1951 0x0000, /* R374 */
1952 0x0000, /* R375 */
1953 0x0000, /* R376 */
1954 0x0000, /* R377 */
1955 0x0000, /* R378 */
1956 0x0000, /* R379 */
1957 0x0000, /* R380 */
1958 0x0000, /* R381 */
1959 0x0000, /* R382 */
1960 0x0000, /* R383 */
1961 0x0000, /* R384 */
1962 0x0000, /* R385 */
1963 0x0000, /* R386 */
1964 0x0000, /* R387 */
1965 0x0000, /* R388 */
1966 0x0000, /* R389 */
1967 0x0000, /* R390 */
1968 0x0000, /* R391 */
1969 0x0000, /* R392 */
1970 0x0000, /* R393 */
1971 0x0000, /* R394 */
1972 0x0000, /* R395 */
1973 0x0000, /* R396 */
1974 0x0000, /* R397 */
1975 0x0000, /* R398 */
1976 0x0000, /* R399 */
1977 0x0000, /* R400 */
1978 0x0000, /* R401 */
1979 0x0000, /* R402 */
1980 0x0000, /* R403 */
1981 0x0000, /* R404 */
1982 0x0000, /* R405 */
1983 0x0000, /* R406 */
1984 0x0000, /* R407 */
1985 0x0000, /* R408 */
1986 0x0000, /* R409 */
1987 0x0000, /* R410 */
1988 0x0000, /* R411 */
1989 0x0000, /* R412 */
1990 0x0000, /* R413 */
1991 0x0000, /* R414 */
1992 0x0000, /* R415 */
1993 0x0000, /* R416 */
1994 0x0000, /* R417 */
1995 0x0000, /* R418 */
1996 0x0000, /* R419 */
1997 0x0000, /* R420 */
1998 0x0000, /* R421 */
1999 0x0000, /* R422 */
2000 0x0000, /* R423 */
2001 0x0000, /* R424 */
2002 0x0000, /* R425 */
2003 0x0000, /* R426 */
2004 0x0000, /* R427 */
2005 0x0000, /* R428 */
2006 0x0000, /* R429 */
2007 0x0000, /* R430 */
2008 0x0000, /* R431 */
2009 0x0000, /* R432 */
2010 0x0000, /* R433 */
2011 0x0000, /* R434 */
2012 0x0000, /* R435 */
2013 0x0000, /* R436 */
2014 0x0000, /* R437 */
2015 0x0000, /* R438 */
2016 0x0000, /* R439 */
2017 0x0000, /* R440 */
2018 0x0000, /* R441 */
2019 0x0000, /* R442 */
2020 0x0000, /* R443 */
2021 0x0000, /* R444 */
2022 0x0000, /* R445 */
2023 0x0000, /* R446 */
2024 0x0000, /* R447 */
2025 0x0000, /* R448 */
2026 0x0000, /* R449 */
2027 0x0000, /* R450 */
2028 0x0000, /* R451 */
2029 0x0000, /* R452 */
2030 0x0000, /* R453 */
2031 0x0000, /* R454 */
2032 0x0000, /* R455 */
2033 0x0000, /* R456 */
2034 0x0000, /* R457 */
2035 0x0000, /* R458 */
2036 0x0000, /* R459 */
2037 0x0000, /* R460 */
2038 0x0000, /* R461 */
2039 0x0000, /* R462 */
2040 0x0000, /* R463 */
2041 0x0000, /* R464 */
2042 0x0000, /* R465 */
2043 0x0000, /* R466 */
2044 0x0000, /* R467 */
2045 0x0000, /* R468 */
2046 0x0000, /* R469 */
2047 0x0000, /* R470 */
2048 0x0000, /* R471 */
2049 0x0000, /* R472 */
2050 0x0000, /* R473 */
2051 0x0000, /* R474 */
2052 0x0000, /* R475 */
2053 0x0000, /* R476 */
2054 0x0000, /* R477 */
2055 0x0000, /* R478 */
2056 0x0000, /* R479 */
2057 0x0000, /* R480 */
2058 0x0000, /* R481 */
2059 0x0000, /* R482 */
2060 0x0000, /* R483 */
2061 0x0000, /* R484 */
2062 0x0000, /* R485 */
2063 0x0000, /* R486 */
2064 0x0000, /* R487 */
2065 0x0000, /* R488 */
2066 0x0000, /* R489 */
2067 0x0000, /* R490 */
2068 0x0000, /* R491 */
2069 0x0000, /* R492 */
2070 0x0000, /* R493 */
2071 0x0000, /* R494 */
2072 0x0000, /* R495 */
2073 0x0000, /* R496 */
2074 0x0000, /* R497 */
2075 0x0000, /* R498 */
2076 0x0000, /* R499 */
2077 0x0000, /* R500 */
2078 0x0000, /* R501 */
2079 0x0000, /* R502 */
2080 0x0000, /* R503 */
2081 0x0000, /* R504 */
2082 0x0000, /* R505 */
2083 0x0000, /* R506 */
2084 0x0000, /* R507 */
2085 0x0000, /* R508 */
2086 0x0000, /* R509 */
2087 0x0000, /* R510 */
2088 0x0000, /* R511 */
2089 0x0000, /* R512 - AIF1 Clocking (1) */
2090 0x0000, /* R513 - AIF1 Clocking (2) */
2091 0x0000, /* R514 */
2092 0x0000, /* R515 */
2093 0x0000, /* R516 - AIF2 Clocking (1) */
2094 0x0000, /* R517 - AIF2 Clocking (2) */
2095 0x0000, /* R518 */
2096 0x0000, /* R519 */
2097 0x0000, /* R520 - Clocking (1) */
2098 0x0000, /* R521 - Clocking (2) */
2099 0x0000, /* R522 */
2100 0x0000, /* R523 */
2101 0x0000, /* R524 */
2102 0x0000, /* R525 */
2103 0x0000, /* R526 */
2104 0x0000, /* R527 */
2105 0x0083, /* R528 - AIF1 Rate */
2106 0x0083, /* R529 - AIF2 Rate */
2107 0x0000, /* R530 - Rate Status */
2108 0x0000, /* R531 */
2109 0x0000, /* R532 */
2110 0x0000, /* R533 */
2111 0x0000, /* R534 */
2112 0x0000, /* R535 */
2113 0x0000, /* R536 */
2114 0x0000, /* R537 */
2115 0x0000, /* R538 */
2116 0x0000, /* R539 */
2117 0x0000, /* R540 */
2118 0x0000, /* R541 */
2119 0x0000, /* R542 */
2120 0x0000, /* R543 */
2121 0x0000, /* R544 - FLL1 Control (1) */
2122 0x0000, /* R545 - FLL1 Control (2) */
2123 0x0000, /* R546 - FLL1 Control (3) */
2124 0x0000, /* R547 - FLL1 Control (4) */
2125 0x0C80, /* R548 - FLL1 Control (5) */
2126 0x0000, /* R549 */
2127 0x0000, /* R550 */
2128 0x0000, /* R551 */
2129 0x0000, /* R552 */
2130 0x0000, /* R553 */
2131 0x0000, /* R554 */
2132 0x0000, /* R555 */
2133 0x0000, /* R556 */
2134 0x0000, /* R557 */
2135 0x0000, /* R558 */
2136 0x0000, /* R559 */
2137 0x0000, /* R560 */
2138 0x0000, /* R561 */
2139 0x0000, /* R562 */
2140 0x0000, /* R563 */
2141 0x0000, /* R564 */
2142 0x0000, /* R565 */
2143 0x0000, /* R566 */
2144 0x0000, /* R567 */
2145 0x0000, /* R568 */
2146 0x0000, /* R569 */
2147 0x0000, /* R570 */
2148 0x0000, /* R571 */
2149 0x0000, /* R572 */
2150 0x0000, /* R573 */
2151 0x0000, /* R574 */
2152 0x0000, /* R575 */
2153 0x0000, /* R576 - FLL2 Control (1) */
2154 0x0000, /* R577 - FLL2 Control (2) */
2155 0x0000, /* R578 - FLL2 Control (3) */
2156 0x0000, /* R579 - FLL2 Control (4) */
2157 0x0C80, /* R580 - FLL2 Control (5) */
2158 0x0000, /* R581 */
2159 0x0000, /* R582 */
2160 0x0000, /* R583 */
2161 0x0000, /* R584 */
2162 0x0000, /* R585 */
2163 0x0000, /* R586 */
2164 0x0000, /* R587 */
2165 0x0000, /* R588 */
2166 0x0000, /* R589 */
2167 0x0000, /* R590 */
2168 0x0000, /* R591 */
2169 0x0000, /* R592 */
2170 0x0000, /* R593 */
2171 0x0000, /* R594 */
2172 0x0000, /* R595 */
2173 0x0000, /* R596 */
2174 0x0000, /* R597 */
2175 0x0000, /* R598 */
2176 0x0000, /* R599 */
2177 0x0000, /* R600 */
2178 0x0000, /* R601 */
2179 0x0000, /* R602 */
2180 0x0000, /* R603 */
2181 0x0000, /* R604 */
2182 0x0000, /* R605 */
2183 0x0000, /* R606 */
2184 0x0000, /* R607 */
2185 0x0000, /* R608 */
2186 0x0000, /* R609 */
2187 0x0000, /* R610 */
2188 0x0000, /* R611 */
2189 0x0000, /* R612 */
2190 0x0000, /* R613 */
2191 0x0000, /* R614 */
2192 0x0000, /* R615 */
2193 0x0000, /* R616 */
2194 0x0000, /* R617 */
2195 0x0000, /* R618 */
2196 0x0000, /* R619 */
2197 0x0000, /* R620 */
2198 0x0000, /* R621 */
2199 0x0000, /* R622 */
2200 0x0000, /* R623 */
2201 0x0000, /* R624 */
2202 0x0000, /* R625 */
2203 0x0000, /* R626 */
2204 0x0000, /* R627 */
2205 0x0000, /* R628 */
2206 0x0000, /* R629 */
2207 0x0000, /* R630 */
2208 0x0000, /* R631 */
2209 0x0000, /* R632 */
2210 0x0000, /* R633 */
2211 0x0000, /* R634 */
2212 0x0000, /* R635 */
2213 0x0000, /* R636 */
2214 0x0000, /* R637 */
2215 0x0000, /* R638 */
2216 0x0000, /* R639 */
2217 0x0000, /* R640 */
2218 0x0000, /* R641 */
2219 0x0000, /* R642 */
2220 0x0000, /* R643 */
2221 0x0000, /* R644 */
2222 0x0000, /* R645 */
2223 0x0000, /* R646 */
2224 0x0000, /* R647 */
2225 0x0000, /* R648 */
2226 0x0000, /* R649 */
2227 0x0000, /* R650 */
2228 0x0000, /* R651 */
2229 0x0000, /* R652 */
2230 0x0000, /* R653 */
2231 0x0000, /* R654 */
2232 0x0000, /* R655 */
2233 0x0000, /* R656 */
2234 0x0000, /* R657 */
2235 0x0000, /* R658 */
2236 0x0000, /* R659 */
2237 0x0000, /* R660 */
2238 0x0000, /* R661 */
2239 0x0000, /* R662 */
2240 0x0000, /* R663 */
2241 0x0000, /* R664 */
2242 0x0000, /* R665 */
2243 0x0000, /* R666 */
2244 0x0000, /* R667 */
2245 0x0000, /* R668 */
2246 0x0000, /* R669 */
2247 0x0000, /* R670 */
2248 0x0000, /* R671 */
2249 0x0000, /* R672 */
2250 0x0000, /* R673 */
2251 0x0000, /* R674 */
2252 0x0000, /* R675 */
2253 0x0000, /* R676 */
2254 0x0000, /* R677 */
2255 0x0000, /* R678 */
2256 0x0000, /* R679 */
2257 0x0000, /* R680 */
2258 0x0000, /* R681 */
2259 0x0000, /* R682 */
2260 0x0000, /* R683 */
2261 0x0000, /* R684 */
2262 0x0000, /* R685 */
2263 0x0000, /* R686 */
2264 0x0000, /* R687 */
2265 0x0000, /* R688 */
2266 0x0000, /* R689 */
2267 0x0000, /* R690 */
2268 0x0000, /* R691 */
2269 0x0000, /* R692 */
2270 0x0000, /* R693 */
2271 0x0000, /* R694 */
2272 0x0000, /* R695 */
2273 0x0000, /* R696 */
2274 0x0000, /* R697 */
2275 0x0000, /* R698 */
2276 0x0000, /* R699 */
2277 0x0000, /* R700 */
2278 0x0000, /* R701 */
2279 0x0000, /* R702 */
2280 0x0000, /* R703 */
2281 0x0000, /* R704 */
2282 0x0000, /* R705 */
2283 0x0000, /* R706 */
2284 0x0000, /* R707 */
2285 0x0000, /* R708 */
2286 0x0000, /* R709 */
2287 0x0000, /* R710 */
2288 0x0000, /* R711 */
2289 0x0000, /* R712 */
2290 0x0000, /* R713 */
2291 0x0000, /* R714 */
2292 0x0000, /* R715 */
2293 0x0000, /* R716 */
2294 0x0000, /* R717 */
2295 0x0000, /* R718 */
2296 0x0000, /* R719 */
2297 0x0000, /* R720 */
2298 0x0000, /* R721 */
2299 0x0000, /* R722 */
2300 0x0000, /* R723 */
2301 0x0000, /* R724 */
2302 0x0000, /* R725 */
2303 0x0000, /* R726 */
2304 0x0000, /* R727 */
2305 0x0000, /* R728 */
2306 0x0000, /* R729 */
2307 0x0000, /* R730 */
2308 0x0000, /* R731 */
2309 0x0000, /* R732 */
2310 0x0000, /* R733 */
2311 0x0000, /* R734 */
2312 0x0000, /* R735 */
2313 0x0000, /* R736 */
2314 0x0000, /* R737 */
2315 0x0000, /* R738 */
2316 0x0000, /* R739 */
2317 0x0000, /* R740 */
2318 0x0000, /* R741 */
2319 0x0000, /* R742 */
2320 0x0000, /* R743 */
2321 0x0000, /* R744 */
2322 0x0000, /* R745 */
2323 0x0000, /* R746 */
2324 0x0000, /* R747 */
2325 0x0000, /* R748 */
2326 0x0000, /* R749 */
2327 0x0000, /* R750 */
2328 0x0000, /* R751 */
2329 0x0000, /* R752 */
2330 0x0000, /* R753 */
2331 0x0000, /* R754 */
2332 0x0000, /* R755 */
2333 0x0000, /* R756 */
2334 0x0000, /* R757 */
2335 0x0000, /* R758 */
2336 0x0000, /* R759 */
2337 0x0000, /* R760 */
2338 0x0000, /* R761 */
2339 0x0000, /* R762 */
2340 0x0000, /* R763 */
2341 0x0000, /* R764 */
2342 0x0000, /* R765 */
2343 0x0000, /* R766 */
2344 0x0000, /* R767 */
2345 0x4050, /* R768 - AIF1 Control (1) */
2346 0x4000, /* R769 - AIF1 Control (2) */
2347 0x0000, /* R770 - AIF1 Master/Slave */
2348 0x0040, /* R771 - AIF1 BCLK */
2349 0x0040, /* R772 - AIF1ADC LRCLK */
2350 0x0040, /* R773 - AIF1DAC LRCLK */
2351 0x0004, /* R774 - AIF1DAC Data */
2352 0x0100, /* R775 - AIF1ADC Data */
2353 0x0000, /* R776 */
2354 0x0000, /* R777 */
2355 0x0000, /* R778 */
2356 0x0000, /* R779 */
2357 0x0000, /* R780 */
2358 0x0000, /* R781 */
2359 0x0000, /* R782 */
2360 0x0000, /* R783 */
2361 0x4050, /* R784 - AIF2 Control (1) */
2362 0x4000, /* R785 - AIF2 Control (2) */
2363 0x0000, /* R786 - AIF2 Master/Slave */
2364 0x0040, /* R787 - AIF2 BCLK */
2365 0x0040, /* R788 - AIF2ADC LRCLK */
2366 0x0040, /* R789 - AIF2DAC LRCLK */
2367 0x0000, /* R790 - AIF2DAC Data */
2368 0x0000, /* R791 - AIF2ADC Data */
2369 0x0000, /* R792 */
2370 0x0000, /* R793 */
2371 0x0000, /* R794 */
2372 0x0000, /* R795 */
2373 0x0000, /* R796 */
2374 0x0000, /* R797 */
2375 0x0000, /* R798 */
2376 0x0000, /* R799 */
2377 0x0000, /* R800 */
2378 0x0000, /* R801 */
2379 0x0000, /* R802 */
2380 0x0000, /* R803 */
2381 0x0000, /* R804 */
2382 0x0000, /* R805 */
2383 0x0000, /* R806 */
2384 0x0000, /* R807 */
2385 0x0000, /* R808 */
2386 0x0000, /* R809 */
2387 0x0000, /* R810 */
2388 0x0000, /* R811 */
2389 0x0000, /* R812 */
2390 0x0000, /* R813 */
2391 0x0000, /* R814 */
2392 0x0000, /* R815 */
2393 0x0000, /* R816 */
2394 0x0000, /* R817 */
2395 0x0000, /* R818 */
2396 0x0000, /* R819 */
2397 0x0000, /* R820 */
2398 0x0000, /* R821 */
2399 0x0000, /* R822 */
2400 0x0000, /* R823 */
2401 0x0000, /* R824 */
2402 0x0000, /* R825 */
2403 0x0000, /* R826 */
2404 0x0000, /* R827 */
2405 0x0000, /* R828 */
2406 0x0000, /* R829 */
2407 0x0000, /* R830 */
2408 0x0000, /* R831 */
2409 0x0000, /* R832 */
2410 0x0000, /* R833 */
2411 0x0000, /* R834 */
2412 0x0000, /* R835 */
2413 0x0000, /* R836 */
2414 0x0000, /* R837 */
2415 0x0000, /* R838 */
2416 0x0000, /* R839 */
2417 0x0000, /* R840 */
2418 0x0000, /* R841 */
2419 0x0000, /* R842 */
2420 0x0000, /* R843 */
2421 0x0000, /* R844 */
2422 0x0000, /* R845 */
2423 0x0000, /* R846 */
2424 0x0000, /* R847 */
2425 0x0000, /* R848 */
2426 0x0000, /* R849 */
2427 0x0000, /* R850 */
2428 0x0000, /* R851 */
2429 0x0000, /* R852 */
2430 0x0000, /* R853 */
2431 0x0000, /* R854 */
2432 0x0000, /* R855 */
2433 0x0000, /* R856 */
2434 0x0000, /* R857 */
2435 0x0000, /* R858 */
2436 0x0000, /* R859 */
2437 0x0000, /* R860 */
2438 0x0000, /* R861 */
2439 0x0000, /* R862 */
2440 0x0000, /* R863 */
2441 0x0000, /* R864 */
2442 0x0000, /* R865 */
2443 0x0000, /* R866 */
2444 0x0000, /* R867 */
2445 0x0000, /* R868 */
2446 0x0000, /* R869 */
2447 0x0000, /* R870 */
2448 0x0000, /* R871 */
2449 0x0000, /* R872 */
2450 0x0000, /* R873 */
2451 0x0000, /* R874 */
2452 0x0000, /* R875 */
2453 0x0000, /* R876 */
2454 0x0000, /* R877 */
2455 0x0000, /* R878 */
2456 0x0000, /* R879 */
2457 0x0000, /* R880 */
2458 0x0000, /* R881 */
2459 0x0000, /* R882 */
2460 0x0000, /* R883 */
2461 0x0000, /* R884 */
2462 0x0000, /* R885 */
2463 0x0000, /* R886 */
2464 0x0000, /* R887 */
2465 0x0000, /* R888 */
2466 0x0000, /* R889 */
2467 0x0000, /* R890 */
2468 0x0000, /* R891 */
2469 0x0000, /* R892 */
2470 0x0000, /* R893 */
2471 0x0000, /* R894 */
2472 0x0000, /* R895 */
2473 0x0000, /* R896 */
2474 0x0000, /* R897 */
2475 0x0000, /* R898 */
2476 0x0000, /* R899 */
2477 0x0000, /* R900 */
2478 0x0000, /* R901 */
2479 0x0000, /* R902 */
2480 0x0000, /* R903 */
2481 0x0000, /* R904 */
2482 0x0000, /* R905 */
2483 0x0000, /* R906 */
2484 0x0000, /* R907 */
2485 0x0000, /* R908 */
2486 0x0000, /* R909 */
2487 0x0000, /* R910 */
2488 0x0000, /* R911 */
2489 0x0000, /* R912 */
2490 0x0000, /* R913 */
2491 0x0000, /* R914 */
2492 0x0000, /* R915 */
2493 0x0000, /* R916 */
2494 0x0000, /* R917 */
2495 0x0000, /* R918 */
2496 0x0000, /* R919 */
2497 0x0000, /* R920 */
2498 0x0000, /* R921 */
2499 0x0000, /* R922 */
2500 0x0000, /* R923 */
2501 0x0000, /* R924 */
2502 0x0000, /* R925 */
2503 0x0000, /* R926 */
2504 0x0000, /* R927 */
2505 0x0000, /* R928 */
2506 0x0000, /* R929 */
2507 0x0000, /* R930 */
2508 0x0000, /* R931 */
2509 0x0000, /* R932 */
2510 0x0000, /* R933 */
2511 0x0000, /* R934 */
2512 0x0000, /* R935 */
2513 0x0000, /* R936 */
2514 0x0000, /* R937 */
2515 0x0000, /* R938 */
2516 0x0000, /* R939 */
2517 0x0000, /* R940 */
2518 0x0000, /* R941 */
2519 0x0000, /* R942 */
2520 0x0000, /* R943 */
2521 0x0000, /* R944 */
2522 0x0000, /* R945 */
2523 0x0000, /* R946 */
2524 0x0000, /* R947 */
2525 0x0000, /* R948 */
2526 0x0000, /* R949 */
2527 0x0000, /* R950 */
2528 0x0000, /* R951 */
2529 0x0000, /* R952 */
2530 0x0000, /* R953 */
2531 0x0000, /* R954 */
2532 0x0000, /* R955 */
2533 0x0000, /* R956 */
2534 0x0000, /* R957 */
2535 0x0000, /* R958 */
2536 0x0000, /* R959 */
2537 0x0000, /* R960 */
2538 0x0000, /* R961 */
2539 0x0000, /* R962 */
2540 0x0000, /* R963 */
2541 0x0000, /* R964 */
2542 0x0000, /* R965 */
2543 0x0000, /* R966 */
2544 0x0000, /* R967 */
2545 0x0000, /* R968 */
2546 0x0000, /* R969 */
2547 0x0000, /* R970 */
2548 0x0000, /* R971 */
2549 0x0000, /* R972 */
2550 0x0000, /* R973 */
2551 0x0000, /* R974 */
2552 0x0000, /* R975 */
2553 0x0000, /* R976 */
2554 0x0000, /* R977 */
2555 0x0000, /* R978 */
2556 0x0000, /* R979 */
2557 0x0000, /* R980 */
2558 0x0000, /* R981 */
2559 0x0000, /* R982 */
2560 0x0000, /* R983 */
2561 0x0000, /* R984 */
2562 0x0000, /* R985 */
2563 0x0000, /* R986 */
2564 0x0000, /* R987 */
2565 0x0000, /* R988 */
2566 0x0000, /* R989 */
2567 0x0000, /* R990 */
2568 0x0000, /* R991 */
2569 0x0000, /* R992 */
2570 0x0000, /* R993 */
2571 0x0000, /* R994 */
2572 0x0000, /* R995 */
2573 0x0000, /* R996 */
2574 0x0000, /* R997 */
2575 0x0000, /* R998 */
2576 0x0000, /* R999 */
2577 0x0000, /* R1000 */
2578 0x0000, /* R1001 */
2579 0x0000, /* R1002 */
2580 0x0000, /* R1003 */
2581 0x0000, /* R1004 */
2582 0x0000, /* R1005 */
2583 0x0000, /* R1006 */
2584 0x0000, /* R1007 */
2585 0x0000, /* R1008 */
2586 0x0000, /* R1009 */
2587 0x0000, /* R1010 */
2588 0x0000, /* R1011 */
2589 0x0000, /* R1012 */
2590 0x0000, /* R1013 */
2591 0x0000, /* R1014 */
2592 0x0000, /* R1015 */
2593 0x0000, /* R1016 */
2594 0x0000, /* R1017 */
2595 0x0000, /* R1018 */
2596 0x0000, /* R1019 */
2597 0x0000, /* R1020 */
2598 0x0000, /* R1021 */
2599 0x0000, /* R1022 */
2600 0x0000, /* R1023 */
2601 0x00C0, /* R1024 - AIF1 ADC1 Left Volume */
2602 0x00C0, /* R1025 - AIF1 ADC1 Right Volume */
2603 0x00C0, /* R1026 - AIF1 DAC1 Left Volume */
2604 0x00C0, /* R1027 - AIF1 DAC1 Right Volume */
2605 0x00C0, /* R1028 - AIF1 ADC2 Left Volume */
2606 0x00C0, /* R1029 - AIF1 ADC2 Right Volume */
2607 0x00C0, /* R1030 - AIF1 DAC2 Left Volume */
2608 0x00C0, /* R1031 - AIF1 DAC2 Right Volume */
2609 0x0000, /* R1032 */
2610 0x0000, /* R1033 */
2611 0x0000, /* R1034 */
2612 0x0000, /* R1035 */
2613 0x0000, /* R1036 */
2614 0x0000, /* R1037 */
2615 0x0000, /* R1038 */
2616 0x0000, /* R1039 */
2617 0x0000, /* R1040 - AIF1 ADC1 Filters */
2618 0x0000, /* R1041 - AIF1 ADC2 Filters */
2619 0x0000, /* R1042 */
2620 0x0000, /* R1043 */
2621 0x0000, /* R1044 */
2622 0x0000, /* R1045 */
2623 0x0000, /* R1046 */
2624 0x0000, /* R1047 */
2625 0x0000, /* R1048 */
2626 0x0000, /* R1049 */
2627 0x0000, /* R1050 */
2628 0x0000, /* R1051 */
2629 0x0000, /* R1052 */
2630 0x0000, /* R1053 */
2631 0x0000, /* R1054 */
2632 0x0000, /* R1055 */
2633 0x0200, /* R1056 - AIF1 DAC1 Filters (1) */
2634 0x0010, /* R1057 - AIF1 DAC1 Filters (2) */
2635 0x0200, /* R1058 - AIF1 DAC2 Filters (1) */
2636 0x0010, /* R1059 - AIF1 DAC2 Filters (2) */
2637 0x0000, /* R1060 */
2638 0x0000, /* R1061 */
2639 0x0000, /* R1062 */
2640 0x0000, /* R1063 */
2641 0x0000, /* R1064 */
2642 0x0000, /* R1065 */
2643 0x0000, /* R1066 */
2644 0x0000, /* R1067 */
2645 0x0000, /* R1068 */
2646 0x0000, /* R1069 */
2647 0x0000, /* R1070 */
2648 0x0000, /* R1071 */
2649 0x0000, /* R1072 */
2650 0x0000, /* R1073 */
2651 0x0000, /* R1074 */
2652 0x0000, /* R1075 */
2653 0x0000, /* R1076 */
2654 0x0000, /* R1077 */
2655 0x0000, /* R1078 */
2656 0x0000, /* R1079 */
2657 0x0000, /* R1080 */
2658 0x0000, /* R1081 */
2659 0x0000, /* R1082 */
2660 0x0000, /* R1083 */
2661 0x0000, /* R1084 */
2662 0x0000, /* R1085 */
2663 0x0000, /* R1086 */
2664 0x0000, /* R1087 */
2665 0x0098, /* R1088 - AIF1 DRC1 (1) */
2666 0x0845, /* R1089 - AIF1 DRC1 (2) */
2667 0x0000, /* R1090 - AIF1 DRC1 (3) */
2668 0x0000, /* R1091 - AIF1 DRC1 (4) */
2669 0x0000, /* R1092 - AIF1 DRC1 (5) */
2670 0x0000, /* R1093 */
2671 0x0000, /* R1094 */
2672 0x0000, /* R1095 */
2673 0x0000, /* R1096 */
2674 0x0000, /* R1097 */
2675 0x0000, /* R1098 */
2676 0x0000, /* R1099 */
2677 0x0000, /* R1100 */
2678 0x0000, /* R1101 */
2679 0x0000, /* R1102 */
2680 0x0000, /* R1103 */
2681 0x0098, /* R1104 - AIF1 DRC2 (1) */
2682 0x0845, /* R1105 - AIF1 DRC2 (2) */
2683 0x0000, /* R1106 - AIF1 DRC2 (3) */
2684 0x0000, /* R1107 - AIF1 DRC2 (4) */
2685 0x0000, /* R1108 - AIF1 DRC2 (5) */
2686 0x0000, /* R1109 */
2687 0x0000, /* R1110 */
2688 0x0000, /* R1111 */
2689 0x0000, /* R1112 */
2690 0x0000, /* R1113 */
2691 0x0000, /* R1114 */
2692 0x0000, /* R1115 */
2693 0x0000, /* R1116 */
2694 0x0000, /* R1117 */
2695 0x0000, /* R1118 */
2696 0x0000, /* R1119 */
2697 0x0000, /* R1120 */
2698 0x0000, /* R1121 */
2699 0x0000, /* R1122 */
2700 0x0000, /* R1123 */
2701 0x0000, /* R1124 */
2702 0x0000, /* R1125 */
2703 0x0000, /* R1126 */
2704 0x0000, /* R1127 */
2705 0x0000, /* R1128 */
2706 0x0000, /* R1129 */
2707 0x0000, /* R1130 */
2708 0x0000, /* R1131 */
2709 0x0000, /* R1132 */
2710 0x0000, /* R1133 */
2711 0x0000, /* R1134 */
2712 0x0000, /* R1135 */
2713 0x0000, /* R1136 */
2714 0x0000, /* R1137 */
2715 0x0000, /* R1138 */
2716 0x0000, /* R1139 */
2717 0x0000, /* R1140 */
2718 0x0000, /* R1141 */
2719 0x0000, /* R1142 */
2720 0x0000, /* R1143 */
2721 0x0000, /* R1144 */
2722 0x0000, /* R1145 */
2723 0x0000, /* R1146 */
2724 0x0000, /* R1147 */
2725 0x0000, /* R1148 */
2726 0x0000, /* R1149 */
2727 0x0000, /* R1150 */
2728 0x0000, /* R1151 */
2729 0x6318, /* R1152 - AIF1 DAC1 EQ Gains (1) */
2730 0x6300, /* R1153 - AIF1 DAC1 EQ Gains (2) */
2731 0x0FCA, /* R1154 - AIF1 DAC1 EQ Band 1 A */
2732 0x0400, /* R1155 - AIF1 DAC1 EQ Band 1 B */
2733 0x00D8, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
2734 0x1EB5, /* R1157 - AIF1 DAC1 EQ Band 2 A */
2735 0xF145, /* R1158 - AIF1 DAC1 EQ Band 2 B */
2736 0x0B75, /* R1159 - AIF1 DAC1 EQ Band 2 C */
2737 0x01C5, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
2738 0x1C58, /* R1161 - AIF1 DAC1 EQ Band 3 A */
2739 0xF373, /* R1162 - AIF1 DAC1 EQ Band 3 B */
2740 0x0A54, /* R1163 - AIF1 DAC1 EQ Band 3 C */
2741 0x0558, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
2742 0x168E, /* R1165 - AIF1 DAC1 EQ Band 4 A */
2743 0xF829, /* R1166 - AIF1 DAC1 EQ Band 4 B */
2744 0x07AD, /* R1167 - AIF1 DAC1 EQ Band 4 C */
2745 0x1103, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
2746 0x0564, /* R1169 - AIF1 DAC1 EQ Band 5 A */
2747 0x0559, /* R1170 - AIF1 DAC1 EQ Band 5 B */
2748 0x4000, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
2749 0x0000, /* R1172 */
2750 0x0000, /* R1173 */
2751 0x0000, /* R1174 */
2752 0x0000, /* R1175 */
2753 0x0000, /* R1176 */
2754 0x0000, /* R1177 */
2755 0x0000, /* R1178 */
2756 0x0000, /* R1179 */
2757 0x0000, /* R1180 */
2758 0x0000, /* R1181 */
2759 0x0000, /* R1182 */
2760 0x0000, /* R1183 */
2761 0x6318, /* R1184 - AIF1 DAC2 EQ Gains (1) */
2762 0x6300, /* R1185 - AIF1 DAC2 EQ Gains (2) */
2763 0x0FCA, /* R1186 - AIF1 DAC2 EQ Band 1 A */
2764 0x0400, /* R1187 - AIF1 DAC2 EQ Band 1 B */
2765 0x00D8, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
2766 0x1EB5, /* R1189 - AIF1 DAC2 EQ Band 2 A */
2767 0xF145, /* R1190 - AIF1 DAC2 EQ Band 2 B */
2768 0x0B75, /* R1191 - AIF1 DAC2 EQ Band 2 C */
2769 0x01C5, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
2770 0x1C58, /* R1193 - AIF1 DAC2 EQ Band 3 A */
2771 0xF373, /* R1194 - AIF1 DAC2 EQ Band 3 B */
2772 0x0A54, /* R1195 - AIF1 DAC2 EQ Band 3 C */
2773 0x0558, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
2774 0x168E, /* R1197 - AIF1 DAC2 EQ Band 4 A */
2775 0xF829, /* R1198 - AIF1 DAC2 EQ Band 4 B */
2776 0x07AD, /* R1199 - AIF1 DAC2 EQ Band 4 C */
2777 0x1103, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
2778 0x0564, /* R1201 - AIF1 DAC2 EQ Band 5 A */
2779 0x0559, /* R1202 - AIF1 DAC2 EQ Band 5 B */
2780 0x4000, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
2781 0x0000, /* R1204 */
2782 0x0000, /* R1205 */
2783 0x0000, /* R1206 */
2784 0x0000, /* R1207 */
2785 0x0000, /* R1208 */
2786 0x0000, /* R1209 */
2787 0x0000, /* R1210 */
2788 0x0000, /* R1211 */
2789 0x0000, /* R1212 */
2790 0x0000, /* R1213 */
2791 0x0000, /* R1214 */
2792 0x0000, /* R1215 */
2793 0x0000, /* R1216 */
2794 0x0000, /* R1217 */
2795 0x0000, /* R1218 */
2796 0x0000, /* R1219 */
2797 0x0000, /* R1220 */
2798 0x0000, /* R1221 */
2799 0x0000, /* R1222 */
2800 0x0000, /* R1223 */
2801 0x0000, /* R1224 */
2802 0x0000, /* R1225 */
2803 0x0000, /* R1226 */
2804 0x0000, /* R1227 */
2805 0x0000, /* R1228 */
2806 0x0000, /* R1229 */
2807 0x0000, /* R1230 */
2808 0x0000, /* R1231 */
2809 0x0000, /* R1232 */
2810 0x0000, /* R1233 */
2811 0x0000, /* R1234 */
2812 0x0000, /* R1235 */
2813 0x0000, /* R1236 */
2814 0x0000, /* R1237 */
2815 0x0000, /* R1238 */
2816 0x0000, /* R1239 */
2817 0x0000, /* R1240 */
2818 0x0000, /* R1241 */
2819 0x0000, /* R1242 */
2820 0x0000, /* R1243 */
2821 0x0000, /* R1244 */
2822 0x0000, /* R1245 */
2823 0x0000, /* R1246 */
2824 0x0000, /* R1247 */
2825 0x0000, /* R1248 */
2826 0x0000, /* R1249 */
2827 0x0000, /* R1250 */
2828 0x0000, /* R1251 */
2829 0x0000, /* R1252 */
2830 0x0000, /* R1253 */
2831 0x0000, /* R1254 */
2832 0x0000, /* R1255 */
2833 0x0000, /* R1256 */
2834 0x0000, /* R1257 */
2835 0x0000, /* R1258 */
2836 0x0000, /* R1259 */
2837 0x0000, /* R1260 */
2838 0x0000, /* R1261 */
2839 0x0000, /* R1262 */
2840 0x0000, /* R1263 */
2841 0x0000, /* R1264 */
2842 0x0000, /* R1265 */
2843 0x0000, /* R1266 */
2844 0x0000, /* R1267 */
2845 0x0000, /* R1268 */
2846 0x0000, /* R1269 */
2847 0x0000, /* R1270 */
2848 0x0000, /* R1271 */
2849 0x0000, /* R1272 */
2850 0x0000, /* R1273 */
2851 0x0000, /* R1274 */
2852 0x0000, /* R1275 */
2853 0x0000, /* R1276 */
2854 0x0000, /* R1277 */
2855 0x0000, /* R1278 */
2856 0x0000, /* R1279 */
2857 0x00C0, /* R1280 - AIF2 ADC Left Volume */
2858 0x00C0, /* R1281 - AIF2 ADC Right Volume */
2859 0x00C0, /* R1282 - AIF2 DAC Left Volume */
2860 0x00C0, /* R1283 - AIF2 DAC Right Volume */
2861 0x0000, /* R1284 */
2862 0x0000, /* R1285 */
2863 0x0000, /* R1286 */
2864 0x0000, /* R1287 */
2865 0x0000, /* R1288 */
2866 0x0000, /* R1289 */
2867 0x0000, /* R1290 */
2868 0x0000, /* R1291 */
2869 0x0000, /* R1292 */
2870 0x0000, /* R1293 */
2871 0x0000, /* R1294 */
2872 0x0000, /* R1295 */
2873 0x0000, /* R1296 - AIF2 ADC Filters */
2874 0x0000, /* R1297 */
2875 0x0000, /* R1298 */
2876 0x0000, /* R1299 */
2877 0x0000, /* R1300 */
2878 0x0000, /* R1301 */
2879 0x0000, /* R1302 */
2880 0x0000, /* R1303 */
2881 0x0000, /* R1304 */
2882 0x0000, /* R1305 */
2883 0x0000, /* R1306 */
2884 0x0000, /* R1307 */
2885 0x0000, /* R1308 */
2886 0x0000, /* R1309 */
2887 0x0000, /* R1310 */
2888 0x0000, /* R1311 */
2889 0x0200, /* R1312 - AIF2 DAC Filters (1) */
2890 0x0010, /* R1313 - AIF2 DAC Filters (2) */
2891 0x0000, /* R1314 */
2892 0x0000, /* R1315 */
2893 0x0000, /* R1316 */
2894 0x0000, /* R1317 */
2895 0x0000, /* R1318 */
2896 0x0000, /* R1319 */
2897 0x0000, /* R1320 */
2898 0x0000, /* R1321 */
2899 0x0000, /* R1322 */
2900 0x0000, /* R1323 */
2901 0x0000, /* R1324 */
2902 0x0000, /* R1325 */
2903 0x0000, /* R1326 */
2904 0x0000, /* R1327 */
2905 0x0000, /* R1328 */
2906 0x0000, /* R1329 */
2907 0x0000, /* R1330 */
2908 0x0000, /* R1331 */
2909 0x0000, /* R1332 */
2910 0x0000, /* R1333 */
2911 0x0000, /* R1334 */
2912 0x0000, /* R1335 */
2913 0x0000, /* R1336 */
2914 0x0000, /* R1337 */
2915 0x0000, /* R1338 */
2916 0x0000, /* R1339 */
2917 0x0000, /* R1340 */
2918 0x0000, /* R1341 */
2919 0x0000, /* R1342 */
2920 0x0000, /* R1343 */
2921 0x0098, /* R1344 - AIF2 DRC (1) */
2922 0x0845, /* R1345 - AIF2 DRC (2) */
2923 0x0000, /* R1346 - AIF2 DRC (3) */
2924 0x0000, /* R1347 - AIF2 DRC (4) */
2925 0x0000, /* R1348 - AIF2 DRC (5) */
2926 0x0000, /* R1349 */
2927 0x0000, /* R1350 */
2928 0x0000, /* R1351 */
2929 0x0000, /* R1352 */
2930 0x0000, /* R1353 */
2931 0x0000, /* R1354 */
2932 0x0000, /* R1355 */
2933 0x0000, /* R1356 */
2934 0x0000, /* R1357 */
2935 0x0000, /* R1358 */
2936 0x0000, /* R1359 */
2937 0x0000, /* R1360 */
2938 0x0000, /* R1361 */
2939 0x0000, /* R1362 */
2940 0x0000, /* R1363 */
2941 0x0000, /* R1364 */
2942 0x0000, /* R1365 */
2943 0x0000, /* R1366 */
2944 0x0000, /* R1367 */
2945 0x0000, /* R1368 */
2946 0x0000, /* R1369 */
2947 0x0000, /* R1370 */
2948 0x0000, /* R1371 */
2949 0x0000, /* R1372 */
2950 0x0000, /* R1373 */
2951 0x0000, /* R1374 */
2952 0x0000, /* R1375 */
2953 0x0000, /* R1376 */
2954 0x0000, /* R1377 */
2955 0x0000, /* R1378 */
2956 0x0000, /* R1379 */
2957 0x0000, /* R1380 */
2958 0x0000, /* R1381 */
2959 0x0000, /* R1382 */
2960 0x0000, /* R1383 */
2961 0x0000, /* R1384 */
2962 0x0000, /* R1385 */
2963 0x0000, /* R1386 */
2964 0x0000, /* R1387 */
2965 0x0000, /* R1388 */
2966 0x0000, /* R1389 */
2967 0x0000, /* R1390 */
2968 0x0000, /* R1391 */
2969 0x0000, /* R1392 */
2970 0x0000, /* R1393 */
2971 0x0000, /* R1394 */
2972 0x0000, /* R1395 */
2973 0x0000, /* R1396 */
2974 0x0000, /* R1397 */
2975 0x0000, /* R1398 */
2976 0x0000, /* R1399 */
2977 0x0000, /* R1400 */
2978 0x0000, /* R1401 */
2979 0x0000, /* R1402 */
2980 0x0000, /* R1403 */
2981 0x0000, /* R1404 */
2982 0x0000, /* R1405 */
2983 0x0000, /* R1406 */
2984 0x0000, /* R1407 */
2985 0x6318, /* R1408 - AIF2 EQ Gains (1) */
2986 0x6300, /* R1409 - AIF2 EQ Gains (2) */
2987 0x0FCA, /* R1410 - AIF2 EQ Band 1 A */
2988 0x0400, /* R1411 - AIF2 EQ Band 1 B */
2989 0x00D8, /* R1412 - AIF2 EQ Band 1 PG */
2990 0x1EB5, /* R1413 - AIF2 EQ Band 2 A */
2991 0xF145, /* R1414 - AIF2 EQ Band 2 B */
2992 0x0B75, /* R1415 - AIF2 EQ Band 2 C */
2993 0x01C5, /* R1416 - AIF2 EQ Band 2 PG */
2994 0x1C58, /* R1417 - AIF2 EQ Band 3 A */
2995 0xF373, /* R1418 - AIF2 EQ Band 3 B */
2996 0x0A54, /* R1419 - AIF2 EQ Band 3 C */
2997 0x0558, /* R1420 - AIF2 EQ Band 3 PG */
2998 0x168E, /* R1421 - AIF2 EQ Band 4 A */
2999 0xF829, /* R1422 - AIF2 EQ Band 4 B */
3000 0x07AD, /* R1423 - AIF2 EQ Band 4 C */
3001 0x1103, /* R1424 - AIF2 EQ Band 4 PG */
3002 0x0564, /* R1425 - AIF2 EQ Band 5 A */
3003 0x0559, /* R1426 - AIF2 EQ Band 5 B */
3004 0x4000, /* R1427 - AIF2 EQ Band 5 PG */
3005 0x0000, /* R1428 */
3006 0x0000, /* R1429 */
3007 0x0000, /* R1430 */
3008 0x0000, /* R1431 */
3009 0x0000, /* R1432 */
3010 0x0000, /* R1433 */
3011 0x0000, /* R1434 */
3012 0x0000, /* R1435 */
3013 0x0000, /* R1436 */
3014 0x0000, /* R1437 */
3015 0x0000, /* R1438 */
3016 0x0000, /* R1439 */
3017 0x0000, /* R1440 */
3018 0x0000, /* R1441 */
3019 0x0000, /* R1442 */
3020 0x0000, /* R1443 */
3021 0x0000, /* R1444 */
3022 0x0000, /* R1445 */
3023 0x0000, /* R1446 */
3024 0x0000, /* R1447 */
3025 0x0000, /* R1448 */
3026 0x0000, /* R1449 */
3027 0x0000, /* R1450 */
3028 0x0000, /* R1451 */
3029 0x0000, /* R1452 */
3030 0x0000, /* R1453 */
3031 0x0000, /* R1454 */
3032 0x0000, /* R1455 */
3033 0x0000, /* R1456 */
3034 0x0000, /* R1457 */
3035 0x0000, /* R1458 */
3036 0x0000, /* R1459 */
3037 0x0000, /* R1460 */
3038 0x0000, /* R1461 */
3039 0x0000, /* R1462 */
3040 0x0000, /* R1463 */
3041 0x0000, /* R1464 */
3042 0x0000, /* R1465 */
3043 0x0000, /* R1466 */
3044 0x0000, /* R1467 */
3045 0x0000, /* R1468 */
3046 0x0000, /* R1469 */
3047 0x0000, /* R1470 */
3048 0x0000, /* R1471 */
3049 0x0000, /* R1472 */
3050 0x0000, /* R1473 */
3051 0x0000, /* R1474 */
3052 0x0000, /* R1475 */
3053 0x0000, /* R1476 */
3054 0x0000, /* R1477 */
3055 0x0000, /* R1478 */
3056 0x0000, /* R1479 */
3057 0x0000, /* R1480 */
3058 0x0000, /* R1481 */
3059 0x0000, /* R1482 */
3060 0x0000, /* R1483 */
3061 0x0000, /* R1484 */
3062 0x0000, /* R1485 */
3063 0x0000, /* R1486 */
3064 0x0000, /* R1487 */
3065 0x0000, /* R1488 */
3066 0x0000, /* R1489 */
3067 0x0000, /* R1490 */
3068 0x0000, /* R1491 */
3069 0x0000, /* R1492 */
3070 0x0000, /* R1493 */
3071 0x0000, /* R1494 */
3072 0x0000, /* R1495 */
3073 0x0000, /* R1496 */
3074 0x0000, /* R1497 */
3075 0x0000, /* R1498 */
3076 0x0000, /* R1499 */
3077 0x0000, /* R1500 */
3078 0x0000, /* R1501 */
3079 0x0000, /* R1502 */
3080 0x0000, /* R1503 */
3081 0x0000, /* R1504 */
3082 0x0000, /* R1505 */
3083 0x0000, /* R1506 */
3084 0x0000, /* R1507 */
3085 0x0000, /* R1508 */
3086 0x0000, /* R1509 */
3087 0x0000, /* R1510 */
3088 0x0000, /* R1511 */
3089 0x0000, /* R1512 */
3090 0x0000, /* R1513 */
3091 0x0000, /* R1514 */
3092 0x0000, /* R1515 */
3093 0x0000, /* R1516 */
3094 0x0000, /* R1517 */
3095 0x0000, /* R1518 */
3096 0x0000, /* R1519 */
3097 0x0000, /* R1520 */
3098 0x0000, /* R1521 */
3099 0x0000, /* R1522 */
3100 0x0000, /* R1523 */
3101 0x0000, /* R1524 */
3102 0x0000, /* R1525 */
3103 0x0000, /* R1526 */
3104 0x0000, /* R1527 */
3105 0x0000, /* R1528 */
3106 0x0000, /* R1529 */
3107 0x0000, /* R1530 */
3108 0x0000, /* R1531 */
3109 0x0000, /* R1532 */
3110 0x0000, /* R1533 */
3111 0x0000, /* R1534 */
3112 0x0000, /* R1535 */
3113 0x0000, /* R1536 - DAC1 Mixer Volumes */
3114 0x0000, /* R1537 - DAC1 Left Mixer Routing */
3115 0x0000, /* R1538 - DAC1 Right Mixer Routing */
3116 0x0000, /* R1539 - DAC2 Mixer Volumes */
3117 0x0000, /* R1540 - DAC2 Left Mixer Routing */
3118 0x0000, /* R1541 - DAC2 Right Mixer Routing */
3119 0x0000, /* R1542 - AIF1 ADC1 Left Mixer Routing */
3120 0x0000, /* R1543 - AIF1 ADC1 Right Mixer Routing */
3121 0x0000, /* R1544 - AIF1 ADC2 Left Mixer Routing */
3122 0x0000, /* R1545 - AIF1 ADC2 Right mixer Routing */
3123 0x0000, /* R1546 */
3124 0x0000, /* R1547 */
3125 0x0000, /* R1548 */
3126 0x0000, /* R1549 */
3127 0x0000, /* R1550 */
3128 0x0000, /* R1551 */
3129 0x02C0, /* R1552 - DAC1 Left Volume */
3130 0x02C0, /* R1553 - DAC1 Right Volume */
3131 0x02C0, /* R1554 - DAC2 Left Volume */
3132 0x02C0, /* R1555 - DAC2 Right Volume */
3133 0x0000, /* R1556 - DAC Softmute */
3134 0x0000, /* R1557 */
3135 0x0000, /* R1558 */
3136 0x0000, /* R1559 */
3137 0x0000, /* R1560 */
3138 0x0000, /* R1561 */
3139 0x0000, /* R1562 */
3140 0x0000, /* R1563 */
3141 0x0000, /* R1564 */
3142 0x0000, /* R1565 */
3143 0x0000, /* R1566 */
3144 0x0000, /* R1567 */
3145 0x0002, /* R1568 - Oversampling */
3146 0x0000, /* R1569 - Sidetone */
3147};
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 4d3e6f1ac584..247a6a99feb8 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -18,15 +18,17 @@
18#include <linux/pm.h> 18#include <linux/pm.h>
19#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>
21#include <linux/regulator/consumer.h> 22#include <linux/regulator/consumer.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23#include <sound/core.h> 24#include <sound/core.h>
25#include <sound/jack.h>
24#include <sound/pcm.h> 26#include <sound/pcm.h>
25#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
26#include <sound/soc.h> 28#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h> 29#include <sound/initval.h>
29#include <sound/tlv.h> 30#include <sound/tlv.h>
31#include <trace/events/asoc.h>
30 32
31#include <linux/mfd/wm8994/core.h> 33#include <linux/mfd/wm8994/core.h>
32#include <linux/mfd/wm8994/registers.h> 34#include <linux/mfd/wm8994/registers.h>
@@ -57,8 +59,6 @@ static int wm8994_retune_mobile_base[] = {
57 WM8994_AIF2_EQ_GAINS_1, 59 WM8994_AIF2_EQ_GAINS_1,
58}; 60};
59 61
60#define WM8994_REG_CACHE_SIZE 0x621
61
62struct wm8994_micdet { 62struct wm8994_micdet {
63 struct snd_soc_jack *jack; 63 struct snd_soc_jack *jack;
64 int det; 64 int det;
@@ -71,7 +71,6 @@ struct wm8994_priv {
71 enum snd_soc_control_type control_type; 71 enum snd_soc_control_type control_type;
72 void *control_data; 72 void *control_data;
73 struct snd_soc_codec *codec; 73 struct snd_soc_codec *codec;
74 u16 reg_cache[WM8994_REG_CACHE_SIZE + 1];
75 int sysclk[2]; 74 int sysclk[2];
76 int sysclk_rate[2]; 75 int sysclk_rate[2];
77 int mclk[2]; 76 int mclk[2];
@@ -81,6 +80,8 @@ struct wm8994_priv {
81 int dac_rates[2]; 80 int dac_rates[2];
82 int lrclk_shared[2]; 81 int lrclk_shared[2];
83 82
83 int mbc_ena[3];
84
84 /* Platform dependant DRC configuration */ 85 /* Platform dependant DRC configuration */
85 const char **drc_texts; 86 const char **drc_texts;
86 int drc_cfg[WM8994_NUM_DRC]; 87 int drc_cfg[WM8994_NUM_DRC];
@@ -92,1588 +93,22 @@ struct wm8994_priv {
92 int retune_mobile_cfg[WM8994_NUM_EQ]; 93 int retune_mobile_cfg[WM8994_NUM_EQ];
93 struct soc_enum retune_mobile_enum; 94 struct soc_enum retune_mobile_enum;
94 95
96 /* Platform dependant MBC configuration */
97 int mbc_cfg;
98 const char **mbc_texts;
99 struct soc_enum mbc_enum;
100
95 struct wm8994_micdet micdet[2]; 101 struct wm8994_micdet micdet[2];
96 102
103 wm8958_micdet_cb jack_cb;
104 void *jack_cb_data;
105 bool jack_is_mic;
106 bool jack_is_video;
107
97 int revision; 108 int revision;
98 struct wm8994_pdata *pdata; 109 struct wm8994_pdata *pdata;
99}; 110};
100 111
101static const struct {
102 unsigned short readable; /* Mask of readable bits */
103 unsigned short writable; /* Mask of writable bits */
104} access_masks[] = {
105 { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */
106 { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */
107 { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */
108 { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */
109 { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */
110 { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */
111 { 0x003F, 0x003F }, /* R6 - Power Management (6) */
112 { 0x0000, 0x0000 }, /* R7 */
113 { 0x0000, 0x0000 }, /* R8 */
114 { 0x0000, 0x0000 }, /* R9 */
115 { 0x0000, 0x0000 }, /* R10 */
116 { 0x0000, 0x0000 }, /* R11 */
117 { 0x0000, 0x0000 }, /* R12 */
118 { 0x0000, 0x0000 }, /* R13 */
119 { 0x0000, 0x0000 }, /* R14 */
120 { 0x0000, 0x0000 }, /* R15 */
121 { 0x0000, 0x0000 }, /* R16 */
122 { 0x0000, 0x0000 }, /* R17 */
123 { 0x0000, 0x0000 }, /* R18 */
124 { 0x0000, 0x0000 }, /* R19 */
125 { 0x0000, 0x0000 }, /* R20 */
126 { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */
127 { 0x0000, 0x0000 }, /* R22 */
128 { 0x0000, 0x0000 }, /* R23 */
129 { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */
130 { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */
131 { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */
132 { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */
133 { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */
134 { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */
135 { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */
136 { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */
137 { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */
138 { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */
139 { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */
140 { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */
141 { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */
142 { 0x003F, 0x003F }, /* R37 - ClassD */
143 { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */
144 { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */
145 { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */
146 { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */
147 { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */
148 { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */
149 { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */
150 { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */
151 { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */
152 { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */
153 { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */
154 { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */
155 { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */
156 { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */
157 { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */
158 { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */
159 { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */
160 { 0x00C1, 0x00C1 }, /* R55 - Additional Control */
161 { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */
162 { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */
163 { 0x00FF, 0x00FF }, /* R58 - MICBIAS */
164 { 0x000F, 0x000F }, /* R59 - LDO 1 */
165 { 0x0007, 0x0007 }, /* R60 - LDO 2 */
166 { 0x0000, 0x0000 }, /* R61 */
167 { 0x0000, 0x0000 }, /* R62 */
168 { 0x0000, 0x0000 }, /* R63 */
169 { 0x0000, 0x0000 }, /* R64 */
170 { 0x0000, 0x0000 }, /* R65 */
171 { 0x0000, 0x0000 }, /* R66 */
172 { 0x0000, 0x0000 }, /* R67 */
173 { 0x0000, 0x0000 }, /* R68 */
174 { 0x0000, 0x0000 }, /* R69 */
175 { 0x0000, 0x0000 }, /* R70 */
176 { 0x0000, 0x0000 }, /* R71 */
177 { 0x0000, 0x0000 }, /* R72 */
178 { 0x0000, 0x0000 }, /* R73 */
179 { 0x0000, 0x0000 }, /* R74 */
180 { 0x0000, 0x0000 }, /* R75 */
181 { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */
182 { 0x0000, 0x0000 }, /* R77 */
183 { 0x0000, 0x0000 }, /* R78 */
184 { 0x0000, 0x0000 }, /* R79 */
185 { 0x0000, 0x0000 }, /* R80 */
186 { 0x0301, 0x0301 }, /* R81 - Class W (1) */
187 { 0x0000, 0x0000 }, /* R82 */
188 { 0x0000, 0x0000 }, /* R83 */
189 { 0x333F, 0x333F }, /* R84 - DC Servo (1) */
190 { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */
191 { 0x0000, 0x0000 }, /* R86 */
192 { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */
193 { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */
194 { 0x0000, 0x0000 }, /* R89 */
195 { 0x0000, 0x0000 }, /* R90 */
196 { 0x0000, 0x0000 }, /* R91 */
197 { 0x0000, 0x0000 }, /* R92 */
198 { 0x0000, 0x0000 }, /* R93 */
199 { 0x0000, 0x0000 }, /* R94 */
200 { 0x0000, 0x0000 }, /* R95 */
201 { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */
202 { 0x0000, 0x0000 }, /* R97 */
203 { 0x0000, 0x0000 }, /* R98 */
204 { 0x0000, 0x0000 }, /* R99 */
205 { 0x0000, 0x0000 }, /* R100 */
206 { 0x0000, 0x0000 }, /* R101 */
207 { 0x0000, 0x0000 }, /* R102 */
208 { 0x0000, 0x0000 }, /* R103 */
209 { 0x0000, 0x0000 }, /* R104 */
210 { 0x0000, 0x0000 }, /* R105 */
211 { 0x0000, 0x0000 }, /* R106 */
212 { 0x0000, 0x0000 }, /* R107 */
213 { 0x0000, 0x0000 }, /* R108 */
214 { 0x0000, 0x0000 }, /* R109 */
215 { 0x0000, 0x0000 }, /* R110 */
216 { 0x0000, 0x0000 }, /* R111 */
217 { 0x0000, 0x0000 }, /* R112 */
218 { 0x0000, 0x0000 }, /* R113 */
219 { 0x0000, 0x0000 }, /* R114 */
220 { 0x0000, 0x0000 }, /* R115 */
221 { 0x0000, 0x0000 }, /* R116 */
222 { 0x0000, 0x0000 }, /* R117 */
223 { 0x0000, 0x0000 }, /* R118 */
224 { 0x0000, 0x0000 }, /* R119 */
225 { 0x0000, 0x0000 }, /* R120 */
226 { 0x0000, 0x0000 }, /* R121 */
227 { 0x0000, 0x0000 }, /* R122 */
228 { 0x0000, 0x0000 }, /* R123 */
229 { 0x0000, 0x0000 }, /* R124 */
230 { 0x0000, 0x0000 }, /* R125 */
231 { 0x0000, 0x0000 }, /* R126 */
232 { 0x0000, 0x0000 }, /* R127 */
233 { 0x0000, 0x0000 }, /* R128 */
234 { 0x0000, 0x0000 }, /* R129 */
235 { 0x0000, 0x0000 }, /* R130 */
236 { 0x0000, 0x0000 }, /* R131 */
237 { 0x0000, 0x0000 }, /* R132 */
238 { 0x0000, 0x0000 }, /* R133 */
239 { 0x0000, 0x0000 }, /* R134 */
240 { 0x0000, 0x0000 }, /* R135 */
241 { 0x0000, 0x0000 }, /* R136 */
242 { 0x0000, 0x0000 }, /* R137 */
243 { 0x0000, 0x0000 }, /* R138 */
244 { 0x0000, 0x0000 }, /* R139 */
245 { 0x0000, 0x0000 }, /* R140 */
246 { 0x0000, 0x0000 }, /* R141 */
247 { 0x0000, 0x0000 }, /* R142 */
248 { 0x0000, 0x0000 }, /* R143 */
249 { 0x0000, 0x0000 }, /* R144 */
250 { 0x0000, 0x0000 }, /* R145 */
251 { 0x0000, 0x0000 }, /* R146 */
252 { 0x0000, 0x0000 }, /* R147 */
253 { 0x0000, 0x0000 }, /* R148 */
254 { 0x0000, 0x0000 }, /* R149 */
255 { 0x0000, 0x0000 }, /* R150 */
256 { 0x0000, 0x0000 }, /* R151 */
257 { 0x0000, 0x0000 }, /* R152 */
258 { 0x0000, 0x0000 }, /* R153 */
259 { 0x0000, 0x0000 }, /* R154 */
260 { 0x0000, 0x0000 }, /* R155 */
261 { 0x0000, 0x0000 }, /* R156 */
262 { 0x0000, 0x0000 }, /* R157 */
263 { 0x0000, 0x0000 }, /* R158 */
264 { 0x0000, 0x0000 }, /* R159 */
265 { 0x0000, 0x0000 }, /* R160 */
266 { 0x0000, 0x0000 }, /* R161 */
267 { 0x0000, 0x0000 }, /* R162 */
268 { 0x0000, 0x0000 }, /* R163 */
269 { 0x0000, 0x0000 }, /* R164 */
270 { 0x0000, 0x0000 }, /* R165 */
271 { 0x0000, 0x0000 }, /* R166 */
272 { 0x0000, 0x0000 }, /* R167 */
273 { 0x0000, 0x0000 }, /* R168 */
274 { 0x0000, 0x0000 }, /* R169 */
275 { 0x0000, 0x0000 }, /* R170 */
276 { 0x0000, 0x0000 }, /* R171 */
277 { 0x0000, 0x0000 }, /* R172 */
278 { 0x0000, 0x0000 }, /* R173 */
279 { 0x0000, 0x0000 }, /* R174 */
280 { 0x0000, 0x0000 }, /* R175 */
281 { 0x0000, 0x0000 }, /* R176 */
282 { 0x0000, 0x0000 }, /* R177 */
283 { 0x0000, 0x0000 }, /* R178 */
284 { 0x0000, 0x0000 }, /* R179 */
285 { 0x0000, 0x0000 }, /* R180 */
286 { 0x0000, 0x0000 }, /* R181 */
287 { 0x0000, 0x0000 }, /* R182 */
288 { 0x0000, 0x0000 }, /* R183 */
289 { 0x0000, 0x0000 }, /* R184 */
290 { 0x0000, 0x0000 }, /* R185 */
291 { 0x0000, 0x0000 }, /* R186 */
292 { 0x0000, 0x0000 }, /* R187 */
293 { 0x0000, 0x0000 }, /* R188 */
294 { 0x0000, 0x0000 }, /* R189 */
295 { 0x0000, 0x0000 }, /* R190 */
296 { 0x0000, 0x0000 }, /* R191 */
297 { 0x0000, 0x0000 }, /* R192 */
298 { 0x0000, 0x0000 }, /* R193 */
299 { 0x0000, 0x0000 }, /* R194 */
300 { 0x0000, 0x0000 }, /* R195 */
301 { 0x0000, 0x0000 }, /* R196 */
302 { 0x0000, 0x0000 }, /* R197 */
303 { 0x0000, 0x0000 }, /* R198 */
304 { 0x0000, 0x0000 }, /* R199 */
305 { 0x0000, 0x0000 }, /* R200 */
306 { 0x0000, 0x0000 }, /* R201 */
307 { 0x0000, 0x0000 }, /* R202 */
308 { 0x0000, 0x0000 }, /* R203 */
309 { 0x0000, 0x0000 }, /* R204 */
310 { 0x0000, 0x0000 }, /* R205 */
311 { 0x0000, 0x0000 }, /* R206 */
312 { 0x0000, 0x0000 }, /* R207 */
313 { 0x0000, 0x0000 }, /* R208 */
314 { 0x0000, 0x0000 }, /* R209 */
315 { 0x0000, 0x0000 }, /* R210 */
316 { 0x0000, 0x0000 }, /* R211 */
317 { 0x0000, 0x0000 }, /* R212 */
318 { 0x0000, 0x0000 }, /* R213 */
319 { 0x0000, 0x0000 }, /* R214 */
320 { 0x0000, 0x0000 }, /* R215 */
321 { 0x0000, 0x0000 }, /* R216 */
322 { 0x0000, 0x0000 }, /* R217 */
323 { 0x0000, 0x0000 }, /* R218 */
324 { 0x0000, 0x0000 }, /* R219 */
325 { 0x0000, 0x0000 }, /* R220 */
326 { 0x0000, 0x0000 }, /* R221 */
327 { 0x0000, 0x0000 }, /* R222 */
328 { 0x0000, 0x0000 }, /* R223 */
329 { 0x0000, 0x0000 }, /* R224 */
330 { 0x0000, 0x0000 }, /* R225 */
331 { 0x0000, 0x0000 }, /* R226 */
332 { 0x0000, 0x0000 }, /* R227 */
333 { 0x0000, 0x0000 }, /* R228 */
334 { 0x0000, 0x0000 }, /* R229 */
335 { 0x0000, 0x0000 }, /* R230 */
336 { 0x0000, 0x0000 }, /* R231 */
337 { 0x0000, 0x0000 }, /* R232 */
338 { 0x0000, 0x0000 }, /* R233 */
339 { 0x0000, 0x0000 }, /* R234 */
340 { 0x0000, 0x0000 }, /* R235 */
341 { 0x0000, 0x0000 }, /* R236 */
342 { 0x0000, 0x0000 }, /* R237 */
343 { 0x0000, 0x0000 }, /* R238 */
344 { 0x0000, 0x0000 }, /* R239 */
345 { 0x0000, 0x0000 }, /* R240 */
346 { 0x0000, 0x0000 }, /* R241 */
347 { 0x0000, 0x0000 }, /* R242 */
348 { 0x0000, 0x0000 }, /* R243 */
349 { 0x0000, 0x0000 }, /* R244 */
350 { 0x0000, 0x0000 }, /* R245 */
351 { 0x0000, 0x0000 }, /* R246 */
352 { 0x0000, 0x0000 }, /* R247 */
353 { 0x0000, 0x0000 }, /* R248 */
354 { 0x0000, 0x0000 }, /* R249 */
355 { 0x0000, 0x0000 }, /* R250 */
356 { 0x0000, 0x0000 }, /* R251 */
357 { 0x0000, 0x0000 }, /* R252 */
358 { 0x0000, 0x0000 }, /* R253 */
359 { 0x0000, 0x0000 }, /* R254 */
360 { 0x0000, 0x0000 }, /* R255 */
361 { 0x000F, 0x0000 }, /* R256 - Chip Revision */
362 { 0x0074, 0x0074 }, /* R257 - Control Interface */
363 { 0x0000, 0x0000 }, /* R258 */
364 { 0x0000, 0x0000 }, /* R259 */
365 { 0x0000, 0x0000 }, /* R260 */
366 { 0x0000, 0x0000 }, /* R261 */
367 { 0x0000, 0x0000 }, /* R262 */
368 { 0x0000, 0x0000 }, /* R263 */
369 { 0x0000, 0x0000 }, /* R264 */
370 { 0x0000, 0x0000 }, /* R265 */
371 { 0x0000, 0x0000 }, /* R266 */
372 { 0x0000, 0x0000 }, /* R267 */
373 { 0x0000, 0x0000 }, /* R268 */
374 { 0x0000, 0x0000 }, /* R269 */
375 { 0x0000, 0x0000 }, /* R270 */
376 { 0x0000, 0x0000 }, /* R271 */
377 { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */
378 { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */
379 { 0x0000, 0x0000 }, /* R274 */
380 { 0x0000, 0x0000 }, /* R275 */
381 { 0x0000, 0x0000 }, /* R276 */
382 { 0x0000, 0x0000 }, /* R277 */
383 { 0x0000, 0x0000 }, /* R278 */
384 { 0x0000, 0x0000 }, /* R279 */
385 { 0x0000, 0x0000 }, /* R280 */
386 { 0x0000, 0x0000 }, /* R281 */
387 { 0x0000, 0x0000 }, /* R282 */
388 { 0x0000, 0x0000 }, /* R283 */
389 { 0x0000, 0x0000 }, /* R284 */
390 { 0x0000, 0x0000 }, /* R285 */
391 { 0x0000, 0x0000 }, /* R286 */
392 { 0x0000, 0x0000 }, /* R287 */
393 { 0x0000, 0x0000 }, /* R288 */
394 { 0x0000, 0x0000 }, /* R289 */
395 { 0x0000, 0x0000 }, /* R290 */
396 { 0x0000, 0x0000 }, /* R291 */
397 { 0x0000, 0x0000 }, /* R292 */
398 { 0x0000, 0x0000 }, /* R293 */
399 { 0x0000, 0x0000 }, /* R294 */
400 { 0x0000, 0x0000 }, /* R295 */
401 { 0x0000, 0x0000 }, /* R296 */
402 { 0x0000, 0x0000 }, /* R297 */
403 { 0x0000, 0x0000 }, /* R298 */
404 { 0x0000, 0x0000 }, /* R299 */
405 { 0x0000, 0x0000 }, /* R300 */
406 { 0x0000, 0x0000 }, /* R301 */
407 { 0x0000, 0x0000 }, /* R302 */
408 { 0x0000, 0x0000 }, /* R303 */
409 { 0x0000, 0x0000 }, /* R304 */
410 { 0x0000, 0x0000 }, /* R305 */
411 { 0x0000, 0x0000 }, /* R306 */
412 { 0x0000, 0x0000 }, /* R307 */
413 { 0x0000, 0x0000 }, /* R308 */
414 { 0x0000, 0x0000 }, /* R309 */
415 { 0x0000, 0x0000 }, /* R310 */
416 { 0x0000, 0x0000 }, /* R311 */
417 { 0x0000, 0x0000 }, /* R312 */
418 { 0x0000, 0x0000 }, /* R313 */
419 { 0x0000, 0x0000 }, /* R314 */
420 { 0x0000, 0x0000 }, /* R315 */
421 { 0x0000, 0x0000 }, /* R316 */
422 { 0x0000, 0x0000 }, /* R317 */
423 { 0x0000, 0x0000 }, /* R318 */
424 { 0x0000, 0x0000 }, /* R319 */
425 { 0x0000, 0x0000 }, /* R320 */
426 { 0x0000, 0x0000 }, /* R321 */
427 { 0x0000, 0x0000 }, /* R322 */
428 { 0x0000, 0x0000 }, /* R323 */
429 { 0x0000, 0x0000 }, /* R324 */
430 { 0x0000, 0x0000 }, /* R325 */
431 { 0x0000, 0x0000 }, /* R326 */
432 { 0x0000, 0x0000 }, /* R327 */
433 { 0x0000, 0x0000 }, /* R328 */
434 { 0x0000, 0x0000 }, /* R329 */
435 { 0x0000, 0x0000 }, /* R330 */
436 { 0x0000, 0x0000 }, /* R331 */
437 { 0x0000, 0x0000 }, /* R332 */
438 { 0x0000, 0x0000 }, /* R333 */
439 { 0x0000, 0x0000 }, /* R334 */
440 { 0x0000, 0x0000 }, /* R335 */
441 { 0x0000, 0x0000 }, /* R336 */
442 { 0x0000, 0x0000 }, /* R337 */
443 { 0x0000, 0x0000 }, /* R338 */
444 { 0x0000, 0x0000 }, /* R339 */
445 { 0x0000, 0x0000 }, /* R340 */
446 { 0x0000, 0x0000 }, /* R341 */
447 { 0x0000, 0x0000 }, /* R342 */
448 { 0x0000, 0x0000 }, /* R343 */
449 { 0x0000, 0x0000 }, /* R344 */
450 { 0x0000, 0x0000 }, /* R345 */
451 { 0x0000, 0x0000 }, /* R346 */
452 { 0x0000, 0x0000 }, /* R347 */
453 { 0x0000, 0x0000 }, /* R348 */
454 { 0x0000, 0x0000 }, /* R349 */
455 { 0x0000, 0x0000 }, /* R350 */
456 { 0x0000, 0x0000 }, /* R351 */
457 { 0x0000, 0x0000 }, /* R352 */
458 { 0x0000, 0x0000 }, /* R353 */
459 { 0x0000, 0x0000 }, /* R354 */
460 { 0x0000, 0x0000 }, /* R355 */
461 { 0x0000, 0x0000 }, /* R356 */
462 { 0x0000, 0x0000 }, /* R357 */
463 { 0x0000, 0x0000 }, /* R358 */
464 { 0x0000, 0x0000 }, /* R359 */
465 { 0x0000, 0x0000 }, /* R360 */
466 { 0x0000, 0x0000 }, /* R361 */
467 { 0x0000, 0x0000 }, /* R362 */
468 { 0x0000, 0x0000 }, /* R363 */
469 { 0x0000, 0x0000 }, /* R364 */
470 { 0x0000, 0x0000 }, /* R365 */
471 { 0x0000, 0x0000 }, /* R366 */
472 { 0x0000, 0x0000 }, /* R367 */
473 { 0x0000, 0x0000 }, /* R368 */
474 { 0x0000, 0x0000 }, /* R369 */
475 { 0x0000, 0x0000 }, /* R370 */
476 { 0x0000, 0x0000 }, /* R371 */
477 { 0x0000, 0x0000 }, /* R372 */
478 { 0x0000, 0x0000 }, /* R373 */
479 { 0x0000, 0x0000 }, /* R374 */
480 { 0x0000, 0x0000 }, /* R375 */
481 { 0x0000, 0x0000 }, /* R376 */
482 { 0x0000, 0x0000 }, /* R377 */
483 { 0x0000, 0x0000 }, /* R378 */
484 { 0x0000, 0x0000 }, /* R379 */
485 { 0x0000, 0x0000 }, /* R380 */
486 { 0x0000, 0x0000 }, /* R381 */
487 { 0x0000, 0x0000 }, /* R382 */
488 { 0x0000, 0x0000 }, /* R383 */
489 { 0x0000, 0x0000 }, /* R384 */
490 { 0x0000, 0x0000 }, /* R385 */
491 { 0x0000, 0x0000 }, /* R386 */
492 { 0x0000, 0x0000 }, /* R387 */
493 { 0x0000, 0x0000 }, /* R388 */
494 { 0x0000, 0x0000 }, /* R389 */
495 { 0x0000, 0x0000 }, /* R390 */
496 { 0x0000, 0x0000 }, /* R391 */
497 { 0x0000, 0x0000 }, /* R392 */
498 { 0x0000, 0x0000 }, /* R393 */
499 { 0x0000, 0x0000 }, /* R394 */
500 { 0x0000, 0x0000 }, /* R395 */
501 { 0x0000, 0x0000 }, /* R396 */
502 { 0x0000, 0x0000 }, /* R397 */
503 { 0x0000, 0x0000 }, /* R398 */
504 { 0x0000, 0x0000 }, /* R399 */
505 { 0x0000, 0x0000 }, /* R400 */
506 { 0x0000, 0x0000 }, /* R401 */
507 { 0x0000, 0x0000 }, /* R402 */
508 { 0x0000, 0x0000 }, /* R403 */
509 { 0x0000, 0x0000 }, /* R404 */
510 { 0x0000, 0x0000 }, /* R405 */
511 { 0x0000, 0x0000 }, /* R406 */
512 { 0x0000, 0x0000 }, /* R407 */
513 { 0x0000, 0x0000 }, /* R408 */
514 { 0x0000, 0x0000 }, /* R409 */
515 { 0x0000, 0x0000 }, /* R410 */
516 { 0x0000, 0x0000 }, /* R411 */
517 { 0x0000, 0x0000 }, /* R412 */
518 { 0x0000, 0x0000 }, /* R413 */
519 { 0x0000, 0x0000 }, /* R414 */
520 { 0x0000, 0x0000 }, /* R415 */
521 { 0x0000, 0x0000 }, /* R416 */
522 { 0x0000, 0x0000 }, /* R417 */
523 { 0x0000, 0x0000 }, /* R418 */
524 { 0x0000, 0x0000 }, /* R419 */
525 { 0x0000, 0x0000 }, /* R420 */
526 { 0x0000, 0x0000 }, /* R421 */
527 { 0x0000, 0x0000 }, /* R422 */
528 { 0x0000, 0x0000 }, /* R423 */
529 { 0x0000, 0x0000 }, /* R424 */
530 { 0x0000, 0x0000 }, /* R425 */
531 { 0x0000, 0x0000 }, /* R426 */
532 { 0x0000, 0x0000 }, /* R427 */
533 { 0x0000, 0x0000 }, /* R428 */
534 { 0x0000, 0x0000 }, /* R429 */
535 { 0x0000, 0x0000 }, /* R430 */
536 { 0x0000, 0x0000 }, /* R431 */
537 { 0x0000, 0x0000 }, /* R432 */
538 { 0x0000, 0x0000 }, /* R433 */
539 { 0x0000, 0x0000 }, /* R434 */
540 { 0x0000, 0x0000 }, /* R435 */
541 { 0x0000, 0x0000 }, /* R436 */
542 { 0x0000, 0x0000 }, /* R437 */
543 { 0x0000, 0x0000 }, /* R438 */
544 { 0x0000, 0x0000 }, /* R439 */
545 { 0x0000, 0x0000 }, /* R440 */
546 { 0x0000, 0x0000 }, /* R441 */
547 { 0x0000, 0x0000 }, /* R442 */
548 { 0x0000, 0x0000 }, /* R443 */
549 { 0x0000, 0x0000 }, /* R444 */
550 { 0x0000, 0x0000 }, /* R445 */
551 { 0x0000, 0x0000 }, /* R446 */
552 { 0x0000, 0x0000 }, /* R447 */
553 { 0x0000, 0x0000 }, /* R448 */
554 { 0x0000, 0x0000 }, /* R449 */
555 { 0x0000, 0x0000 }, /* R450 */
556 { 0x0000, 0x0000 }, /* R451 */
557 { 0x0000, 0x0000 }, /* R452 */
558 { 0x0000, 0x0000 }, /* R453 */
559 { 0x0000, 0x0000 }, /* R454 */
560 { 0x0000, 0x0000 }, /* R455 */
561 { 0x0000, 0x0000 }, /* R456 */
562 { 0x0000, 0x0000 }, /* R457 */
563 { 0x0000, 0x0000 }, /* R458 */
564 { 0x0000, 0x0000 }, /* R459 */
565 { 0x0000, 0x0000 }, /* R460 */
566 { 0x0000, 0x0000 }, /* R461 */
567 { 0x0000, 0x0000 }, /* R462 */
568 { 0x0000, 0x0000 }, /* R463 */
569 { 0x0000, 0x0000 }, /* R464 */
570 { 0x0000, 0x0000 }, /* R465 */
571 { 0x0000, 0x0000 }, /* R466 */
572 { 0x0000, 0x0000 }, /* R467 */
573 { 0x0000, 0x0000 }, /* R468 */
574 { 0x0000, 0x0000 }, /* R469 */
575 { 0x0000, 0x0000 }, /* R470 */
576 { 0x0000, 0x0000 }, /* R471 */
577 { 0x0000, 0x0000 }, /* R472 */
578 { 0x0000, 0x0000 }, /* R473 */
579 { 0x0000, 0x0000 }, /* R474 */
580 { 0x0000, 0x0000 }, /* R475 */
581 { 0x0000, 0x0000 }, /* R476 */
582 { 0x0000, 0x0000 }, /* R477 */
583 { 0x0000, 0x0000 }, /* R478 */
584 { 0x0000, 0x0000 }, /* R479 */
585 { 0x0000, 0x0000 }, /* R480 */
586 { 0x0000, 0x0000 }, /* R481 */
587 { 0x0000, 0x0000 }, /* R482 */
588 { 0x0000, 0x0000 }, /* R483 */
589 { 0x0000, 0x0000 }, /* R484 */
590 { 0x0000, 0x0000 }, /* R485 */
591 { 0x0000, 0x0000 }, /* R486 */
592 { 0x0000, 0x0000 }, /* R487 */
593 { 0x0000, 0x0000 }, /* R488 */
594 { 0x0000, 0x0000 }, /* R489 */
595 { 0x0000, 0x0000 }, /* R490 */
596 { 0x0000, 0x0000 }, /* R491 */
597 { 0x0000, 0x0000 }, /* R492 */
598 { 0x0000, 0x0000 }, /* R493 */
599 { 0x0000, 0x0000 }, /* R494 */
600 { 0x0000, 0x0000 }, /* R495 */
601 { 0x0000, 0x0000 }, /* R496 */
602 { 0x0000, 0x0000 }, /* R497 */
603 { 0x0000, 0x0000 }, /* R498 */
604 { 0x0000, 0x0000 }, /* R499 */
605 { 0x0000, 0x0000 }, /* R500 */
606 { 0x0000, 0x0000 }, /* R501 */
607 { 0x0000, 0x0000 }, /* R502 */
608 { 0x0000, 0x0000 }, /* R503 */
609 { 0x0000, 0x0000 }, /* R504 */
610 { 0x0000, 0x0000 }, /* R505 */
611 { 0x0000, 0x0000 }, /* R506 */
612 { 0x0000, 0x0000 }, /* R507 */
613 { 0x0000, 0x0000 }, /* R508 */
614 { 0x0000, 0x0000 }, /* R509 */
615 { 0x0000, 0x0000 }, /* R510 */
616 { 0x0000, 0x0000 }, /* R511 */
617 { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */
618 { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */
619 { 0x0000, 0x0000 }, /* R514 */
620 { 0x0000, 0x0000 }, /* R515 */
621 { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */
622 { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */
623 { 0x0000, 0x0000 }, /* R518 */
624 { 0x0000, 0x0000 }, /* R519 */
625 { 0x001F, 0x001F }, /* R520 - Clocking (1) */
626 { 0x0777, 0x0777 }, /* R521 - Clocking (2) */
627 { 0x0000, 0x0000 }, /* R522 */
628 { 0x0000, 0x0000 }, /* R523 */
629 { 0x0000, 0x0000 }, /* R524 */
630 { 0x0000, 0x0000 }, /* R525 */
631 { 0x0000, 0x0000 }, /* R526 */
632 { 0x0000, 0x0000 }, /* R527 */
633 { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */
634 { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */
635 { 0x000F, 0x0000 }, /* R530 - Rate Status */
636 { 0x0000, 0x0000 }, /* R531 */
637 { 0x0000, 0x0000 }, /* R532 */
638 { 0x0000, 0x0000 }, /* R533 */
639 { 0x0000, 0x0000 }, /* R534 */
640 { 0x0000, 0x0000 }, /* R535 */
641 { 0x0000, 0x0000 }, /* R536 */
642 { 0x0000, 0x0000 }, /* R537 */
643 { 0x0000, 0x0000 }, /* R538 */
644 { 0x0000, 0x0000 }, /* R539 */
645 { 0x0000, 0x0000 }, /* R540 */
646 { 0x0000, 0x0000 }, /* R541 */
647 { 0x0000, 0x0000 }, /* R542 */
648 { 0x0000, 0x0000 }, /* R543 */
649 { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */
650 { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */
651 { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */
652 { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */
653 { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */
654 { 0x0000, 0x0000 }, /* R549 */
655 { 0x0000, 0x0000 }, /* R550 */
656 { 0x0000, 0x0000 }, /* R551 */
657 { 0x0000, 0x0000 }, /* R552 */
658 { 0x0000, 0x0000 }, /* R553 */
659 { 0x0000, 0x0000 }, /* R554 */
660 { 0x0000, 0x0000 }, /* R555 */
661 { 0x0000, 0x0000 }, /* R556 */
662 { 0x0000, 0x0000 }, /* R557 */
663 { 0x0000, 0x0000 }, /* R558 */
664 { 0x0000, 0x0000 }, /* R559 */
665 { 0x0000, 0x0000 }, /* R560 */
666 { 0x0000, 0x0000 }, /* R561 */
667 { 0x0000, 0x0000 }, /* R562 */
668 { 0x0000, 0x0000 }, /* R563 */
669 { 0x0000, 0x0000 }, /* R564 */
670 { 0x0000, 0x0000 }, /* R565 */
671 { 0x0000, 0x0000 }, /* R566 */
672 { 0x0000, 0x0000 }, /* R567 */
673 { 0x0000, 0x0000 }, /* R568 */
674 { 0x0000, 0x0000 }, /* R569 */
675 { 0x0000, 0x0000 }, /* R570 */
676 { 0x0000, 0x0000 }, /* R571 */
677 { 0x0000, 0x0000 }, /* R572 */
678 { 0x0000, 0x0000 }, /* R573 */
679 { 0x0000, 0x0000 }, /* R574 */
680 { 0x0000, 0x0000 }, /* R575 */
681 { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */
682 { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */
683 { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */
684 { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */
685 { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */
686 { 0x0000, 0x0000 }, /* R581 */
687 { 0x0000, 0x0000 }, /* R582 */
688 { 0x0000, 0x0000 }, /* R583 */
689 { 0x0000, 0x0000 }, /* R584 */
690 { 0x0000, 0x0000 }, /* R585 */
691 { 0x0000, 0x0000 }, /* R586 */
692 { 0x0000, 0x0000 }, /* R587 */
693 { 0x0000, 0x0000 }, /* R588 */
694 { 0x0000, 0x0000 }, /* R589 */
695 { 0x0000, 0x0000 }, /* R590 */
696 { 0x0000, 0x0000 }, /* R591 */
697 { 0x0000, 0x0000 }, /* R592 */
698 { 0x0000, 0x0000 }, /* R593 */
699 { 0x0000, 0x0000 }, /* R594 */
700 { 0x0000, 0x0000 }, /* R595 */
701 { 0x0000, 0x0000 }, /* R596 */
702 { 0x0000, 0x0000 }, /* R597 */
703 { 0x0000, 0x0000 }, /* R598 */
704 { 0x0000, 0x0000 }, /* R599 */
705 { 0x0000, 0x0000 }, /* R600 */
706 { 0x0000, 0x0000 }, /* R601 */
707 { 0x0000, 0x0000 }, /* R602 */
708 { 0x0000, 0x0000 }, /* R603 */
709 { 0x0000, 0x0000 }, /* R604 */
710 { 0x0000, 0x0000 }, /* R605 */
711 { 0x0000, 0x0000 }, /* R606 */
712 { 0x0000, 0x0000 }, /* R607 */
713 { 0x0000, 0x0000 }, /* R608 */
714 { 0x0000, 0x0000 }, /* R609 */
715 { 0x0000, 0x0000 }, /* R610 */
716 { 0x0000, 0x0000 }, /* R611 */
717 { 0x0000, 0x0000 }, /* R612 */
718 { 0x0000, 0x0000 }, /* R613 */
719 { 0x0000, 0x0000 }, /* R614 */
720 { 0x0000, 0x0000 }, /* R615 */
721 { 0x0000, 0x0000 }, /* R616 */
722 { 0x0000, 0x0000 }, /* R617 */
723 { 0x0000, 0x0000 }, /* R618 */
724 { 0x0000, 0x0000 }, /* R619 */
725 { 0x0000, 0x0000 }, /* R620 */
726 { 0x0000, 0x0000 }, /* R621 */
727 { 0x0000, 0x0000 }, /* R622 */
728 { 0x0000, 0x0000 }, /* R623 */
729 { 0x0000, 0x0000 }, /* R624 */
730 { 0x0000, 0x0000 }, /* R625 */
731 { 0x0000, 0x0000 }, /* R626 */
732 { 0x0000, 0x0000 }, /* R627 */
733 { 0x0000, 0x0000 }, /* R628 */
734 { 0x0000, 0x0000 }, /* R629 */
735 { 0x0000, 0x0000 }, /* R630 */
736 { 0x0000, 0x0000 }, /* R631 */
737 { 0x0000, 0x0000 }, /* R632 */
738 { 0x0000, 0x0000 }, /* R633 */
739 { 0x0000, 0x0000 }, /* R634 */
740 { 0x0000, 0x0000 }, /* R635 */
741 { 0x0000, 0x0000 }, /* R636 */
742 { 0x0000, 0x0000 }, /* R637 */
743 { 0x0000, 0x0000 }, /* R638 */
744 { 0x0000, 0x0000 }, /* R639 */
745 { 0x0000, 0x0000 }, /* R640 */
746 { 0x0000, 0x0000 }, /* R641 */
747 { 0x0000, 0x0000 }, /* R642 */
748 { 0x0000, 0x0000 }, /* R643 */
749 { 0x0000, 0x0000 }, /* R644 */
750 { 0x0000, 0x0000 }, /* R645 */
751 { 0x0000, 0x0000 }, /* R646 */
752 { 0x0000, 0x0000 }, /* R647 */
753 { 0x0000, 0x0000 }, /* R648 */
754 { 0x0000, 0x0000 }, /* R649 */
755 { 0x0000, 0x0000 }, /* R650 */
756 { 0x0000, 0x0000 }, /* R651 */
757 { 0x0000, 0x0000 }, /* R652 */
758 { 0x0000, 0x0000 }, /* R653 */
759 { 0x0000, 0x0000 }, /* R654 */
760 { 0x0000, 0x0000 }, /* R655 */
761 { 0x0000, 0x0000 }, /* R656 */
762 { 0x0000, 0x0000 }, /* R657 */
763 { 0x0000, 0x0000 }, /* R658 */
764 { 0x0000, 0x0000 }, /* R659 */
765 { 0x0000, 0x0000 }, /* R660 */
766 { 0x0000, 0x0000 }, /* R661 */
767 { 0x0000, 0x0000 }, /* R662 */
768 { 0x0000, 0x0000 }, /* R663 */
769 { 0x0000, 0x0000 }, /* R664 */
770 { 0x0000, 0x0000 }, /* R665 */
771 { 0x0000, 0x0000 }, /* R666 */
772 { 0x0000, 0x0000 }, /* R667 */
773 { 0x0000, 0x0000 }, /* R668 */
774 { 0x0000, 0x0000 }, /* R669 */
775 { 0x0000, 0x0000 }, /* R670 */
776 { 0x0000, 0x0000 }, /* R671 */
777 { 0x0000, 0x0000 }, /* R672 */
778 { 0x0000, 0x0000 }, /* R673 */
779 { 0x0000, 0x0000 }, /* R674 */
780 { 0x0000, 0x0000 }, /* R675 */
781 { 0x0000, 0x0000 }, /* R676 */
782 { 0x0000, 0x0000 }, /* R677 */
783 { 0x0000, 0x0000 }, /* R678 */
784 { 0x0000, 0x0000 }, /* R679 */
785 { 0x0000, 0x0000 }, /* R680 */
786 { 0x0000, 0x0000 }, /* R681 */
787 { 0x0000, 0x0000 }, /* R682 */
788 { 0x0000, 0x0000 }, /* R683 */
789 { 0x0000, 0x0000 }, /* R684 */
790 { 0x0000, 0x0000 }, /* R685 */
791 { 0x0000, 0x0000 }, /* R686 */
792 { 0x0000, 0x0000 }, /* R687 */
793 { 0x0000, 0x0000 }, /* R688 */
794 { 0x0000, 0x0000 }, /* R689 */
795 { 0x0000, 0x0000 }, /* R690 */
796 { 0x0000, 0x0000 }, /* R691 */
797 { 0x0000, 0x0000 }, /* R692 */
798 { 0x0000, 0x0000 }, /* R693 */
799 { 0x0000, 0x0000 }, /* R694 */
800 { 0x0000, 0x0000 }, /* R695 */
801 { 0x0000, 0x0000 }, /* R696 */
802 { 0x0000, 0x0000 }, /* R697 */
803 { 0x0000, 0x0000 }, /* R698 */
804 { 0x0000, 0x0000 }, /* R699 */
805 { 0x0000, 0x0000 }, /* R700 */
806 { 0x0000, 0x0000 }, /* R701 */
807 { 0x0000, 0x0000 }, /* R702 */
808 { 0x0000, 0x0000 }, /* R703 */
809 { 0x0000, 0x0000 }, /* R704 */
810 { 0x0000, 0x0000 }, /* R705 */
811 { 0x0000, 0x0000 }, /* R706 */
812 { 0x0000, 0x0000 }, /* R707 */
813 { 0x0000, 0x0000 }, /* R708 */
814 { 0x0000, 0x0000 }, /* R709 */
815 { 0x0000, 0x0000 }, /* R710 */
816 { 0x0000, 0x0000 }, /* R711 */
817 { 0x0000, 0x0000 }, /* R712 */
818 { 0x0000, 0x0000 }, /* R713 */
819 { 0x0000, 0x0000 }, /* R714 */
820 { 0x0000, 0x0000 }, /* R715 */
821 { 0x0000, 0x0000 }, /* R716 */
822 { 0x0000, 0x0000 }, /* R717 */
823 { 0x0000, 0x0000 }, /* R718 */
824 { 0x0000, 0x0000 }, /* R719 */
825 { 0x0000, 0x0000 }, /* R720 */
826 { 0x0000, 0x0000 }, /* R721 */
827 { 0x0000, 0x0000 }, /* R722 */
828 { 0x0000, 0x0000 }, /* R723 */
829 { 0x0000, 0x0000 }, /* R724 */
830 { 0x0000, 0x0000 }, /* R725 */
831 { 0x0000, 0x0000 }, /* R726 */
832 { 0x0000, 0x0000 }, /* R727 */
833 { 0x0000, 0x0000 }, /* R728 */
834 { 0x0000, 0x0000 }, /* R729 */
835 { 0x0000, 0x0000 }, /* R730 */
836 { 0x0000, 0x0000 }, /* R731 */
837 { 0x0000, 0x0000 }, /* R732 */
838 { 0x0000, 0x0000 }, /* R733 */
839 { 0x0000, 0x0000 }, /* R734 */
840 { 0x0000, 0x0000 }, /* R735 */
841 { 0x0000, 0x0000 }, /* R736 */
842 { 0x0000, 0x0000 }, /* R737 */
843 { 0x0000, 0x0000 }, /* R738 */
844 { 0x0000, 0x0000 }, /* R739 */
845 { 0x0000, 0x0000 }, /* R740 */
846 { 0x0000, 0x0000 }, /* R741 */
847 { 0x0000, 0x0000 }, /* R742 */
848 { 0x0000, 0x0000 }, /* R743 */
849 { 0x0000, 0x0000 }, /* R744 */
850 { 0x0000, 0x0000 }, /* R745 */
851 { 0x0000, 0x0000 }, /* R746 */
852 { 0x0000, 0x0000 }, /* R747 */
853 { 0x0000, 0x0000 }, /* R748 */
854 { 0x0000, 0x0000 }, /* R749 */
855 { 0x0000, 0x0000 }, /* R750 */
856 { 0x0000, 0x0000 }, /* R751 */
857 { 0x0000, 0x0000 }, /* R752 */
858 { 0x0000, 0x0000 }, /* R753 */
859 { 0x0000, 0x0000 }, /* R754 */
860 { 0x0000, 0x0000 }, /* R755 */
861 { 0x0000, 0x0000 }, /* R756 */
862 { 0x0000, 0x0000 }, /* R757 */
863 { 0x0000, 0x0000 }, /* R758 */
864 { 0x0000, 0x0000 }, /* R759 */
865 { 0x0000, 0x0000 }, /* R760 */
866 { 0x0000, 0x0000 }, /* R761 */
867 { 0x0000, 0x0000 }, /* R762 */
868 { 0x0000, 0x0000 }, /* R763 */
869 { 0x0000, 0x0000 }, /* R764 */
870 { 0x0000, 0x0000 }, /* R765 */
871 { 0x0000, 0x0000 }, /* R766 */
872 { 0x0000, 0x0000 }, /* R767 */
873 { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */
874 { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */
875 { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */
876 { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */
877 { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */
878 { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */
879 { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */
880 { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */
881 { 0x0000, 0x0000 }, /* R776 */
882 { 0x0000, 0x0000 }, /* R777 */
883 { 0x0000, 0x0000 }, /* R778 */
884 { 0x0000, 0x0000 }, /* R779 */
885 { 0x0000, 0x0000 }, /* R780 */
886 { 0x0000, 0x0000 }, /* R781 */
887 { 0x0000, 0x0000 }, /* R782 */
888 { 0x0000, 0x0000 }, /* R783 */
889 { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */
890 { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */
891 { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */
892 { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */
893 { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */
894 { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */
895 { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */
896 { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */
897 { 0x0000, 0x0000 }, /* R792 */
898 { 0x0000, 0x0000 }, /* R793 */
899 { 0x0000, 0x0000 }, /* R794 */
900 { 0x0000, 0x0000 }, /* R795 */
901 { 0x0000, 0x0000 }, /* R796 */
902 { 0x0000, 0x0000 }, /* R797 */
903 { 0x0000, 0x0000 }, /* R798 */
904 { 0x0000, 0x0000 }, /* R799 */
905 { 0x0000, 0x0000 }, /* R800 */
906 { 0x0000, 0x0000 }, /* R801 */
907 { 0x0000, 0x0000 }, /* R802 */
908 { 0x0000, 0x0000 }, /* R803 */
909 { 0x0000, 0x0000 }, /* R804 */
910 { 0x0000, 0x0000 }, /* R805 */
911 { 0x0000, 0x0000 }, /* R806 */
912 { 0x0000, 0x0000 }, /* R807 */
913 { 0x0000, 0x0000 }, /* R808 */
914 { 0x0000, 0x0000 }, /* R809 */
915 { 0x0000, 0x0000 }, /* R810 */
916 { 0x0000, 0x0000 }, /* R811 */
917 { 0x0000, 0x0000 }, /* R812 */
918 { 0x0000, 0x0000 }, /* R813 */
919 { 0x0000, 0x0000 }, /* R814 */
920 { 0x0000, 0x0000 }, /* R815 */
921 { 0x0000, 0x0000 }, /* R816 */
922 { 0x0000, 0x0000 }, /* R817 */
923 { 0x0000, 0x0000 }, /* R818 */
924 { 0x0000, 0x0000 }, /* R819 */
925 { 0x0000, 0x0000 }, /* R820 */
926 { 0x0000, 0x0000 }, /* R821 */
927 { 0x0000, 0x0000 }, /* R822 */
928 { 0x0000, 0x0000 }, /* R823 */
929 { 0x0000, 0x0000 }, /* R824 */
930 { 0x0000, 0x0000 }, /* R825 */
931 { 0x0000, 0x0000 }, /* R826 */
932 { 0x0000, 0x0000 }, /* R827 */
933 { 0x0000, 0x0000 }, /* R828 */
934 { 0x0000, 0x0000 }, /* R829 */
935 { 0x0000, 0x0000 }, /* R830 */
936 { 0x0000, 0x0000 }, /* R831 */
937 { 0x0000, 0x0000 }, /* R832 */
938 { 0x0000, 0x0000 }, /* R833 */
939 { 0x0000, 0x0000 }, /* R834 */
940 { 0x0000, 0x0000 }, /* R835 */
941 { 0x0000, 0x0000 }, /* R836 */
942 { 0x0000, 0x0000 }, /* R837 */
943 { 0x0000, 0x0000 }, /* R838 */
944 { 0x0000, 0x0000 }, /* R839 */
945 { 0x0000, 0x0000 }, /* R840 */
946 { 0x0000, 0x0000 }, /* R841 */
947 { 0x0000, 0x0000 }, /* R842 */
948 { 0x0000, 0x0000 }, /* R843 */
949 { 0x0000, 0x0000 }, /* R844 */
950 { 0x0000, 0x0000 }, /* R845 */
951 { 0x0000, 0x0000 }, /* R846 */
952 { 0x0000, 0x0000 }, /* R847 */
953 { 0x0000, 0x0000 }, /* R848 */
954 { 0x0000, 0x0000 }, /* R849 */
955 { 0x0000, 0x0000 }, /* R850 */
956 { 0x0000, 0x0000 }, /* R851 */
957 { 0x0000, 0x0000 }, /* R852 */
958 { 0x0000, 0x0000 }, /* R853 */
959 { 0x0000, 0x0000 }, /* R854 */
960 { 0x0000, 0x0000 }, /* R855 */
961 { 0x0000, 0x0000 }, /* R856 */
962 { 0x0000, 0x0000 }, /* R857 */
963 { 0x0000, 0x0000 }, /* R858 */
964 { 0x0000, 0x0000 }, /* R859 */
965 { 0x0000, 0x0000 }, /* R860 */
966 { 0x0000, 0x0000 }, /* R861 */
967 { 0x0000, 0x0000 }, /* R862 */
968 { 0x0000, 0x0000 }, /* R863 */
969 { 0x0000, 0x0000 }, /* R864 */
970 { 0x0000, 0x0000 }, /* R865 */
971 { 0x0000, 0x0000 }, /* R866 */
972 { 0x0000, 0x0000 }, /* R867 */
973 { 0x0000, 0x0000 }, /* R868 */
974 { 0x0000, 0x0000 }, /* R869 */
975 { 0x0000, 0x0000 }, /* R870 */
976 { 0x0000, 0x0000 }, /* R871 */
977 { 0x0000, 0x0000 }, /* R872 */
978 { 0x0000, 0x0000 }, /* R873 */
979 { 0x0000, 0x0000 }, /* R874 */
980 { 0x0000, 0x0000 }, /* R875 */
981 { 0x0000, 0x0000 }, /* R876 */
982 { 0x0000, 0x0000 }, /* R877 */
983 { 0x0000, 0x0000 }, /* R878 */
984 { 0x0000, 0x0000 }, /* R879 */
985 { 0x0000, 0x0000 }, /* R880 */
986 { 0x0000, 0x0000 }, /* R881 */
987 { 0x0000, 0x0000 }, /* R882 */
988 { 0x0000, 0x0000 }, /* R883 */
989 { 0x0000, 0x0000 }, /* R884 */
990 { 0x0000, 0x0000 }, /* R885 */
991 { 0x0000, 0x0000 }, /* R886 */
992 { 0x0000, 0x0000 }, /* R887 */
993 { 0x0000, 0x0000 }, /* R888 */
994 { 0x0000, 0x0000 }, /* R889 */
995 { 0x0000, 0x0000 }, /* R890 */
996 { 0x0000, 0x0000 }, /* R891 */
997 { 0x0000, 0x0000 }, /* R892 */
998 { 0x0000, 0x0000 }, /* R893 */
999 { 0x0000, 0x0000 }, /* R894 */
1000 { 0x0000, 0x0000 }, /* R895 */
1001 { 0x0000, 0x0000 }, /* R896 */
1002 { 0x0000, 0x0000 }, /* R897 */
1003 { 0x0000, 0x0000 }, /* R898 */
1004 { 0x0000, 0x0000 }, /* R899 */
1005 { 0x0000, 0x0000 }, /* R900 */
1006 { 0x0000, 0x0000 }, /* R901 */
1007 { 0x0000, 0x0000 }, /* R902 */
1008 { 0x0000, 0x0000 }, /* R903 */
1009 { 0x0000, 0x0000 }, /* R904 */
1010 { 0x0000, 0x0000 }, /* R905 */
1011 { 0x0000, 0x0000 }, /* R906 */
1012 { 0x0000, 0x0000 }, /* R907 */
1013 { 0x0000, 0x0000 }, /* R908 */
1014 { 0x0000, 0x0000 }, /* R909 */
1015 { 0x0000, 0x0000 }, /* R910 */
1016 { 0x0000, 0x0000 }, /* R911 */
1017 { 0x0000, 0x0000 }, /* R912 */
1018 { 0x0000, 0x0000 }, /* R913 */
1019 { 0x0000, 0x0000 }, /* R914 */
1020 { 0x0000, 0x0000 }, /* R915 */
1021 { 0x0000, 0x0000 }, /* R916 */
1022 { 0x0000, 0x0000 }, /* R917 */
1023 { 0x0000, 0x0000 }, /* R918 */
1024 { 0x0000, 0x0000 }, /* R919 */
1025 { 0x0000, 0x0000 }, /* R920 */
1026 { 0x0000, 0x0000 }, /* R921 */
1027 { 0x0000, 0x0000 }, /* R922 */
1028 { 0x0000, 0x0000 }, /* R923 */
1029 { 0x0000, 0x0000 }, /* R924 */
1030 { 0x0000, 0x0000 }, /* R925 */
1031 { 0x0000, 0x0000 }, /* R926 */
1032 { 0x0000, 0x0000 }, /* R927 */
1033 { 0x0000, 0x0000 }, /* R928 */
1034 { 0x0000, 0x0000 }, /* R929 */
1035 { 0x0000, 0x0000 }, /* R930 */
1036 { 0x0000, 0x0000 }, /* R931 */
1037 { 0x0000, 0x0000 }, /* R932 */
1038 { 0x0000, 0x0000 }, /* R933 */
1039 { 0x0000, 0x0000 }, /* R934 */
1040 { 0x0000, 0x0000 }, /* R935 */
1041 { 0x0000, 0x0000 }, /* R936 */
1042 { 0x0000, 0x0000 }, /* R937 */
1043 { 0x0000, 0x0000 }, /* R938 */
1044 { 0x0000, 0x0000 }, /* R939 */
1045 { 0x0000, 0x0000 }, /* R940 */
1046 { 0x0000, 0x0000 }, /* R941 */
1047 { 0x0000, 0x0000 }, /* R942 */
1048 { 0x0000, 0x0000 }, /* R943 */
1049 { 0x0000, 0x0000 }, /* R944 */
1050 { 0x0000, 0x0000 }, /* R945 */
1051 { 0x0000, 0x0000 }, /* R946 */
1052 { 0x0000, 0x0000 }, /* R947 */
1053 { 0x0000, 0x0000 }, /* R948 */
1054 { 0x0000, 0x0000 }, /* R949 */
1055 { 0x0000, 0x0000 }, /* R950 */
1056 { 0x0000, 0x0000 }, /* R951 */
1057 { 0x0000, 0x0000 }, /* R952 */
1058 { 0x0000, 0x0000 }, /* R953 */
1059 { 0x0000, 0x0000 }, /* R954 */
1060 { 0x0000, 0x0000 }, /* R955 */
1061 { 0x0000, 0x0000 }, /* R956 */
1062 { 0x0000, 0x0000 }, /* R957 */
1063 { 0x0000, 0x0000 }, /* R958 */
1064 { 0x0000, 0x0000 }, /* R959 */
1065 { 0x0000, 0x0000 }, /* R960 */
1066 { 0x0000, 0x0000 }, /* R961 */
1067 { 0x0000, 0x0000 }, /* R962 */
1068 { 0x0000, 0x0000 }, /* R963 */
1069 { 0x0000, 0x0000 }, /* R964 */
1070 { 0x0000, 0x0000 }, /* R965 */
1071 { 0x0000, 0x0000 }, /* R966 */
1072 { 0x0000, 0x0000 }, /* R967 */
1073 { 0x0000, 0x0000 }, /* R968 */
1074 { 0x0000, 0x0000 }, /* R969 */
1075 { 0x0000, 0x0000 }, /* R970 */
1076 { 0x0000, 0x0000 }, /* R971 */
1077 { 0x0000, 0x0000 }, /* R972 */
1078 { 0x0000, 0x0000 }, /* R973 */
1079 { 0x0000, 0x0000 }, /* R974 */
1080 { 0x0000, 0x0000 }, /* R975 */
1081 { 0x0000, 0x0000 }, /* R976 */
1082 { 0x0000, 0x0000 }, /* R977 */
1083 { 0x0000, 0x0000 }, /* R978 */
1084 { 0x0000, 0x0000 }, /* R979 */
1085 { 0x0000, 0x0000 }, /* R980 */
1086 { 0x0000, 0x0000 }, /* R981 */
1087 { 0x0000, 0x0000 }, /* R982 */
1088 { 0x0000, 0x0000 }, /* R983 */
1089 { 0x0000, 0x0000 }, /* R984 */
1090 { 0x0000, 0x0000 }, /* R985 */
1091 { 0x0000, 0x0000 }, /* R986 */
1092 { 0x0000, 0x0000 }, /* R987 */
1093 { 0x0000, 0x0000 }, /* R988 */
1094 { 0x0000, 0x0000 }, /* R989 */
1095 { 0x0000, 0x0000 }, /* R990 */
1096 { 0x0000, 0x0000 }, /* R991 */
1097 { 0x0000, 0x0000 }, /* R992 */
1098 { 0x0000, 0x0000 }, /* R993 */
1099 { 0x0000, 0x0000 }, /* R994 */
1100 { 0x0000, 0x0000 }, /* R995 */
1101 { 0x0000, 0x0000 }, /* R996 */
1102 { 0x0000, 0x0000 }, /* R997 */
1103 { 0x0000, 0x0000 }, /* R998 */
1104 { 0x0000, 0x0000 }, /* R999 */
1105 { 0x0000, 0x0000 }, /* R1000 */
1106 { 0x0000, 0x0000 }, /* R1001 */
1107 { 0x0000, 0x0000 }, /* R1002 */
1108 { 0x0000, 0x0000 }, /* R1003 */
1109 { 0x0000, 0x0000 }, /* R1004 */
1110 { 0x0000, 0x0000 }, /* R1005 */
1111 { 0x0000, 0x0000 }, /* R1006 */
1112 { 0x0000, 0x0000 }, /* R1007 */
1113 { 0x0000, 0x0000 }, /* R1008 */
1114 { 0x0000, 0x0000 }, /* R1009 */
1115 { 0x0000, 0x0000 }, /* R1010 */
1116 { 0x0000, 0x0000 }, /* R1011 */
1117 { 0x0000, 0x0000 }, /* R1012 */
1118 { 0x0000, 0x0000 }, /* R1013 */
1119 { 0x0000, 0x0000 }, /* R1014 */
1120 { 0x0000, 0x0000 }, /* R1015 */
1121 { 0x0000, 0x0000 }, /* R1016 */
1122 { 0x0000, 0x0000 }, /* R1017 */
1123 { 0x0000, 0x0000 }, /* R1018 */
1124 { 0x0000, 0x0000 }, /* R1019 */
1125 { 0x0000, 0x0000 }, /* R1020 */
1126 { 0x0000, 0x0000 }, /* R1021 */
1127 { 0x0000, 0x0000 }, /* R1022 */
1128 { 0x0000, 0x0000 }, /* R1023 */
1129 { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */
1130 { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */
1131 { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */
1132 { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */
1133 { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */
1134 { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */
1135 { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */
1136 { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */
1137 { 0x0000, 0x0000 }, /* R1032 */
1138 { 0x0000, 0x0000 }, /* R1033 */
1139 { 0x0000, 0x0000 }, /* R1034 */
1140 { 0x0000, 0x0000 }, /* R1035 */
1141 { 0x0000, 0x0000 }, /* R1036 */
1142 { 0x0000, 0x0000 }, /* R1037 */
1143 { 0x0000, 0x0000 }, /* R1038 */
1144 { 0x0000, 0x0000 }, /* R1039 */
1145 { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */
1146 { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */
1147 { 0x0000, 0x0000 }, /* R1042 */
1148 { 0x0000, 0x0000 }, /* R1043 */
1149 { 0x0000, 0x0000 }, /* R1044 */
1150 { 0x0000, 0x0000 }, /* R1045 */
1151 { 0x0000, 0x0000 }, /* R1046 */
1152 { 0x0000, 0x0000 }, /* R1047 */
1153 { 0x0000, 0x0000 }, /* R1048 */
1154 { 0x0000, 0x0000 }, /* R1049 */
1155 { 0x0000, 0x0000 }, /* R1050 */
1156 { 0x0000, 0x0000 }, /* R1051 */
1157 { 0x0000, 0x0000 }, /* R1052 */
1158 { 0x0000, 0x0000 }, /* R1053 */
1159 { 0x0000, 0x0000 }, /* R1054 */
1160 { 0x0000, 0x0000 }, /* R1055 */
1161 { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */
1162 { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */
1163 { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */
1164 { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */
1165 { 0x0000, 0x0000 }, /* R1060 */
1166 { 0x0000, 0x0000 }, /* R1061 */
1167 { 0x0000, 0x0000 }, /* R1062 */
1168 { 0x0000, 0x0000 }, /* R1063 */
1169 { 0x0000, 0x0000 }, /* R1064 */
1170 { 0x0000, 0x0000 }, /* R1065 */
1171 { 0x0000, 0x0000 }, /* R1066 */
1172 { 0x0000, 0x0000 }, /* R1067 */
1173 { 0x0000, 0x0000 }, /* R1068 */
1174 { 0x0000, 0x0000 }, /* R1069 */
1175 { 0x0000, 0x0000 }, /* R1070 */
1176 { 0x0000, 0x0000 }, /* R1071 */
1177 { 0x0000, 0x0000 }, /* R1072 */
1178 { 0x0000, 0x0000 }, /* R1073 */
1179 { 0x0000, 0x0000 }, /* R1074 */
1180 { 0x0000, 0x0000 }, /* R1075 */
1181 { 0x0000, 0x0000 }, /* R1076 */
1182 { 0x0000, 0x0000 }, /* R1077 */
1183 { 0x0000, 0x0000 }, /* R1078 */
1184 { 0x0000, 0x0000 }, /* R1079 */
1185 { 0x0000, 0x0000 }, /* R1080 */
1186 { 0x0000, 0x0000 }, /* R1081 */
1187 { 0x0000, 0x0000 }, /* R1082 */
1188 { 0x0000, 0x0000 }, /* R1083 */
1189 { 0x0000, 0x0000 }, /* R1084 */
1190 { 0x0000, 0x0000 }, /* R1085 */
1191 { 0x0000, 0x0000 }, /* R1086 */
1192 { 0x0000, 0x0000 }, /* R1087 */
1193 { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */
1194 { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */
1195 { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */
1196 { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */
1197 { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */
1198 { 0x0000, 0x0000 }, /* R1093 */
1199 { 0x0000, 0x0000 }, /* R1094 */
1200 { 0x0000, 0x0000 }, /* R1095 */
1201 { 0x0000, 0x0000 }, /* R1096 */
1202 { 0x0000, 0x0000 }, /* R1097 */
1203 { 0x0000, 0x0000 }, /* R1098 */
1204 { 0x0000, 0x0000 }, /* R1099 */
1205 { 0x0000, 0x0000 }, /* R1100 */
1206 { 0x0000, 0x0000 }, /* R1101 */
1207 { 0x0000, 0x0000 }, /* R1102 */
1208 { 0x0000, 0x0000 }, /* R1103 */
1209 { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */
1210 { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */
1211 { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */
1212 { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */
1213 { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */
1214 { 0x0000, 0x0000 }, /* R1109 */
1215 { 0x0000, 0x0000 }, /* R1110 */
1216 { 0x0000, 0x0000 }, /* R1111 */
1217 { 0x0000, 0x0000 }, /* R1112 */
1218 { 0x0000, 0x0000 }, /* R1113 */
1219 { 0x0000, 0x0000 }, /* R1114 */
1220 { 0x0000, 0x0000 }, /* R1115 */
1221 { 0x0000, 0x0000 }, /* R1116 */
1222 { 0x0000, 0x0000 }, /* R1117 */
1223 { 0x0000, 0x0000 }, /* R1118 */
1224 { 0x0000, 0x0000 }, /* R1119 */
1225 { 0x0000, 0x0000 }, /* R1120 */
1226 { 0x0000, 0x0000 }, /* R1121 */
1227 { 0x0000, 0x0000 }, /* R1122 */
1228 { 0x0000, 0x0000 }, /* R1123 */
1229 { 0x0000, 0x0000 }, /* R1124 */
1230 { 0x0000, 0x0000 }, /* R1125 */
1231 { 0x0000, 0x0000 }, /* R1126 */
1232 { 0x0000, 0x0000 }, /* R1127 */
1233 { 0x0000, 0x0000 }, /* R1128 */
1234 { 0x0000, 0x0000 }, /* R1129 */
1235 { 0x0000, 0x0000 }, /* R1130 */
1236 { 0x0000, 0x0000 }, /* R1131 */
1237 { 0x0000, 0x0000 }, /* R1132 */
1238 { 0x0000, 0x0000 }, /* R1133 */
1239 { 0x0000, 0x0000 }, /* R1134 */
1240 { 0x0000, 0x0000 }, /* R1135 */
1241 { 0x0000, 0x0000 }, /* R1136 */
1242 { 0x0000, 0x0000 }, /* R1137 */
1243 { 0x0000, 0x0000 }, /* R1138 */
1244 { 0x0000, 0x0000 }, /* R1139 */
1245 { 0x0000, 0x0000 }, /* R1140 */
1246 { 0x0000, 0x0000 }, /* R1141 */
1247 { 0x0000, 0x0000 }, /* R1142 */
1248 { 0x0000, 0x0000 }, /* R1143 */
1249 { 0x0000, 0x0000 }, /* R1144 */
1250 { 0x0000, 0x0000 }, /* R1145 */
1251 { 0x0000, 0x0000 }, /* R1146 */
1252 { 0x0000, 0x0000 }, /* R1147 */
1253 { 0x0000, 0x0000 }, /* R1148 */
1254 { 0x0000, 0x0000 }, /* R1149 */
1255 { 0x0000, 0x0000 }, /* R1150 */
1256 { 0x0000, 0x0000 }, /* R1151 */
1257 { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */
1258 { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */
1259 { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */
1260 { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */
1261 { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */
1262 { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */
1263 { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */
1264 { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */
1265 { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */
1266 { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */
1267 { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */
1268 { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */
1269 { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */
1270 { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */
1271 { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */
1272 { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */
1273 { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */
1274 { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */
1275 { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */
1276 { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */
1277 { 0x0000, 0x0000 }, /* R1172 */
1278 { 0x0000, 0x0000 }, /* R1173 */
1279 { 0x0000, 0x0000 }, /* R1174 */
1280 { 0x0000, 0x0000 }, /* R1175 */
1281 { 0x0000, 0x0000 }, /* R1176 */
1282 { 0x0000, 0x0000 }, /* R1177 */
1283 { 0x0000, 0x0000 }, /* R1178 */
1284 { 0x0000, 0x0000 }, /* R1179 */
1285 { 0x0000, 0x0000 }, /* R1180 */
1286 { 0x0000, 0x0000 }, /* R1181 */
1287 { 0x0000, 0x0000 }, /* R1182 */
1288 { 0x0000, 0x0000 }, /* R1183 */
1289 { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */
1290 { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */
1291 { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */
1292 { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */
1293 { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */
1294 { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */
1295 { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */
1296 { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */
1297 { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */
1298 { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */
1299 { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */
1300 { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */
1301 { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */
1302 { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */
1303 { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */
1304 { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */
1305 { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */
1306 { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */
1307 { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */
1308 { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */
1309 { 0x0000, 0x0000 }, /* R1204 */
1310 { 0x0000, 0x0000 }, /* R1205 */
1311 { 0x0000, 0x0000 }, /* R1206 */
1312 { 0x0000, 0x0000 }, /* R1207 */
1313 { 0x0000, 0x0000 }, /* R1208 */
1314 { 0x0000, 0x0000 }, /* R1209 */
1315 { 0x0000, 0x0000 }, /* R1210 */
1316 { 0x0000, 0x0000 }, /* R1211 */
1317 { 0x0000, 0x0000 }, /* R1212 */
1318 { 0x0000, 0x0000 }, /* R1213 */
1319 { 0x0000, 0x0000 }, /* R1214 */
1320 { 0x0000, 0x0000 }, /* R1215 */
1321 { 0x0000, 0x0000 }, /* R1216 */
1322 { 0x0000, 0x0000 }, /* R1217 */
1323 { 0x0000, 0x0000 }, /* R1218 */
1324 { 0x0000, 0x0000 }, /* R1219 */
1325 { 0x0000, 0x0000 }, /* R1220 */
1326 { 0x0000, 0x0000 }, /* R1221 */
1327 { 0x0000, 0x0000 }, /* R1222 */
1328 { 0x0000, 0x0000 }, /* R1223 */
1329 { 0x0000, 0x0000 }, /* R1224 */
1330 { 0x0000, 0x0000 }, /* R1225 */
1331 { 0x0000, 0x0000 }, /* R1226 */
1332 { 0x0000, 0x0000 }, /* R1227 */
1333 { 0x0000, 0x0000 }, /* R1228 */
1334 { 0x0000, 0x0000 }, /* R1229 */
1335 { 0x0000, 0x0000 }, /* R1230 */
1336 { 0x0000, 0x0000 }, /* R1231 */
1337 { 0x0000, 0x0000 }, /* R1232 */
1338 { 0x0000, 0x0000 }, /* R1233 */
1339 { 0x0000, 0x0000 }, /* R1234 */
1340 { 0x0000, 0x0000 }, /* R1235 */
1341 { 0x0000, 0x0000 }, /* R1236 */
1342 { 0x0000, 0x0000 }, /* R1237 */
1343 { 0x0000, 0x0000 }, /* R1238 */
1344 { 0x0000, 0x0000 }, /* R1239 */
1345 { 0x0000, 0x0000 }, /* R1240 */
1346 { 0x0000, 0x0000 }, /* R1241 */
1347 { 0x0000, 0x0000 }, /* R1242 */
1348 { 0x0000, 0x0000 }, /* R1243 */
1349 { 0x0000, 0x0000 }, /* R1244 */
1350 { 0x0000, 0x0000 }, /* R1245 */
1351 { 0x0000, 0x0000 }, /* R1246 */
1352 { 0x0000, 0x0000 }, /* R1247 */
1353 { 0x0000, 0x0000 }, /* R1248 */
1354 { 0x0000, 0x0000 }, /* R1249 */
1355 { 0x0000, 0x0000 }, /* R1250 */
1356 { 0x0000, 0x0000 }, /* R1251 */
1357 { 0x0000, 0x0000 }, /* R1252 */
1358 { 0x0000, 0x0000 }, /* R1253 */
1359 { 0x0000, 0x0000 }, /* R1254 */
1360 { 0x0000, 0x0000 }, /* R1255 */
1361 { 0x0000, 0x0000 }, /* R1256 */
1362 { 0x0000, 0x0000 }, /* R1257 */
1363 { 0x0000, 0x0000 }, /* R1258 */
1364 { 0x0000, 0x0000 }, /* R1259 */
1365 { 0x0000, 0x0000 }, /* R1260 */
1366 { 0x0000, 0x0000 }, /* R1261 */
1367 { 0x0000, 0x0000 }, /* R1262 */
1368 { 0x0000, 0x0000 }, /* R1263 */
1369 { 0x0000, 0x0000 }, /* R1264 */
1370 { 0x0000, 0x0000 }, /* R1265 */
1371 { 0x0000, 0x0000 }, /* R1266 */
1372 { 0x0000, 0x0000 }, /* R1267 */
1373 { 0x0000, 0x0000 }, /* R1268 */
1374 { 0x0000, 0x0000 }, /* R1269 */
1375 { 0x0000, 0x0000 }, /* R1270 */
1376 { 0x0000, 0x0000 }, /* R1271 */
1377 { 0x0000, 0x0000 }, /* R1272 */
1378 { 0x0000, 0x0000 }, /* R1273 */
1379 { 0x0000, 0x0000 }, /* R1274 */
1380 { 0x0000, 0x0000 }, /* R1275 */
1381 { 0x0000, 0x0000 }, /* R1276 */
1382 { 0x0000, 0x0000 }, /* R1277 */
1383 { 0x0000, 0x0000 }, /* R1278 */
1384 { 0x0000, 0x0000 }, /* R1279 */
1385 { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */
1386 { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */
1387 { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */
1388 { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */
1389 { 0x0000, 0x0000 }, /* R1284 */
1390 { 0x0000, 0x0000 }, /* R1285 */
1391 { 0x0000, 0x0000 }, /* R1286 */
1392 { 0x0000, 0x0000 }, /* R1287 */
1393 { 0x0000, 0x0000 }, /* R1288 */
1394 { 0x0000, 0x0000 }, /* R1289 */
1395 { 0x0000, 0x0000 }, /* R1290 */
1396 { 0x0000, 0x0000 }, /* R1291 */
1397 { 0x0000, 0x0000 }, /* R1292 */
1398 { 0x0000, 0x0000 }, /* R1293 */
1399 { 0x0000, 0x0000 }, /* R1294 */
1400 { 0x0000, 0x0000 }, /* R1295 */
1401 { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */
1402 { 0x0000, 0x0000 }, /* R1297 */
1403 { 0x0000, 0x0000 }, /* R1298 */
1404 { 0x0000, 0x0000 }, /* R1299 */
1405 { 0x0000, 0x0000 }, /* R1300 */
1406 { 0x0000, 0x0000 }, /* R1301 */
1407 { 0x0000, 0x0000 }, /* R1302 */
1408 { 0x0000, 0x0000 }, /* R1303 */
1409 { 0x0000, 0x0000 }, /* R1304 */
1410 { 0x0000, 0x0000 }, /* R1305 */
1411 { 0x0000, 0x0000 }, /* R1306 */
1412 { 0x0000, 0x0000 }, /* R1307 */
1413 { 0x0000, 0x0000 }, /* R1308 */
1414 { 0x0000, 0x0000 }, /* R1309 */
1415 { 0x0000, 0x0000 }, /* R1310 */
1416 { 0x0000, 0x0000 }, /* R1311 */
1417 { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */
1418 { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */
1419 { 0x0000, 0x0000 }, /* R1314 */
1420 { 0x0000, 0x0000 }, /* R1315 */
1421 { 0x0000, 0x0000 }, /* R1316 */
1422 { 0x0000, 0x0000 }, /* R1317 */
1423 { 0x0000, 0x0000 }, /* R1318 */
1424 { 0x0000, 0x0000 }, /* R1319 */
1425 { 0x0000, 0x0000 }, /* R1320 */
1426 { 0x0000, 0x0000 }, /* R1321 */
1427 { 0x0000, 0x0000 }, /* R1322 */
1428 { 0x0000, 0x0000 }, /* R1323 */
1429 { 0x0000, 0x0000 }, /* R1324 */
1430 { 0x0000, 0x0000 }, /* R1325 */
1431 { 0x0000, 0x0000 }, /* R1326 */
1432 { 0x0000, 0x0000 }, /* R1327 */
1433 { 0x0000, 0x0000 }, /* R1328 */
1434 { 0x0000, 0x0000 }, /* R1329 */
1435 { 0x0000, 0x0000 }, /* R1330 */
1436 { 0x0000, 0x0000 }, /* R1331 */
1437 { 0x0000, 0x0000 }, /* R1332 */
1438 { 0x0000, 0x0000 }, /* R1333 */
1439 { 0x0000, 0x0000 }, /* R1334 */
1440 { 0x0000, 0x0000 }, /* R1335 */
1441 { 0x0000, 0x0000 }, /* R1336 */
1442 { 0x0000, 0x0000 }, /* R1337 */
1443 { 0x0000, 0x0000 }, /* R1338 */
1444 { 0x0000, 0x0000 }, /* R1339 */
1445 { 0x0000, 0x0000 }, /* R1340 */
1446 { 0x0000, 0x0000 }, /* R1341 */
1447 { 0x0000, 0x0000 }, /* R1342 */
1448 { 0x0000, 0x0000 }, /* R1343 */
1449 { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */
1450 { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */
1451 { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */
1452 { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */
1453 { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */
1454 { 0x0000, 0x0000 }, /* R1349 */
1455 { 0x0000, 0x0000 }, /* R1350 */
1456 { 0x0000, 0x0000 }, /* R1351 */
1457 { 0x0000, 0x0000 }, /* R1352 */
1458 { 0x0000, 0x0000 }, /* R1353 */
1459 { 0x0000, 0x0000 }, /* R1354 */
1460 { 0x0000, 0x0000 }, /* R1355 */
1461 { 0x0000, 0x0000 }, /* R1356 */
1462 { 0x0000, 0x0000 }, /* R1357 */
1463 { 0x0000, 0x0000 }, /* R1358 */
1464 { 0x0000, 0x0000 }, /* R1359 */
1465 { 0x0000, 0x0000 }, /* R1360 */
1466 { 0x0000, 0x0000 }, /* R1361 */
1467 { 0x0000, 0x0000 }, /* R1362 */
1468 { 0x0000, 0x0000 }, /* R1363 */
1469 { 0x0000, 0x0000 }, /* R1364 */
1470 { 0x0000, 0x0000 }, /* R1365 */
1471 { 0x0000, 0x0000 }, /* R1366 */
1472 { 0x0000, 0x0000 }, /* R1367 */
1473 { 0x0000, 0x0000 }, /* R1368 */
1474 { 0x0000, 0x0000 }, /* R1369 */
1475 { 0x0000, 0x0000 }, /* R1370 */
1476 { 0x0000, 0x0000 }, /* R1371 */
1477 { 0x0000, 0x0000 }, /* R1372 */
1478 { 0x0000, 0x0000 }, /* R1373 */
1479 { 0x0000, 0x0000 }, /* R1374 */
1480 { 0x0000, 0x0000 }, /* R1375 */
1481 { 0x0000, 0x0000 }, /* R1376 */
1482 { 0x0000, 0x0000 }, /* R1377 */
1483 { 0x0000, 0x0000 }, /* R1378 */
1484 { 0x0000, 0x0000 }, /* R1379 */
1485 { 0x0000, 0x0000 }, /* R1380 */
1486 { 0x0000, 0x0000 }, /* R1381 */
1487 { 0x0000, 0x0000 }, /* R1382 */
1488 { 0x0000, 0x0000 }, /* R1383 */
1489 { 0x0000, 0x0000 }, /* R1384 */
1490 { 0x0000, 0x0000 }, /* R1385 */
1491 { 0x0000, 0x0000 }, /* R1386 */
1492 { 0x0000, 0x0000 }, /* R1387 */
1493 { 0x0000, 0x0000 }, /* R1388 */
1494 { 0x0000, 0x0000 }, /* R1389 */
1495 { 0x0000, 0x0000 }, /* R1390 */
1496 { 0x0000, 0x0000 }, /* R1391 */
1497 { 0x0000, 0x0000 }, /* R1392 */
1498 { 0x0000, 0x0000 }, /* R1393 */
1499 { 0x0000, 0x0000 }, /* R1394 */
1500 { 0x0000, 0x0000 }, /* R1395 */
1501 { 0x0000, 0x0000 }, /* R1396 */
1502 { 0x0000, 0x0000 }, /* R1397 */
1503 { 0x0000, 0x0000 }, /* R1398 */
1504 { 0x0000, 0x0000 }, /* R1399 */
1505 { 0x0000, 0x0000 }, /* R1400 */
1506 { 0x0000, 0x0000 }, /* R1401 */
1507 { 0x0000, 0x0000 }, /* R1402 */
1508 { 0x0000, 0x0000 }, /* R1403 */
1509 { 0x0000, 0x0000 }, /* R1404 */
1510 { 0x0000, 0x0000 }, /* R1405 */
1511 { 0x0000, 0x0000 }, /* R1406 */
1512 { 0x0000, 0x0000 }, /* R1407 */
1513 { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */
1514 { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */
1515 { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */
1516 { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */
1517 { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */
1518 { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */
1519 { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */
1520 { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */
1521 { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */
1522 { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */
1523 { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */
1524 { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */
1525 { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */
1526 { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */
1527 { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */
1528 { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */
1529 { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */
1530 { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */
1531 { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */
1532 { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */
1533 { 0x0000, 0x0000 }, /* R1428 */
1534 { 0x0000, 0x0000 }, /* R1429 */
1535 { 0x0000, 0x0000 }, /* R1430 */
1536 { 0x0000, 0x0000 }, /* R1431 */
1537 { 0x0000, 0x0000 }, /* R1432 */
1538 { 0x0000, 0x0000 }, /* R1433 */
1539 { 0x0000, 0x0000 }, /* R1434 */
1540 { 0x0000, 0x0000 }, /* R1435 */
1541 { 0x0000, 0x0000 }, /* R1436 */
1542 { 0x0000, 0x0000 }, /* R1437 */
1543 { 0x0000, 0x0000 }, /* R1438 */
1544 { 0x0000, 0x0000 }, /* R1439 */
1545 { 0x0000, 0x0000 }, /* R1440 */
1546 { 0x0000, 0x0000 }, /* R1441 */
1547 { 0x0000, 0x0000 }, /* R1442 */
1548 { 0x0000, 0x0000 }, /* R1443 */
1549 { 0x0000, 0x0000 }, /* R1444 */
1550 { 0x0000, 0x0000 }, /* R1445 */
1551 { 0x0000, 0x0000 }, /* R1446 */
1552 { 0x0000, 0x0000 }, /* R1447 */
1553 { 0x0000, 0x0000 }, /* R1448 */
1554 { 0x0000, 0x0000 }, /* R1449 */
1555 { 0x0000, 0x0000 }, /* R1450 */
1556 { 0x0000, 0x0000 }, /* R1451 */
1557 { 0x0000, 0x0000 }, /* R1452 */
1558 { 0x0000, 0x0000 }, /* R1453 */
1559 { 0x0000, 0x0000 }, /* R1454 */
1560 { 0x0000, 0x0000 }, /* R1455 */
1561 { 0x0000, 0x0000 }, /* R1456 */
1562 { 0x0000, 0x0000 }, /* R1457 */
1563 { 0x0000, 0x0000 }, /* R1458 */
1564 { 0x0000, 0x0000 }, /* R1459 */
1565 { 0x0000, 0x0000 }, /* R1460 */
1566 { 0x0000, 0x0000 }, /* R1461 */
1567 { 0x0000, 0x0000 }, /* R1462 */
1568 { 0x0000, 0x0000 }, /* R1463 */
1569 { 0x0000, 0x0000 }, /* R1464 */
1570 { 0x0000, 0x0000 }, /* R1465 */
1571 { 0x0000, 0x0000 }, /* R1466 */
1572 { 0x0000, 0x0000 }, /* R1467 */
1573 { 0x0000, 0x0000 }, /* R1468 */
1574 { 0x0000, 0x0000 }, /* R1469 */
1575 { 0x0000, 0x0000 }, /* R1470 */
1576 { 0x0000, 0x0000 }, /* R1471 */
1577 { 0x0000, 0x0000 }, /* R1472 */
1578 { 0x0000, 0x0000 }, /* R1473 */
1579 { 0x0000, 0x0000 }, /* R1474 */
1580 { 0x0000, 0x0000 }, /* R1475 */
1581 { 0x0000, 0x0000 }, /* R1476 */
1582 { 0x0000, 0x0000 }, /* R1477 */
1583 { 0x0000, 0x0000 }, /* R1478 */
1584 { 0x0000, 0x0000 }, /* R1479 */
1585 { 0x0000, 0x0000 }, /* R1480 */
1586 { 0x0000, 0x0000 }, /* R1481 */
1587 { 0x0000, 0x0000 }, /* R1482 */
1588 { 0x0000, 0x0000 }, /* R1483 */
1589 { 0x0000, 0x0000 }, /* R1484 */
1590 { 0x0000, 0x0000 }, /* R1485 */
1591 { 0x0000, 0x0000 }, /* R1486 */
1592 { 0x0000, 0x0000 }, /* R1487 */
1593 { 0x0000, 0x0000 }, /* R1488 */
1594 { 0x0000, 0x0000 }, /* R1489 */
1595 { 0x0000, 0x0000 }, /* R1490 */
1596 { 0x0000, 0x0000 }, /* R1491 */
1597 { 0x0000, 0x0000 }, /* R1492 */
1598 { 0x0000, 0x0000 }, /* R1493 */
1599 { 0x0000, 0x0000 }, /* R1494 */
1600 { 0x0000, 0x0000 }, /* R1495 */
1601 { 0x0000, 0x0000 }, /* R1496 */
1602 { 0x0000, 0x0000 }, /* R1497 */
1603 { 0x0000, 0x0000 }, /* R1498 */
1604 { 0x0000, 0x0000 }, /* R1499 */
1605 { 0x0000, 0x0000 }, /* R1500 */
1606 { 0x0000, 0x0000 }, /* R1501 */
1607 { 0x0000, 0x0000 }, /* R1502 */
1608 { 0x0000, 0x0000 }, /* R1503 */
1609 { 0x0000, 0x0000 }, /* R1504 */
1610 { 0x0000, 0x0000 }, /* R1505 */
1611 { 0x0000, 0x0000 }, /* R1506 */
1612 { 0x0000, 0x0000 }, /* R1507 */
1613 { 0x0000, 0x0000 }, /* R1508 */
1614 { 0x0000, 0x0000 }, /* R1509 */
1615 { 0x0000, 0x0000 }, /* R1510 */
1616 { 0x0000, 0x0000 }, /* R1511 */
1617 { 0x0000, 0x0000 }, /* R1512 */
1618 { 0x0000, 0x0000 }, /* R1513 */
1619 { 0x0000, 0x0000 }, /* R1514 */
1620 { 0x0000, 0x0000 }, /* R1515 */
1621 { 0x0000, 0x0000 }, /* R1516 */
1622 { 0x0000, 0x0000 }, /* R1517 */
1623 { 0x0000, 0x0000 }, /* R1518 */
1624 { 0x0000, 0x0000 }, /* R1519 */
1625 { 0x0000, 0x0000 }, /* R1520 */
1626 { 0x0000, 0x0000 }, /* R1521 */
1627 { 0x0000, 0x0000 }, /* R1522 */
1628 { 0x0000, 0x0000 }, /* R1523 */
1629 { 0x0000, 0x0000 }, /* R1524 */
1630 { 0x0000, 0x0000 }, /* R1525 */
1631 { 0x0000, 0x0000 }, /* R1526 */
1632 { 0x0000, 0x0000 }, /* R1527 */
1633 { 0x0000, 0x0000 }, /* R1528 */
1634 { 0x0000, 0x0000 }, /* R1529 */
1635 { 0x0000, 0x0000 }, /* R1530 */
1636 { 0x0000, 0x0000 }, /* R1531 */
1637 { 0x0000, 0x0000 }, /* R1532 */
1638 { 0x0000, 0x0000 }, /* R1533 */
1639 { 0x0000, 0x0000 }, /* R1534 */
1640 { 0x0000, 0x0000 }, /* R1535 */
1641 { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */
1642 { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */
1643 { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */
1644 { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */
1645 { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */
1646 { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */
1647 { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */
1648 { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */
1649 { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */
1650 { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */
1651 { 0x0000, 0x0000 }, /* R1546 */
1652 { 0x0000, 0x0000 }, /* R1547 */
1653 { 0x0000, 0x0000 }, /* R1548 */
1654 { 0x0000, 0x0000 }, /* R1549 */
1655 { 0x0000, 0x0000 }, /* R1550 */
1656 { 0x0000, 0x0000 }, /* R1551 */
1657 { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */
1658 { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */
1659 { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */
1660 { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */
1661 { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */
1662 { 0x0000, 0x0000 }, /* R1557 */
1663 { 0x0000, 0x0000 }, /* R1558 */
1664 { 0x0000, 0x0000 }, /* R1559 */
1665 { 0x0000, 0x0000 }, /* R1560 */
1666 { 0x0000, 0x0000 }, /* R1561 */
1667 { 0x0000, 0x0000 }, /* R1562 */
1668 { 0x0000, 0x0000 }, /* R1563 */
1669 { 0x0000, 0x0000 }, /* R1564 */
1670 { 0x0000, 0x0000 }, /* R1565 */
1671 { 0x0000, 0x0000 }, /* R1566 */
1672 { 0x0000, 0x0000 }, /* R1567 */
1673 { 0x0003, 0x0003 }, /* R1568 - Oversampling */
1674 { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */
1675};
1676
1677static int wm8994_readable(unsigned int reg) 112static int wm8994_readable(unsigned int reg)
1678{ 113{
1679 switch (reg) { 114 switch (reg) {
@@ -1696,14 +131,14 @@ static int wm8994_readable(unsigned int reg)
1696 break; 131 break;
1697 } 132 }
1698 133
1699 if (reg >= ARRAY_SIZE(access_masks)) 134 if (reg >= WM8994_CACHE_SIZE)
1700 return 0; 135 return 0;
1701 return access_masks[reg].readable != 0; 136 return wm8994_access_masks[reg].readable != 0;
1702} 137}
1703 138
1704static int wm8994_volatile(unsigned int reg) 139static int wm8994_volatile(unsigned int reg)
1705{ 140{
1706 if (reg >= WM8994_REG_CACHE_SIZE) 141 if (reg >= WM8994_CACHE_SIZE)
1707 return 1; 142 return 1;
1708 143
1709 switch (reg) { 144 switch (reg) {
@@ -1714,6 +149,8 @@ static int wm8994_volatile(unsigned int reg)
1714 case WM8994_RATE_STATUS: 149 case WM8994_RATE_STATUS:
1715 case WM8994_LDO_1: 150 case WM8994_LDO_1:
1716 case WM8994_LDO_2: 151 case WM8994_LDO_2:
152 case WM8958_DSP2_EXECCONTROL:
153 case WM8958_MIC_DETECT_3:
1717 return 1; 154 return 1;
1718 default: 155 default:
1719 return 0; 156 return 0;
@@ -1723,14 +160,16 @@ static int wm8994_volatile(unsigned int reg)
1723static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, 160static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1724 unsigned int value) 161 unsigned int value)
1725{ 162{
1726 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 163 int ret;
1727 164
1728 BUG_ON(reg > WM8994_MAX_REGISTER); 165 BUG_ON(reg > WM8994_MAX_REGISTER);
1729 166
1730 if (!wm8994_volatile(reg)) 167 if (!wm8994_volatile(reg)) {
1731 wm8994->reg_cache[reg] = value; 168 ret = snd_soc_cache_write(codec, reg, value);
1732 169 if (ret != 0)
1733 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); 170 dev_err(codec->dev, "Cache write to %x failed: %d\n",
171 reg, ret);
172 }
1734 173
1735 return wm8994_reg_write(codec->control_data, reg, value); 174 return wm8994_reg_write(codec->control_data, reg, value);
1736} 175}
@@ -1738,14 +177,22 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg,
1738static unsigned int wm8994_read(struct snd_soc_codec *codec, 177static unsigned int wm8994_read(struct snd_soc_codec *codec,
1739 unsigned int reg) 178 unsigned int reg)
1740{ 179{
1741 u16 *reg_cache = codec->reg_cache; 180 unsigned int val;
181 int ret;
1742 182
1743 BUG_ON(reg > WM8994_MAX_REGISTER); 183 BUG_ON(reg > WM8994_MAX_REGISTER);
1744 184
1745 if (wm8994_volatile(reg)) 185 if (!wm8994_volatile(reg) && wm8994_readable(reg) &&
1746 return wm8994_reg_read(codec->control_data, reg); 186 reg < codec->driver->reg_cache_size) {
1747 else 187 ret = snd_soc_cache_read(codec, reg, &val);
1748 return reg_cache[reg]; 188 if (ret >= 0)
189 return val;
190 else
191 dev_err(codec->dev, "Cache read from %x failed: %d\n",
192 reg, ret);
193 }
194
195 return wm8994_reg_read(codec->control_data, reg);
1749} 196}
1750 197
1751static int configure_aif_clock(struct snd_soc_codec *codec, int aif) 198static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
@@ -1837,7 +284,7 @@ static int configure_clock(struct snd_soc_codec *codec)
1837 284
1838 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new); 285 snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new);
1839 286
1840 snd_soc_dapm_sync(codec); 287 snd_soc_dapm_sync(&codec->dapm);
1841 288
1842 return 0; 289 return 0;
1843} 290}
@@ -1864,6 +311,19 @@ static const char *sidetone_hpf_text[] = {
1864static const struct soc_enum sidetone_hpf = 311static const struct soc_enum sidetone_hpf =
1865 SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text); 312 SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text);
1866 313
314static const char *adc_hpf_text[] = {
315 "HiFi", "Voice 1", "Voice 2", "Voice 3"
316};
317
318static const struct soc_enum aif1adc1_hpf =
319 SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text);
320
321static const struct soc_enum aif1adc2_hpf =
322 SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text);
323
324static const struct soc_enum aif2adc_hpf =
325 SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text);
326
1867static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); 327static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0);
1868static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); 328static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
1869static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0); 329static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0);
@@ -2071,21 +531,252 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,
2071 return 0; 531 return 0;
2072} 532}
2073 533
2074static const char *aifdac_src_text[] = { 534static const char *aif_chan_src_text[] = {
2075 "Left", "Right" 535 "Left", "Right"
2076}; 536};
2077 537
538static const struct soc_enum aif1adcl_src =
539 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text);
540
541static const struct soc_enum aif1adcr_src =
542 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text);
543
544static const struct soc_enum aif2adcl_src =
545 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text);
546
547static const struct soc_enum aif2adcr_src =
548 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text);
549
2078static const struct soc_enum aif1dacl_src = 550static const struct soc_enum aif1dacl_src =
2079 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aifdac_src_text); 551 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text);
2080 552
2081static const struct soc_enum aif1dacr_src = 553static const struct soc_enum aif1dacr_src =
2082 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aifdac_src_text); 554 SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text);
2083 555
2084static const struct soc_enum aif2dacl_src = 556static const struct soc_enum aif2dacl_src =
2085 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aifdac_src_text); 557 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text);
2086 558
2087static const struct soc_enum aif2dacr_src = 559static const struct soc_enum aif2dacr_src =
2088 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aifdac_src_text); 560 SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text);
561
562static const char *osr_text[] = {
563 "Low Power", "High Performance",
564};
565
566static const struct soc_enum dac_osr =
567 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text);
568
569static const struct soc_enum adc_osr =
570 SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text);
571
572static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start)
573{
574 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
575 struct wm8994_pdata *pdata = wm8994->pdata;
576 int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5);
577 int ena, reg, aif, i;
578
579 switch (mbc) {
580 case 0:
581 pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA);
582 aif = 0;
583 break;
584 case 1:
585 pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA);
586 aif = 0;
587 break;
588 case 2:
589 pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA);
590 aif = 1;
591 break;
592 default:
593 BUG();
594 return;
595 }
596
597 /* We can only enable the MBC if the AIF is enabled and we
598 * want it to be enabled. */
599 ena = pwr_reg && wm8994->mbc_ena[mbc];
600
601 reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM);
602
603 dev_dbg(codec->dev, "MBC %d startup: %d, power: %x, DSP: %x\n",
604 mbc, start, pwr_reg, reg);
605
606 if (start && ena) {
607 /* If the DSP is already running then noop */
608 if (reg & WM8958_DSP2_ENA)
609 return;
610
611 /* Switch the clock over to the appropriate AIF */
612 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
613 WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA,
614 aif << WM8958_DSP2CLK_SRC_SHIFT |
615 WM8958_DSP2CLK_ENA);
616
617 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
618 WM8958_DSP2_ENA, WM8958_DSP2_ENA);
619
620 /* If we've got user supplied MBC settings use them */
621 if (pdata && pdata->num_mbc_cfgs) {
622 struct wm8958_mbc_cfg *cfg
623 = &pdata->mbc_cfgs[wm8994->mbc_cfg];
624
625 for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++)
626 snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1,
627 cfg->coeff_regs[i]);
628
629 for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++)
630 snd_soc_write(codec,
631 i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1,
632 cfg->cutoff_regs[i]);
633 }
634
635 /* Run the DSP */
636 snd_soc_write(codec, WM8958_DSP2_EXECCONTROL,
637 WM8958_DSP2_RUNR);
638
639 /* And we're off! */
640 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
641 WM8958_MBC_ENA | WM8958_MBC_SEL_MASK,
642 mbc << WM8958_MBC_SEL_SHIFT |
643 WM8958_MBC_ENA);
644 } else {
645 /* If the DSP is already stopped then noop */
646 if (!(reg & WM8958_DSP2_ENA))
647 return;
648
649 snd_soc_update_bits(codec, WM8958_DSP2_CONFIG,
650 WM8958_MBC_ENA, 0);
651 snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM,
652 WM8958_DSP2_ENA, 0);
653 snd_soc_update_bits(codec, WM8994_CLOCKING_1,
654 WM8958_DSP2CLK_ENA, 0);
655 }
656}
657
658static int wm8958_aif_ev(struct snd_soc_dapm_widget *w,
659 struct snd_kcontrol *kcontrol, int event)
660{
661 struct snd_soc_codec *codec = w->codec;
662 int mbc;
663
664 switch (w->shift) {
665 case 13:
666 case 12:
667 mbc = 2;
668 break;
669 case 11:
670 case 10:
671 mbc = 1;
672 break;
673 case 9:
674 case 8:
675 mbc = 0;
676 break;
677 default:
678 BUG();
679 return -EINVAL;
680 }
681
682 switch (event) {
683 case SND_SOC_DAPM_POST_PMU:
684 wm8958_mbc_apply(codec, mbc, 1);
685 break;
686 case SND_SOC_DAPM_POST_PMD:
687 wm8958_mbc_apply(codec, mbc, 0);
688 break;
689 }
690
691 return 0;
692}
693
694static int wm8958_put_mbc_enum(struct snd_kcontrol *kcontrol,
695 struct snd_ctl_elem_value *ucontrol)
696{
697 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
698 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
699 struct wm8994_pdata *pdata = wm8994->pdata;
700 int value = ucontrol->value.integer.value[0];
701 int reg;
702
703 /* Don't allow on the fly reconfiguration */
704 reg = snd_soc_read(codec, WM8994_CLOCKING_1);
705 if (reg < 0 || reg & WM8958_DSP2CLK_ENA)
706 return -EBUSY;
707
708 if (value >= pdata->num_mbc_cfgs)
709 return -EINVAL;
710
711 wm8994->mbc_cfg = value;
712
713 return 0;
714}
715
716static int wm8958_get_mbc_enum(struct snd_kcontrol *kcontrol,
717 struct snd_ctl_elem_value *ucontrol)
718{
719 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
720 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
721
722 ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg;
723
724 return 0;
725}
726
727static int wm8958_mbc_info(struct snd_kcontrol *kcontrol,
728 struct snd_ctl_elem_info *uinfo)
729{
730 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
731 uinfo->count = 1;
732 uinfo->value.integer.min = 0;
733 uinfo->value.integer.max = 1;
734 return 0;
735}
736
737static int wm8958_mbc_get(struct snd_kcontrol *kcontrol,
738 struct snd_ctl_elem_value *ucontrol)
739{
740 int mbc = kcontrol->private_value;
741 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
742 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
743
744 ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc];
745
746 return 0;
747}
748
749static int wm8958_mbc_put(struct snd_kcontrol *kcontrol,
750 struct snd_ctl_elem_value *ucontrol)
751{
752 int mbc = kcontrol->private_value;
753 int i;
754 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
755 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
756
757 if (ucontrol->value.integer.value[0] > 1)
758 return -EINVAL;
759
760 for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) {
761 if (mbc != i && wm8994->mbc_ena[i]) {
762 dev_dbg(codec->dev, "MBC %d active already\n", mbc);
763 return -EBUSY;
764 }
765 }
766
767 wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0];
768
769 wm8958_mbc_apply(codec, mbc, wm8994->mbc_ena[mbc]);
770
771 return 0;
772}
773
774#define WM8958_MBC_SWITCH(xname, xval) {\
775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
776 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\
777 .info = wm8958_mbc_info, \
778 .get = wm8958_mbc_get, .put = wm8958_mbc_put, \
779 .private_value = xval }
2089 780
2090static const struct snd_kcontrol_new wm8994_snd_controls[] = { 781static const struct snd_kcontrol_new wm8994_snd_controls[] = {
2091SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, 782SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME,
@@ -2098,10 +789,15 @@ SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME,
2098 WM8994_AIF2_ADC_RIGHT_VOLUME, 789 WM8994_AIF2_ADC_RIGHT_VOLUME,
2099 1, 119, 0, digital_tlv), 790 1, 119, 0, digital_tlv),
2100 791
792SOC_ENUM("AIF1ADCL Source", aif1adcl_src),
793SOC_ENUM("AIF1ADCR Source", aif1adcr_src),
794SOC_ENUM("AIF2ADCL Source", aif2adcl_src),
795SOC_ENUM("AIF2ADCR Source", aif2adcr_src),
796
2101SOC_ENUM("AIF1DACL Source", aif1dacl_src), 797SOC_ENUM("AIF1DACL Source", aif1dacl_src),
2102SOC_ENUM("AIF1DACR Source", aif1dacr_src), 798SOC_ENUM("AIF1DACR Source", aif1dacr_src),
2103SOC_ENUM("AIF2DACL Source", aif1dacl_src), 799SOC_ENUM("AIF2DACL Source", aif2dacl_src),
2104SOC_ENUM("AIF2DACR Source", aif1dacr_src), 800SOC_ENUM("AIF2DACR Source", aif2dacr_src),
2105 801
2106SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME, 802SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME,
2107 WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), 803 WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
@@ -2140,6 +836,18 @@ SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES,
2140SOC_ENUM("Sidetone HPF Mux", sidetone_hpf), 836SOC_ENUM("Sidetone HPF Mux", sidetone_hpf),
2141SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0), 837SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0),
2142 838
839SOC_ENUM("AIF1ADC1 HPF Mode", aif1adc1_hpf),
840SOC_DOUBLE("AIF1ADC1 HPF Switch", WM8994_AIF1_ADC1_FILTERS, 12, 11, 1, 0),
841
842SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf),
843SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0),
844
845SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf),
846SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0),
847
848SOC_ENUM("ADC OSR", adc_osr),
849SOC_ENUM("DAC OSR", dac_osr),
850
2143SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME, 851SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME,
2144 WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), 852 WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv),
2145SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME, 853SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME,
@@ -2162,15 +870,15 @@ SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION,
2162 870
2163SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2, 871SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2,
2164 10, 15, 0, wm8994_3d_tlv), 872 10, 15, 0, wm8994_3d_tlv),
2165SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, 873SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC1_FILTERS_2,
2166 8, 1, 0), 874 8, 1, 0),
2167SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2, 875SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2,
2168 10, 15, 0, wm8994_3d_tlv), 876 10, 15, 0, wm8994_3d_tlv),
2169SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, 877SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2,
2170 8, 1, 0), 878 8, 1, 0),
2171SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2, 879SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF2_DAC_FILTERS_2,
2172 10, 15, 0, wm8994_3d_tlv), 880 10, 15, 0, wm8994_3d_tlv),
2173SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, 881SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF2_DAC_FILTERS_2,
2174 8, 1, 0), 882 8, 1, 0),
2175}; 883};
2176 884
@@ -2209,6 +917,13 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0,
2209 eq_tlv), 917 eq_tlv),
2210}; 918};
2211 919
920static const struct snd_kcontrol_new wm8958_snd_controls[] = {
921SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv),
922WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0),
923WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1),
924WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2),
925};
926
2212static int clk_sys_event(struct snd_soc_dapm_widget *w, 927static int clk_sys_event(struct snd_soc_dapm_widget *w,
2213 struct snd_kcontrol *kcontrol, int event) 928 struct snd_kcontrol *kcontrol, int event)
2214{ 929{
@@ -2228,6 +943,7 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w,
2228 943
2229static void wm8994_update_class_w(struct snd_soc_codec *codec) 944static void wm8994_update_class_w(struct snd_soc_codec *codec)
2230{ 945{
946 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2231 int enable = 1; 947 int enable = 1;
2232 int source = 0; /* GCC flow analysis can't track enable */ 948 int source = 0; /* GCC flow analysis can't track enable */
2233 int reg, reg_r; 949 int reg, reg_r;
@@ -2278,11 +994,13 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec)
2278 WM8994_CP_DYN_PWR | 994 WM8994_CP_DYN_PWR |
2279 WM8994_CP_DYN_SRC_SEL_MASK, 995 WM8994_CP_DYN_SRC_SEL_MASK,
2280 source | WM8994_CP_DYN_PWR); 996 source | WM8994_CP_DYN_PWR);
997 wm8994->hubs.class_w = true;
2281 998
2282 } else { 999 } else {
2283 dev_dbg(codec->dev, "Class W disabled\n"); 1000 dev_dbg(codec->dev, "Class W disabled\n");
2284 snd_soc_update_bits(codec, WM8994_CLASS_W_1, 1001 snd_soc_update_bits(codec, WM8994_CLASS_W_1,
2285 WM8994_CP_DYN_PWR, 0); 1002 WM8994_CP_DYN_PWR, 0);
1003 wm8994->hubs.class_w = false;
2286 } 1004 }
2287} 1005}
2288 1006
@@ -2512,14 +1230,47 @@ static const struct snd_kcontrol_new aif2adc_mux =
2512 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); 1230 SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum);
2513 1231
2514static const char *aif3adc_text[] = { 1232static const char *aif3adc_text[] = {
2515 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", 1233 "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM",
2516}; 1234};
2517 1235
2518static const struct soc_enum aif3adc_enum = 1236static const struct soc_enum wm8994_aif3adc_enum =
2519 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text); 1237 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text);
2520 1238
2521static const struct snd_kcontrol_new aif3adc_mux = 1239static const struct snd_kcontrol_new wm8994_aif3adc_mux =
2522 SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum); 1240 SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum);
1241
1242static const struct soc_enum wm8958_aif3adc_enum =
1243 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text);
1244
1245static const struct snd_kcontrol_new wm8958_aif3adc_mux =
1246 SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum);
1247
1248static const char *mono_pcm_out_text[] = {
1249 "None", "AIF2ADCL", "AIF2ADCR",
1250};
1251
1252static const struct soc_enum mono_pcm_out_enum =
1253 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text);
1254
1255static const struct snd_kcontrol_new mono_pcm_out_mux =
1256 SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum);
1257
1258static const char *aif2dac_src_text[] = {
1259 "AIF2", "AIF3",
1260};
1261
1262/* Note that these two control shouldn't be simultaneously switched to AIF3 */
1263static const struct soc_enum aif2dacl_src_enum =
1264 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text);
1265
1266static const struct snd_kcontrol_new aif2dacl_src_mux =
1267 SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum);
1268
1269static const struct soc_enum aif2dacr_src_enum =
1270 SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text);
1271
1272static const struct snd_kcontrol_new aif2dacr_src_mux =
1273 SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum);
2523 1274
2524static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { 1275static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = {
2525SND_SOC_DAPM_INPUT("DMIC1DAT"), 1276SND_SOC_DAPM_INPUT("DMIC1DAT"),
@@ -2540,19 +1291,23 @@ SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture",
2540 0, WM8994_POWER_MANAGEMENT_4, 9, 0), 1291 0, WM8994_POWER_MANAGEMENT_4, 9, 0),
2541SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", 1292SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture",
2542 0, WM8994_POWER_MANAGEMENT_4, 8, 0), 1293 0, WM8994_POWER_MANAGEMENT_4, 8, 0),
2543SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0, 1294SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0,
2544 WM8994_POWER_MANAGEMENT_5, 9, 0), 1295 WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev,
2545SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0, 1296 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2546 WM8994_POWER_MANAGEMENT_5, 8, 0), 1297SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0,
1298 WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev,
1299 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2547 1300
2548SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture", 1301SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
2549 0, WM8994_POWER_MANAGEMENT_4, 11, 0), 1302 0, WM8994_POWER_MANAGEMENT_4, 11, 0),
2550SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", 1303SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
2551 0, WM8994_POWER_MANAGEMENT_4, 10, 0), 1304 0, WM8994_POWER_MANAGEMENT_4, 10, 0),
2552SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0, 1305SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0,
2553 WM8994_POWER_MANAGEMENT_5, 11, 0), 1306 WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev,
2554SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0, 1307 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2555 WM8994_POWER_MANAGEMENT_5, 10, 0), 1308SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0,
1309 WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev,
1310 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
2556 1311
2557SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0, 1312SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
2558 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)), 1313 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
@@ -2581,10 +1336,12 @@ SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0,
2581 WM8994_POWER_MANAGEMENT_4, 13, 0), 1336 WM8994_POWER_MANAGEMENT_4, 13, 0),
2582SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0, 1337SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0,
2583 WM8994_POWER_MANAGEMENT_4, 12, 0), 1338 WM8994_POWER_MANAGEMENT_4, 12, 0),
2584SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0, 1339SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0,
2585 WM8994_POWER_MANAGEMENT_5, 13, 0), 1340 WM8994_POWER_MANAGEMENT_5, 13, 0, wm8958_aif_ev,
2586SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0, 1341 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2587 WM8994_POWER_MANAGEMENT_5, 12, 0), 1342SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0,
1343 WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev,
1344 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
2588 1345
2589SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), 1346SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
2590SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), 1347SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0),
@@ -2593,7 +1350,6 @@ SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0),
2593SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), 1350SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux),
2594SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), 1351SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux),
2595SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), 1352SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux),
2596SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux),
2597 1353
2598SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), 1354SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0),
2599SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), 1355SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0),
@@ -2631,8 +1387,18 @@ SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0,
2631SND_SOC_DAPM_POST("Debug log", post_ev), 1387SND_SOC_DAPM_POST("Debug log", post_ev),
2632}; 1388};
2633 1389
2634static const struct snd_soc_dapm_route intercon[] = { 1390static const struct snd_soc_dapm_widget wm8994_specific_dapm_widgets[] = {
1391SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux),
1392};
1393
1394static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = {
1395SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux),
1396SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux),
1397SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux),
1398SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8958_aif3adc_mux),
1399};
2635 1400
1401static const struct snd_soc_dapm_route intercon[] = {
2636 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys }, 1402 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
2637 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys }, 1403 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
2638 1404
@@ -2740,9 +1506,6 @@ static const struct snd_soc_dapm_route intercon[] = {
2740 { "AIF1DAC2L", NULL, "AIF1DAC Mux" }, 1506 { "AIF1DAC2L", NULL, "AIF1DAC Mux" },
2741 { "AIF1DAC2R", NULL, "AIF1DAC Mux" }, 1507 { "AIF1DAC2R", NULL, "AIF1DAC Mux" },
2742 1508
2743 { "AIF2DACL", NULL, "AIF2DAC Mux" },
2744 { "AIF2DACR", NULL, "AIF2DAC Mux" },
2745
2746 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" }, 1509 { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" },
2747 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" }, 1510 { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" },
2748 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" }, 1511 { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" },
@@ -2815,6 +1578,26 @@ static const struct snd_soc_dapm_route intercon[] = {
2815 { "Right Headphone Mux", "DAC", "DAC1R" }, 1578 { "Right Headphone Mux", "DAC", "DAC1R" },
2816}; 1579};
2817 1580
1581static const struct snd_soc_dapm_route wm8994_intercon[] = {
1582 { "AIF2DACL", NULL, "AIF2DAC Mux" },
1583 { "AIF2DACR", NULL, "AIF2DAC Mux" },
1584};
1585
1586static const struct snd_soc_dapm_route wm8958_intercon[] = {
1587 { "AIF2DACL", NULL, "AIF2DACL Mux" },
1588 { "AIF2DACR", NULL, "AIF2DACR Mux" },
1589
1590 { "AIF2DACL Mux", "AIF2", "AIF2DAC Mux" },
1591 { "AIF2DACL Mux", "AIF3", "AIF3DACDAT" },
1592 { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" },
1593 { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" },
1594
1595 { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" },
1596 { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" },
1597
1598 { "AIF3ADC Mux", "Mono PCM", "Mono PCM Out Mux" },
1599};
1600
2818/* The size in bits of the FLL divide multiplied by 10 1601/* The size in bits of the FLL divide multiplied by 10
2819 * to allow rounding later */ 1602 * to allow rounding later */
2820#define FIXED_FLL_SIZE ((1 << 16) * 10) 1603#define FIXED_FLL_SIZE ((1 << 16) * 10)
@@ -2930,6 +1713,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src,
2930 /* Allow no source specification when stopping */ 1713 /* Allow no source specification when stopping */
2931 if (freq_out) 1714 if (freq_out)
2932 return -EINVAL; 1715 return -EINVAL;
1716 src = wm8994->fll[id].src;
2933 break; 1717 break;
2934 case WM8994_FLL_SRC_MCLK1: 1718 case WM8994_FLL_SRC_MCLK1:
2935 case WM8994_FLL_SRC_MCLK2: 1719 case WM8994_FLL_SRC_MCLK2:
@@ -3094,6 +1878,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai,
3094static int wm8994_set_bias_level(struct snd_soc_codec *codec, 1878static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3095 enum snd_soc_bias_level level) 1879 enum snd_soc_bias_level level)
3096{ 1880{
1881 struct wm8994 *control = codec->control_data;
3097 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 1882 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3098 1883
3099 switch (level) { 1884 switch (level) {
@@ -3107,16 +1892,36 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3107 break; 1892 break;
3108 1893
3109 case SND_SOC_BIAS_STANDBY: 1894 case SND_SOC_BIAS_STANDBY:
3110 if (codec->bias_level == SND_SOC_BIAS_OFF) { 1895 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
3111 /* Tweak DC servo and DSP configuration for 1896 pm_runtime_get_sync(codec->dev);
3112 * improved performance. */ 1897
3113 if (wm8994->revision < 4) { 1898 switch (control->type) {
3114 /* Tweak DC servo and DSP configuration for 1899 case WM8994:
3115 * improved performance. */ 1900 if (wm8994->revision < 4) {
3116 snd_soc_write(codec, 0x102, 0x3); 1901 /* Tweak DC servo and DSP
3117 snd_soc_write(codec, 0x56, 0x3); 1902 * configuration for improved
3118 snd_soc_write(codec, 0x817, 0); 1903 * performance. */
3119 snd_soc_write(codec, 0x102, 0); 1904 snd_soc_write(codec, 0x102, 0x3);
1905 snd_soc_write(codec, 0x56, 0x3);
1906 snd_soc_write(codec, 0x817, 0);
1907 snd_soc_write(codec, 0x102, 0);
1908 }
1909 break;
1910
1911 case WM8958:
1912 if (wm8994->revision == 0) {
1913 /* Optimise performance for rev A */
1914 snd_soc_write(codec, 0x102, 0x3);
1915 snd_soc_write(codec, 0xcb, 0x81);
1916 snd_soc_write(codec, 0x817, 0);
1917 snd_soc_write(codec, 0x102, 0);
1918
1919 snd_soc_update_bits(codec,
1920 WM8958_CHARGE_PUMP_2,
1921 WM8958_CP_DISCH,
1922 WM8958_CP_DISCH);
1923 }
1924 break;
3120 } 1925 }
3121 1926
3122 /* Discharge LINEOUT1 & 2 */ 1927 /* Discharge LINEOUT1 & 2 */
@@ -3151,7 +1956,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3151 break; 1956 break;
3152 1957
3153 case SND_SOC_BIAS_OFF: 1958 case SND_SOC_BIAS_OFF:
3154 if (codec->bias_level == SND_SOC_BIAS_STANDBY) { 1959 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
3155 /* Switch over to startup biases */ 1960 /* Switch over to startup biases */
3156 snd_soc_update_bits(codec, WM8994_ANTIPOP_2, 1961 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3157 WM8994_BIAS_SRC | 1962 WM8994_BIAS_SRC |
@@ -3183,16 +1988,19 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
3183 WM8994_STARTUP_BIAS_ENA | 1988 WM8994_STARTUP_BIAS_ENA |
3184 WM8994_VMID_BUF_ENA | 1989 WM8994_VMID_BUF_ENA |
3185 WM8994_VMID_RAMP_MASK, 0); 1990 WM8994_VMID_RAMP_MASK, 0);
1991
1992 pm_runtime_put(codec->dev);
3186 } 1993 }
3187 break; 1994 break;
3188 } 1995 }
3189 codec->bias_level = level; 1996 codec->dapm.bias_level = level;
3190 return 0; 1997 return 0;
3191} 1998}
3192 1999
3193static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) 2000static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3194{ 2001{
3195 struct snd_soc_codec *codec = dai->codec; 2002 struct snd_soc_codec *codec = dai->codec;
2003 struct wm8994 *control = codec->control_data;
3196 int ms_reg; 2004 int ms_reg;
3197 int aif1_reg; 2005 int aif1_reg;
3198 int ms = 0; 2006 int ms = 0;
@@ -3277,6 +2085,13 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
3277 return -EINVAL; 2085 return -EINVAL;
3278 } 2086 }
3279 2087
2088 /* The AIF2 format configuration needs to be mirrored to AIF3
2089 * on WM8958 if it's in use so just do it all the time. */
2090 if (control->type == WM8958 && dai->id == 2)
2091 snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1,
2092 WM8994_AIF1_LRCLK_INV |
2093 WM8958_AIF3_FMT_MASK, aif1);
2094
3280 snd_soc_update_bits(codec, aif1_reg, 2095 snd_soc_update_bits(codec, aif1_reg,
3281 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV | 2096 WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV |
3282 WM8994_AIF1_FMT_MASK, 2097 WM8994_AIF1_FMT_MASK,
@@ -3317,12 +2132,15 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3317 struct snd_soc_dai *dai) 2132 struct snd_soc_dai *dai)
3318{ 2133{
3319 struct snd_soc_codec *codec = dai->codec; 2134 struct snd_soc_codec *codec = dai->codec;
2135 struct wm8994 *control = codec->control_data;
3320 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2136 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3321 int aif1_reg; 2137 int aif1_reg;
2138 int aif2_reg;
3322 int bclk_reg; 2139 int bclk_reg;
3323 int lrclk_reg; 2140 int lrclk_reg;
3324 int rate_reg; 2141 int rate_reg;
3325 int aif1 = 0; 2142 int aif1 = 0;
2143 int aif2 = 0;
3326 int bclk = 0; 2144 int bclk = 0;
3327 int lrclk = 0; 2145 int lrclk = 0;
3328 int rate_val = 0; 2146 int rate_val = 0;
@@ -3333,6 +2151,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3333 switch (dai->id) { 2151 switch (dai->id) {
3334 case 1: 2152 case 1:
3335 aif1_reg = WM8994_AIF1_CONTROL_1; 2153 aif1_reg = WM8994_AIF1_CONTROL_1;
2154 aif2_reg = WM8994_AIF1_CONTROL_2;
3336 bclk_reg = WM8994_AIF1_BCLK; 2155 bclk_reg = WM8994_AIF1_BCLK;
3337 rate_reg = WM8994_AIF1_RATE; 2156 rate_reg = WM8994_AIF1_RATE;
3338 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || 2157 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
@@ -3345,6 +2164,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3345 break; 2164 break;
3346 case 2: 2165 case 2:
3347 aif1_reg = WM8994_AIF2_CONTROL_1; 2166 aif1_reg = WM8994_AIF2_CONTROL_1;
2167 aif2_reg = WM8994_AIF2_CONTROL_2;
3348 bclk_reg = WM8994_AIF2_BCLK; 2168 bclk_reg = WM8994_AIF2_BCLK;
3349 rate_reg = WM8994_AIF2_RATE; 2169 rate_reg = WM8994_AIF2_RATE;
3350 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || 2170 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||
@@ -3355,6 +2175,14 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3355 dev_dbg(codec->dev, "AIF2 using split LRCLK\n"); 2175 dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
3356 } 2176 }
3357 break; 2177 break;
2178 case 3:
2179 switch (control->type) {
2180 case WM8958:
2181 aif1_reg = WM8958_AIF3_CONTROL_1;
2182 break;
2183 default:
2184 return 0;
2185 }
3358 default: 2186 default:
3359 return -EINVAL; 2187 return -EINVAL;
3360 } 2188 }
@@ -3392,6 +2220,10 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3392 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", 2220 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
3393 dai->id, wm8994->aifclk[id], bclk_rate); 2221 dai->id, wm8994->aifclk[id], bclk_rate);
3394 2222
2223 if (params_channels(params) == 1 &&
2224 (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18)
2225 aif2 |= WM8994_AIF1_MONO;
2226
3395 if (wm8994->aifclk[id] == 0) { 2227 if (wm8994->aifclk[id] == 0) {
3396 dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id); 2228 dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id);
3397 return -EINVAL; 2229 return -EINVAL;
@@ -3435,6 +2267,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3435 lrclk, bclk_rate / lrclk); 2267 lrclk, bclk_rate / lrclk);
3436 2268
3437 snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); 2269 snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
2270 snd_soc_update_bits(codec, aif2_reg, WM8994_AIF1_MONO, aif2);
3438 snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk); 2271 snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk);
3439 snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK, 2272 snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK,
3440 lrclk); 2273 lrclk);
@@ -3458,6 +2291,47 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream,
3458 return 0; 2291 return 0;
3459} 2292}
3460 2293
2294static int wm8994_aif3_hw_params(struct snd_pcm_substream *substream,
2295 struct snd_pcm_hw_params *params,
2296 struct snd_soc_dai *dai)
2297{
2298 struct snd_soc_codec *codec = dai->codec;
2299 struct wm8994 *control = codec->control_data;
2300 int aif1_reg;
2301 int aif1 = 0;
2302
2303 switch (dai->id) {
2304 case 3:
2305 switch (control->type) {
2306 case WM8958:
2307 aif1_reg = WM8958_AIF3_CONTROL_1;
2308 break;
2309 default:
2310 return 0;
2311 }
2312 default:
2313 return 0;
2314 }
2315
2316 switch (params_format(params)) {
2317 case SNDRV_PCM_FORMAT_S16_LE:
2318 break;
2319 case SNDRV_PCM_FORMAT_S20_3LE:
2320 aif1 |= 0x20;
2321 break;
2322 case SNDRV_PCM_FORMAT_S24_LE:
2323 aif1 |= 0x40;
2324 break;
2325 case SNDRV_PCM_FORMAT_S32_LE:
2326 aif1 |= 0x60;
2327 break;
2328 default:
2329 return -EINVAL;
2330 }
2331
2332 return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1);
2333}
2334
3461static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) 2335static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute)
3462{ 2336{
3463 struct snd_soc_codec *codec = codec_dai->codec; 2337 struct snd_soc_codec *codec = codec_dai->codec;
@@ -3539,6 +2413,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = {
3539}; 2413};
3540 2414
3541static struct snd_soc_dai_ops wm8994_aif3_dai_ops = { 2415static struct snd_soc_dai_ops wm8994_aif3_dai_ops = {
2416 .hw_params = wm8994_aif3_hw_params,
3542 .set_tristate = wm8994_set_tristate, 2417 .set_tristate = wm8994_set_tristate,
3543}; 2418};
3544 2419
@@ -3548,14 +2423,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
3548 .id = 1, 2423 .id = 1,
3549 .playback = { 2424 .playback = {
3550 .stream_name = "AIF1 Playback", 2425 .stream_name = "AIF1 Playback",
3551 .channels_min = 2, 2426 .channels_min = 1,
3552 .channels_max = 2, 2427 .channels_max = 2,
3553 .rates = WM8994_RATES, 2428 .rates = WM8994_RATES,
3554 .formats = WM8994_FORMATS, 2429 .formats = WM8994_FORMATS,
3555 }, 2430 },
3556 .capture = { 2431 .capture = {
3557 .stream_name = "AIF1 Capture", 2432 .stream_name = "AIF1 Capture",
3558 .channels_min = 2, 2433 .channels_min = 1,
3559 .channels_max = 2, 2434 .channels_max = 2,
3560 .rates = WM8994_RATES, 2435 .rates = WM8994_RATES,
3561 .formats = WM8994_FORMATS, 2436 .formats = WM8994_FORMATS,
@@ -3567,14 +2442,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
3567 .id = 2, 2442 .id = 2,
3568 .playback = { 2443 .playback = {
3569 .stream_name = "AIF2 Playback", 2444 .stream_name = "AIF2 Playback",
3570 .channels_min = 2, 2445 .channels_min = 1,
3571 .channels_max = 2, 2446 .channels_max = 2,
3572 .rates = WM8994_RATES, 2447 .rates = WM8994_RATES,
3573 .formats = WM8994_FORMATS, 2448 .formats = WM8994_FORMATS,
3574 }, 2449 },
3575 .capture = { 2450 .capture = {
3576 .stream_name = "AIF2 Capture", 2451 .stream_name = "AIF2 Capture",
3577 .channels_min = 2, 2452 .channels_min = 1,
3578 .channels_max = 2, 2453 .channels_max = 2,
3579 .rates = WM8994_RATES, 2454 .rates = WM8994_RATES,
3580 .formats = WM8994_FORMATS, 2455 .formats = WM8994_FORMATS,
@@ -3586,14 +2461,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
3586 .id = 3, 2461 .id = 3,
3587 .playback = { 2462 .playback = {
3588 .stream_name = "AIF3 Playback", 2463 .stream_name = "AIF3 Playback",
3589 .channels_min = 2, 2464 .channels_min = 1,
3590 .channels_max = 2, 2465 .channels_max = 2,
3591 .rates = WM8994_RATES, 2466 .rates = WM8994_RATES,
3592 .formats = WM8994_FORMATS, 2467 .formats = WM8994_FORMATS,
3593 }, 2468 },
3594 .capture = { 2469 .capture = {
3595 .stream_name = "AIF3 Capture", 2470 .stream_name = "AIF3 Capture",
3596 .channels_min = 2, 2471 .channels_min = 1,
3597 .channels_max = 2, 2472 .channels_max = 2,
3598 .rates = WM8994_RATES, 2473 .rates = WM8994_RATES,
3599 .formats = WM8994_FORMATS, 2474 .formats = WM8994_FORMATS,
@@ -3625,26 +2500,12 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state)
3625static int wm8994_resume(struct snd_soc_codec *codec) 2500static int wm8994_resume(struct snd_soc_codec *codec)
3626{ 2501{
3627 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2502 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3628 u16 *reg_cache = codec->reg_cache;
3629 int i, ret; 2503 int i, ret;
3630 2504
3631 /* Restore the registers */ 2505 /* Restore the registers */
3632 for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) { 2506 ret = snd_soc_cache_sync(codec);
3633 switch (i) { 2507 if (ret != 0)
3634 case WM8994_LDO_1: 2508 dev_err(codec->dev, "Failed to sync cache: %d\n", ret);
3635 case WM8994_LDO_2:
3636 case WM8994_SOFTWARE_RESET:
3637 /* Handled by other MFD drivers */
3638 continue;
3639 default:
3640 break;
3641 }
3642
3643 if (!access_masks[i].writable)
3644 continue;
3645
3646 wm8994_reg_write(codec->control_data, i, reg_cache[i]);
3647 }
3648 2509
3649 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 2510 wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
3650 2511
@@ -3794,6 +2655,34 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994)
3794 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", 2655 dev_dbg(codec->dev, "%d ReTune Mobile configurations\n",
3795 pdata->num_retune_mobile_cfgs); 2656 pdata->num_retune_mobile_cfgs);
3796 2657
2658 if (pdata->num_mbc_cfgs) {
2659 struct snd_kcontrol_new control[] = {
2660 SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum,
2661 wm8958_get_mbc_enum, wm8958_put_mbc_enum),
2662 };
2663
2664 /* We need an array of texts for the enum API */
2665 wm8994->mbc_texts = kmalloc(sizeof(char *)
2666 * pdata->num_mbc_cfgs, GFP_KERNEL);
2667 if (!wm8994->mbc_texts) {
2668 dev_err(wm8994->codec->dev,
2669 "Failed to allocate %d MBC config texts\n",
2670 pdata->num_mbc_cfgs);
2671 return;
2672 }
2673
2674 for (i = 0; i < pdata->num_mbc_cfgs; i++)
2675 wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name;
2676
2677 wm8994->mbc_enum.max = pdata->num_mbc_cfgs;
2678 wm8994->mbc_enum.texts = wm8994->mbc_texts;
2679
2680 ret = snd_soc_add_controls(wm8994->codec, control, 1);
2681 if (ret != 0)
2682 dev_err(wm8994->codec->dev,
2683 "Failed to add MBC mode controls: %d\n", ret);
2684 }
2685
3797 if (pdata->num_retune_mobile_cfgs) 2686 if (pdata->num_retune_mobile_cfgs)
3798 wm8994_handle_retune_mobile_pdata(wm8994); 2687 wm8994_handle_retune_mobile_pdata(wm8994);
3799 else 2688 else
@@ -3823,8 +2712,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
3823{ 2712{
3824 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2713 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3825 struct wm8994_micdet *micdet; 2714 struct wm8994_micdet *micdet;
2715 struct wm8994 *control = codec->control_data;
3826 int reg; 2716 int reg;
3827 2717
2718 if (control->type != WM8994)
2719 return -EINVAL;
2720
3828 switch (micbias) { 2721 switch (micbias) {
3829 case 1: 2722 case 1:
3830 micdet = &wm8994->micdet[0]; 2723 micdet = &wm8994->micdet[0];
@@ -3863,6 +2756,10 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
3863 int reg; 2756 int reg;
3864 int report; 2757 int report;
3865 2758
2759#ifndef CONFIG_SND_SOC_WM8994_MODULE
2760 trace_snd_soc_jack_irq(dev_name(codec->dev));
2761#endif
2762
3866 reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2); 2763 reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2);
3867 if (reg < 0) { 2764 if (reg < 0) {
3868 dev_err(codec->dev, "Failed to read microphone status: %d\n", 2765 dev_err(codec->dev, "Failed to read microphone status: %d\n",
@@ -3891,77 +2788,251 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data)
3891 return IRQ_HANDLED; 2788 return IRQ_HANDLED;
3892} 2789}
3893 2790
2791/* Default microphone detection handler for WM8958 - the user can
2792 * override this if they wish.
2793 */
2794static void wm8958_default_micdet(u16 status, void *data)
2795{
2796 struct snd_soc_codec *codec = data;
2797 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2798 int report = 0;
2799
2800 /* If nothing present then clear our statuses */
2801 if (!(status & WM8958_MICD_STS)) {
2802 wm8994->jack_is_video = false;
2803 wm8994->jack_is_mic = false;
2804 goto done;
2805 }
2806
2807 /* Assume anything over 475 ohms is a microphone and remember
2808 * that we've seen one (since buttons override it) */
2809 if (status & 0x600)
2810 wm8994->jack_is_mic = true;
2811 if (wm8994->jack_is_mic)
2812 report |= SND_JACK_MICROPHONE;
2813
2814 /* Video has an impedence of approximately 75 ohms; assume
2815 * this isn't used as a button and remember it since buttons
2816 * override it. */
2817 if (status & 0x40)
2818 wm8994->jack_is_video = true;
2819 if (wm8994->jack_is_video)
2820 report |= SND_JACK_VIDEOOUT;
2821
2822 /* Everything else is buttons; just assign slots */
2823 if (status & 0x4)
2824 report |= SND_JACK_BTN_0;
2825 if (status & 0x8)
2826 report |= SND_JACK_BTN_1;
2827 if (status & 0x10)
2828 report |= SND_JACK_BTN_2;
2829 if (status & 0x20)
2830 report |= SND_JACK_BTN_3;
2831 if (status & 0x80)
2832 report |= SND_JACK_BTN_4;
2833 if (status & 0x100)
2834 report |= SND_JACK_BTN_5;
2835
2836done:
2837 snd_soc_jack_report(wm8994->micdet[0].jack,
2838 SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 |
2839 SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5 |
2840 SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT,
2841 report);
2842}
2843
2844/**
2845 * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ
2846 *
2847 * @codec: WM8958 codec
2848 * @jack: jack to report detection events on
2849 *
2850 * Enable microphone detection functionality for the WM8958. By
2851 * default simple detection which supports the detection of up to 6
2852 * buttons plus video and microphone functionality is supported.
2853 *
2854 * The WM8958 has an advanced jack detection facility which is able to
2855 * support complex accessory detection, especially when used in
2856 * conjunction with external circuitry. In order to provide maximum
2857 * flexiblity a callback is provided which allows a completely custom
2858 * detection algorithm.
2859 */
2860int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
2861 wm8958_micdet_cb cb, void *cb_data)
2862{
2863 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2864 struct wm8994 *control = codec->control_data;
2865
2866 if (control->type != WM8958)
2867 return -EINVAL;
2868
2869 if (jack) {
2870 if (!cb) {
2871 dev_dbg(codec->dev, "Using default micdet callback\n");
2872 cb = wm8958_default_micdet;
2873 cb_data = codec;
2874 }
2875
2876 wm8994->micdet[0].jack = jack;
2877 wm8994->jack_cb = cb;
2878 wm8994->jack_cb_data = cb_data;
2879
2880 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2881 WM8958_MICD_ENA, WM8958_MICD_ENA);
2882 } else {
2883 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2884 WM8958_MICD_ENA, 0);
2885 }
2886
2887 return 0;
2888}
2889EXPORT_SYMBOL_GPL(wm8958_mic_detect);
2890
2891static irqreturn_t wm8958_mic_irq(int irq, void *data)
2892{
2893 struct wm8994_priv *wm8994 = data;
2894 struct snd_soc_codec *codec = wm8994->codec;
2895 int reg;
2896
2897 reg = snd_soc_read(codec, WM8958_MIC_DETECT_3);
2898 if (reg < 0) {
2899 dev_err(codec->dev, "Failed to read mic detect status: %d\n",
2900 reg);
2901 return IRQ_NONE;
2902 }
2903
2904 if (!(reg & WM8958_MICD_VALID)) {
2905 dev_dbg(codec->dev, "Mic detect data not valid\n");
2906 goto out;
2907 }
2908
2909#ifndef CONFIG_SND_SOC_WM8994_MODULE
2910 trace_snd_soc_jack_irq(dev_name(codec->dev));
2911#endif
2912
2913 if (wm8994->jack_cb)
2914 wm8994->jack_cb(reg, wm8994->jack_cb_data);
2915 else
2916 dev_warn(codec->dev, "Accessory detection with no callback\n");
2917
2918out:
2919 return IRQ_HANDLED;
2920}
2921
3894static int wm8994_codec_probe(struct snd_soc_codec *codec) 2922static int wm8994_codec_probe(struct snd_soc_codec *codec)
3895{ 2923{
2924 struct wm8994 *control;
3896 struct wm8994_priv *wm8994; 2925 struct wm8994_priv *wm8994;
2926 struct snd_soc_dapm_context *dapm = &codec->dapm;
3897 int ret, i; 2927 int ret, i;
3898 2928
3899 codec->control_data = dev_get_drvdata(codec->dev->parent); 2929 codec->control_data = dev_get_drvdata(codec->dev->parent);
2930 control = codec->control_data;
3900 2931
3901 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); 2932 wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL);
3902 if (wm8994 == NULL) 2933 if (wm8994 == NULL)
3903 return -ENOMEM; 2934 return -ENOMEM;
3904 snd_soc_codec_set_drvdata(codec, wm8994); 2935 snd_soc_codec_set_drvdata(codec, wm8994);
3905 2936
3906 codec->reg_cache = &wm8994->reg_cache;
3907
3908 wm8994->pdata = dev_get_platdata(codec->dev->parent); 2937 wm8994->pdata = dev_get_platdata(codec->dev->parent);
3909 wm8994->codec = codec; 2938 wm8994->codec = codec;
3910 2939
3911 /* Fill the cache with physical values we inherited; don't reset */ 2940 pm_runtime_enable(codec->dev);
3912 ret = wm8994_bulk_read(codec->control_data, 0, 2941 pm_runtime_resume(codec->dev);
3913 ARRAY_SIZE(wm8994->reg_cache) - 1,
3914 codec->reg_cache);
3915 if (ret < 0) {
3916 dev_err(codec->dev, "Failed to fill register cache: %d\n",
3917 ret);
3918 goto err;
3919 }
3920 2942
3921 /* Clear the cached values for unreadable/volatile registers to 2943 /* Read our current status back from the chip - we don't want to
3922 * avoid potential confusion. 2944 * reset as this may interfere with the GPIO or LDO operation. */
3923 */ 2945 for (i = 0; i < WM8994_CACHE_SIZE; i++) {
3924 for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++) 2946 if (!wm8994_readable(i) || wm8994_volatile(i))
3925 if (wm8994_volatile(i) || !wm8994_readable(i)) 2947 continue;
3926 wm8994->reg_cache[i] = 0; 2948
2949 ret = wm8994_reg_read(codec->control_data, i);
2950 if (ret <= 0)
2951 continue;
2952
2953 ret = snd_soc_cache_write(codec, i, ret);
2954 if (ret != 0) {
2955 dev_err(codec->dev,
2956 "Failed to initialise cache for 0x%x: %d\n",
2957 i, ret);
2958 goto err;
2959 }
2960 }
3927 2961
3928 /* Set revision-specific configuration */ 2962 /* Set revision-specific configuration */
3929 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); 2963 wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION);
3930 switch (wm8994->revision) { 2964 switch (control->type) {
3931 case 2: 2965 case WM8994:
3932 case 3: 2966 switch (wm8994->revision) {
3933 wm8994->hubs.dcs_codes = -5; 2967 case 2:
3934 wm8994->hubs.hp_startup_mode = 1; 2968 case 3:
2969 wm8994->hubs.dcs_codes = -5;
2970 wm8994->hubs.hp_startup_mode = 1;
2971 wm8994->hubs.dcs_readback_mode = 1;
2972 break;
2973 default:
2974 wm8994->hubs.dcs_readback_mode = 1;
2975 break;
2976 }
2977
2978 case WM8958:
3935 wm8994->hubs.dcs_readback_mode = 1; 2979 wm8994->hubs.dcs_readback_mode = 1;
3936 break; 2980 break;
2981
3937 default: 2982 default:
3938 wm8994->hubs.dcs_readback_mode = 1;
3939 break; 2983 break;
3940 } 2984 }
3941 2985
3942 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET, 2986 switch (control->type) {
3943 wm8994_mic_irq, "Mic 1 detect", wm8994); 2987 case WM8994:
3944 if (ret != 0) 2988 ret = wm8994_request_irq(codec->control_data,
3945 dev_warn(codec->dev, 2989 WM8994_IRQ_MIC1_DET,
3946 "Failed to request Mic1 detect IRQ: %d\n", ret); 2990 wm8994_mic_irq, "Mic 1 detect",
3947 2991 wm8994);
3948 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, 2992 if (ret != 0)
3949 wm8994_mic_irq, "Mic 1 short", wm8994); 2993 dev_warn(codec->dev,
3950 if (ret != 0) 2994 "Failed to request Mic1 detect IRQ: %d\n",
3951 dev_warn(codec->dev, 2995 ret);
3952 "Failed to request Mic1 short IRQ: %d\n", ret); 2996
3953 2997 ret = wm8994_request_irq(codec->control_data,
3954 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET, 2998 WM8994_IRQ_MIC1_SHRT,
3955 wm8994_mic_irq, "Mic 2 detect", wm8994); 2999 wm8994_mic_irq, "Mic 1 short",
3956 if (ret != 0) 3000 wm8994);
3957 dev_warn(codec->dev, 3001 if (ret != 0)
3958 "Failed to request Mic2 detect IRQ: %d\n", ret); 3002 dev_warn(codec->dev,
3003 "Failed to request Mic1 short IRQ: %d\n",
3004 ret);
3005
3006 ret = wm8994_request_irq(codec->control_data,
3007 WM8994_IRQ_MIC2_DET,
3008 wm8994_mic_irq, "Mic 2 detect",
3009 wm8994);
3010 if (ret != 0)
3011 dev_warn(codec->dev,
3012 "Failed to request Mic2 detect IRQ: %d\n",
3013 ret);
3014
3015 ret = wm8994_request_irq(codec->control_data,
3016 WM8994_IRQ_MIC2_SHRT,
3017 wm8994_mic_irq, "Mic 2 short",
3018 wm8994);
3019 if (ret != 0)
3020 dev_warn(codec->dev,
3021 "Failed to request Mic2 short IRQ: %d\n",
3022 ret);
3023 break;
3959 3024
3960 ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, 3025 case WM8958:
3961 wm8994_mic_irq, "Mic 2 short", wm8994); 3026 ret = wm8994_request_irq(codec->control_data,
3962 if (ret != 0) 3027 WM8994_IRQ_MIC1_DET,
3963 dev_warn(codec->dev, 3028 wm8958_mic_irq, "Mic detect",
3964 "Failed to request Mic2 short IRQ: %d\n", ret); 3029 wm8994);
3030 if (ret != 0)
3031 dev_warn(codec->dev,
3032 "Failed to request Mic detect IRQ: %d\n",
3033 ret);
3034 break;
3035 }
3965 3036
3966 /* Remember if AIFnLRCLK is configured as a GPIO. This should be 3037 /* Remember if AIFnLRCLK is configured as a GPIO. This should be
3967 * configured on init - if a system wants to do this dynamically 3038 * configured on init - if a system wants to do this dynamically
@@ -4034,10 +3105,36 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
4034 wm_hubs_add_analogue_controls(codec); 3105 wm_hubs_add_analogue_controls(codec);
4035 snd_soc_add_controls(codec, wm8994_snd_controls, 3106 snd_soc_add_controls(codec, wm8994_snd_controls,
4036 ARRAY_SIZE(wm8994_snd_controls)); 3107 ARRAY_SIZE(wm8994_snd_controls));
4037 snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets, 3108 snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets,
4038 ARRAY_SIZE(wm8994_dapm_widgets)); 3109 ARRAY_SIZE(wm8994_dapm_widgets));
3110
3111 switch (control->type) {
3112 case WM8994:
3113 snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets,
3114 ARRAY_SIZE(wm8994_specific_dapm_widgets));
3115 break;
3116 case WM8958:
3117 snd_soc_add_controls(codec, wm8958_snd_controls,
3118 ARRAY_SIZE(wm8958_snd_controls));
3119 snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets,
3120 ARRAY_SIZE(wm8958_dapm_widgets));
3121 break;
3122 }
3123
3124
4039 wm_hubs_add_analogue_routes(codec, 0, 0); 3125 wm_hubs_add_analogue_routes(codec, 0, 0);
4040 snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); 3126 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
3127
3128 switch (control->type) {
3129 case WM8994:
3130 snd_soc_dapm_add_routes(dapm, wm8994_intercon,
3131 ARRAY_SIZE(wm8994_intercon));
3132 break;
3133 case WM8958:
3134 snd_soc_dapm_add_routes(dapm, wm8958_intercon,
3135 ARRAY_SIZE(wm8958_intercon));
3136 break;
3137 }
4041 3138
4042 return 0; 3139 return 0;
4043 3140
@@ -4054,13 +3151,29 @@ err:
4054static int wm8994_codec_remove(struct snd_soc_codec *codec) 3151static int wm8994_codec_remove(struct snd_soc_codec *codec)
4055{ 3152{
4056 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 3153 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
3154 struct wm8994 *control = codec->control_data;
4057 3155
4058 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); 3156 wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF);
4059 3157
4060 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); 3158 pm_runtime_disable(codec->dev);
4061 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); 3159
4062 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); 3160 switch (control->type) {
4063 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); 3161 case WM8994:
3162 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT,
3163 wm8994);
3164 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET,
3165 wm8994);
3166 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT,
3167 wm8994);
3168 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
3169 wm8994);
3170 break;
3171
3172 case WM8958:
3173 wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
3174 wm8994);
3175 break;
3176 }
4064 kfree(wm8994->retune_mobile_texts); 3177 kfree(wm8994->retune_mobile_texts);
4065 kfree(wm8994->drc_texts); 3178 kfree(wm8994->drc_texts);
4066 kfree(wm8994); 3179 kfree(wm8994);
@@ -4073,11 +3186,16 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8994 = {
4073 .remove = wm8994_codec_remove, 3186 .remove = wm8994_codec_remove,
4074 .suspend = wm8994_suspend, 3187 .suspend = wm8994_suspend,
4075 .resume = wm8994_resume, 3188 .resume = wm8994_resume,
4076 .read = wm8994_read, 3189 .read = wm8994_read,
4077 .write = wm8994_write, 3190 .write = wm8994_write,
4078 .readable_register = wm8994_readable, 3191 .readable_register = wm8994_readable,
4079 .volatile_register = wm8994_volatile, 3192 .volatile_register = wm8994_volatile,
4080 .set_bias_level = wm8994_set_bias_level, 3193 .set_bias_level = wm8994_set_bias_level,
3194
3195 .reg_cache_size = WM8994_CACHE_SIZE,
3196 .reg_cache_default = wm8994_reg_defaults,
3197 .reg_word_size = 2,
3198 .compress_type = SND_SOC_RBTREE_COMPRESSION,
4081}; 3199};
4082 3200
4083static int __devinit wm8994_probe(struct platform_device *pdev) 3201static int __devinit wm8994_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h
index d8dce260c430..0c355bfc88f1 100644
--- a/sound/soc/codecs/wm8994.h
+++ b/sound/soc/codecs/wm8994.h
@@ -28,7 +28,21 @@
28#define WM8994_FLL_SRC_LRCLK 3 28#define WM8994_FLL_SRC_LRCLK 3
29#define WM8994_FLL_SRC_BCLK 4 29#define WM8994_FLL_SRC_BCLK 4
30 30
31typedef void (*wm8958_micdet_cb)(u16 status, void *data);
32
31int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, 33int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
32 int micbias, int det, int shrt); 34 int micbias, int det, int shrt);
35int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack,
36 wm8958_micdet_cb cb, void *cb_data);
37
38#define WM8994_CACHE_SIZE 1570
39
40struct wm8994_access_mask {
41 unsigned short readable; /* Mask of readable bits */
42 unsigned short writable; /* Mask of writable bits */
43};
44
45extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE];
46extern const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE];
33 47
34#endif 48#endif
diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c
new file mode 100644
index 000000000000..6045cbde492b
--- /dev/null
+++ b/sound/soc/codecs/wm8995.c
@@ -0,0 +1,1818 @@
1/*
2 * wm8995.c -- WM8995 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 *
8 * Based on wm8994.c and wm_hubs.c by Mark Brown
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/moduleparam.h>
17#include <linux/init.h>
18#include <linux/delay.h>
19#include <linux/pm.h>
20#include <linux/i2c.h>
21#include <linux/spi/spi.h>
22#include <linux/slab.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30
31#include "wm8995.h"
32
33static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] = {
34 [0] = 0x8995, [5] = 0x0100, [16] = 0x000b, [17] = 0x000b,
35 [24] = 0x02c0, [25] = 0x02c0, [26] = 0x02c0, [27] = 0x02c0,
36 [28] = 0x000f, [32] = 0x0005, [33] = 0x0005, [40] = 0x0003,
37 [41] = 0x0013, [48] = 0x0004, [56] = 0x09f8, [64] = 0x1f25,
38 [69] = 0x0004, [82] = 0xaaaa, [84] = 0x2a2a, [146] = 0x0060,
39 [256] = 0x0002, [257] = 0x8004, [520] = 0x0010, [528] = 0x0083,
40 [529] = 0x0083, [548] = 0x0c80, [580] = 0x0c80, [768] = 0x4050,
41 [769] = 0x4000, [771] = 0x0040, [772] = 0x0040, [773] = 0x0040,
42 [774] = 0x0004, [775] = 0x0100, [784] = 0x4050, [785] = 0x4000,
43 [787] = 0x0040, [788] = 0x0040, [789] = 0x0040, [1024] = 0x00c0,
44 [1025] = 0x00c0, [1026] = 0x00c0, [1027] = 0x00c0, [1028] = 0x00c0,
45 [1029] = 0x00c0, [1030] = 0x00c0, [1031] = 0x00c0, [1056] = 0x0200,
46 [1057] = 0x0010, [1058] = 0x0200, [1059] = 0x0010, [1088] = 0x0098,
47 [1089] = 0x0845, [1104] = 0x0098, [1105] = 0x0845, [1152] = 0x6318,
48 [1153] = 0x6300, [1154] = 0x0fca, [1155] = 0x0400, [1156] = 0x00d8,
49 [1157] = 0x1eb5, [1158] = 0xf145, [1159] = 0x0b75, [1160] = 0x01c5,
50 [1161] = 0x1c58, [1162] = 0xf373, [1163] = 0x0a54, [1164] = 0x0558,
51 [1165] = 0x168e, [1166] = 0xf829, [1167] = 0x07ad, [1168] = 0x1103,
52 [1169] = 0x0564, [1170] = 0x0559, [1171] = 0x4000, [1184] = 0x6318,
53 [1185] = 0x6300, [1186] = 0x0fca, [1187] = 0x0400, [1188] = 0x00d8,
54 [1189] = 0x1eb5, [1190] = 0xf145, [1191] = 0x0b75, [1192] = 0x01c5,
55 [1193] = 0x1c58, [1194] = 0xf373, [1195] = 0x0a54, [1196] = 0x0558,
56 [1197] = 0x168e, [1198] = 0xf829, [1199] = 0x07ad, [1200] = 0x1103,
57 [1201] = 0x0564, [1202] = 0x0559, [1203] = 0x4000, [1280] = 0x00c0,
58 [1281] = 0x00c0, [1282] = 0x00c0, [1283] = 0x00c0, [1312] = 0x0200,
59 [1313] = 0x0010, [1344] = 0x0098, [1345] = 0x0845, [1408] = 0x6318,
60 [1409] = 0x6300, [1410] = 0x0fca, [1411] = 0x0400, [1412] = 0x00d8,
61 [1413] = 0x1eb5, [1414] = 0xf145, [1415] = 0x0b75, [1416] = 0x01c5,
62 [1417] = 0x1c58, [1418] = 0xf373, [1419] = 0x0a54, [1420] = 0x0558,
63 [1421] = 0x168e, [1422] = 0xf829, [1423] = 0x07ad, [1424] = 0x1103,
64 [1425] = 0x0564, [1426] = 0x0559, [1427] = 0x4000, [1568] = 0x0002,
65 [1792] = 0xa100, [1793] = 0xa101, [1794] = 0xa101, [1795] = 0xa101,
66 [1796] = 0xa101, [1797] = 0xa101, [1798] = 0xa101, [1799] = 0xa101,
67 [1800] = 0xa101, [1801] = 0xa101, [1802] = 0xa101, [1803] = 0xa101,
68 [1804] = 0xa101, [1805] = 0xa101, [1825] = 0x0055, [1848] = 0x3fff,
69 [1849] = 0x1fff, [2049] = 0x0001, [2050] = 0x0069, [2056] = 0x0002,
70 [2057] = 0x0003, [2058] = 0x0069, [12288] = 0x0001, [12289] = 0x0001,
71 [12291] = 0x0006, [12292] = 0x0040, [12293] = 0x0001, [12294] = 0x000f,
72 [12295] = 0x0006, [12296] = 0x0001, [12297] = 0x0003, [12298] = 0x0104,
73 [12300] = 0x0060, [12301] = 0x0011, [12302] = 0x0401, [12304] = 0x0050,
74 [12305] = 0x0003, [12306] = 0x0100, [12308] = 0x0051, [12309] = 0x0003,
75 [12310] = 0x0104, [12311] = 0x000a, [12312] = 0x0060, [12313] = 0x003b,
76 [12314] = 0x0502, [12315] = 0x0100, [12316] = 0x2fff, [12320] = 0x2fff,
77 [12324] = 0x2fff, [12328] = 0x2fff, [12332] = 0x2fff, [12336] = 0x2fff,
78 [12340] = 0x2fff, [12344] = 0x2fff, [12348] = 0x2fff, [12352] = 0x0001,
79 [12353] = 0x0001, [12355] = 0x0006, [12356] = 0x0040, [12357] = 0x0001,
80 [12358] = 0x000f, [12359] = 0x0006, [12360] = 0x0001, [12361] = 0x0003,
81 [12362] = 0x0104, [12364] = 0x0060, [12365] = 0x0011, [12366] = 0x0401,
82 [12368] = 0x0050, [12369] = 0x0003, [12370] = 0x0100, [12372] = 0x0060,
83 [12373] = 0x003b, [12374] = 0x0502, [12375] = 0x0100, [12376] = 0x2fff,
84 [12380] = 0x2fff, [12384] = 0x2fff, [12388] = 0x2fff, [12392] = 0x2fff,
85 [12396] = 0x2fff, [12400] = 0x2fff, [12404] = 0x2fff, [12408] = 0x2fff,
86 [12412] = 0x2fff, [12416] = 0x0001, [12417] = 0x0001, [12419] = 0x0006,
87 [12420] = 0x0040, [12421] = 0x0001, [12422] = 0x000f, [12423] = 0x0006,
88 [12424] = 0x0001, [12425] = 0x0003, [12426] = 0x0106, [12428] = 0x0061,
89 [12429] = 0x0011, [12430] = 0x0401, [12432] = 0x0050, [12433] = 0x0003,
90 [12434] = 0x0102, [12436] = 0x0051, [12437] = 0x0003, [12438] = 0x0106,
91 [12439] = 0x000a, [12440] = 0x0061, [12441] = 0x003b, [12442] = 0x0502,
92 [12443] = 0x0100, [12444] = 0x2fff, [12448] = 0x2fff, [12452] = 0x2fff,
93 [12456] = 0x2fff, [12460] = 0x2fff, [12464] = 0x2fff, [12468] = 0x2fff,
94 [12472] = 0x2fff, [12476] = 0x2fff, [12480] = 0x0001, [12481] = 0x0001,
95 [12483] = 0x0006, [12484] = 0x0040, [12485] = 0x0001, [12486] = 0x000f,
96 [12487] = 0x0006, [12488] = 0x0001, [12489] = 0x0003, [12490] = 0x0106,
97 [12492] = 0x0061, [12493] = 0x0011, [12494] = 0x0401, [12496] = 0x0050,
98 [12497] = 0x0003, [12498] = 0x0102, [12500] = 0x0061, [12501] = 0x003b,
99 [12502] = 0x0502, [12503] = 0x0100, [12504] = 0x2fff, [12508] = 0x2fff,
100 [12512] = 0x2fff, [12516] = 0x2fff, [12520] = 0x2fff, [12524] = 0x2fff,
101 [12528] = 0x2fff, [12532] = 0x2fff, [12536] = 0x2fff, [12540] = 0x2fff,
102 [12544] = 0x0060, [12546] = 0x0601, [12548] = 0x0050, [12550] = 0x0100,
103 [12552] = 0x0001, [12554] = 0x0104, [12555] = 0x0100, [12556] = 0x2fff,
104 [12560] = 0x2fff, [12564] = 0x2fff, [12568] = 0x2fff, [12572] = 0x2fff,
105 [12576] = 0x2fff, [12580] = 0x2fff, [12584] = 0x2fff, [12588] = 0x2fff,
106 [12592] = 0x2fff, [12596] = 0x2fff, [12600] = 0x2fff, [12604] = 0x2fff,
107 [12608] = 0x0061, [12610] = 0x0601, [12612] = 0x0050, [12614] = 0x0102,
108 [12616] = 0x0001, [12618] = 0x0106, [12619] = 0x0100, [12620] = 0x2fff,
109 [12624] = 0x2fff, [12628] = 0x2fff, [12632] = 0x2fff, [12636] = 0x2fff,
110 [12640] = 0x2fff, [12644] = 0x2fff, [12648] = 0x2fff, [12652] = 0x2fff,
111 [12656] = 0x2fff, [12660] = 0x2fff, [12664] = 0x2fff, [12668] = 0x2fff,
112 [12672] = 0x0060, [12674] = 0x0601, [12676] = 0x0061, [12678] = 0x0601,
113 [12680] = 0x0050, [12682] = 0x0300, [12684] = 0x0001, [12686] = 0x0304,
114 [12688] = 0x0040, [12690] = 0x000f, [12692] = 0x0001, [12695] = 0x0100
115};
116
117struct fll_config {
118 int src;
119 int in;
120 int out;
121};
122
123struct wm8995_priv {
124 enum snd_soc_control_type control_type;
125 int sysclk[2];
126 int mclk[2];
127 int aifclk[2];
128 struct fll_config fll[2], fll_suspend[2];
129};
130
131static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
132static const DECLARE_TLV_DB_SCALE(in1lr_pga_tlv, -1650, 150, 0);
133static const DECLARE_TLV_DB_SCALE(in1l_boost_tlv, 0, 600, 0);
134static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);
135
136static const char *in1l_text[] = {
137 "Differential", "Single-ended IN1LN", "Single-ended IN1LP"
138};
139
140static const SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL,
141 2, in1l_text);
142
143static const char *in1r_text[] = {
144 "Differential", "Single-ended IN1RN", "Single-ended IN1RP"
145};
146
147static const SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL,
148 0, in1r_text);
149
150static const char *dmic_src_text[] = {
151 "DMICDAT1", "DMICDAT2", "DMICDAT3"
152};
153
154static const SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5,
155 8, dmic_src_text);
156static const SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5,
157 6, dmic_src_text);
158
159static const struct snd_kcontrol_new wm8995_snd_controls[] = {
160 SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME,
161 WM8995_DAC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
162 SOC_DOUBLE_R("DAC1 Switch", WM8995_DAC1_LEFT_VOLUME,
163 WM8995_DAC1_RIGHT_VOLUME, 9, 1, 1),
164
165 SOC_DOUBLE_R_TLV("DAC2 Volume", WM8995_DAC2_LEFT_VOLUME,
166 WM8995_DAC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
167 SOC_DOUBLE_R("DAC2 Switch", WM8995_DAC2_LEFT_VOLUME,
168 WM8995_DAC2_RIGHT_VOLUME, 9, 1, 1),
169
170 SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8995_AIF1_DAC1_LEFT_VOLUME,
171 WM8995_AIF1_DAC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
172 SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8995_AIF1_DAC2_LEFT_VOLUME,
173 WM8995_AIF1_DAC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
174 SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8995_AIF2_DAC_LEFT_VOLUME,
175 WM8995_AIF2_DAC_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
176
177 SOC_DOUBLE_R_TLV("IN1LR Volume", WM8995_LEFT_LINE_INPUT_1_VOLUME,
178 WM8995_RIGHT_LINE_INPUT_1_VOLUME, 0, 31, 0, in1lr_pga_tlv),
179
180 SOC_SINGLE_TLV("IN1L Boost", WM8995_LEFT_LINE_INPUT_CONTROL,
181 4, 3, 0, in1l_boost_tlv),
182
183 SOC_ENUM("IN1L Mode", in1l_enum),
184 SOC_ENUM("IN1R Mode", in1r_enum),
185
186 SOC_ENUM("DMIC1 SRC", dmic_src1_enum),
187 SOC_ENUM("DMIC2 SRC", dmic_src2_enum),
188
189 SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8995_DAC1_MIXER_VOLUMES, 0, 5,
190 24, 0, sidetone_tlv),
191 SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8995_DAC2_MIXER_VOLUMES, 0, 5,
192 24, 0, sidetone_tlv),
193
194 SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8995_AIF1_ADC1_LEFT_VOLUME,
195 WM8995_AIF1_ADC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
196 SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8995_AIF1_ADC2_LEFT_VOLUME,
197 WM8995_AIF1_ADC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv),
198 SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8995_AIF2_ADC_LEFT_VOLUME,
199 WM8995_AIF2_ADC_RIGHT_VOLUME, 0, 96, 0, digital_tlv)
200};
201
202static void wm8995_update_class_w(struct snd_soc_codec *codec)
203{
204 int enable = 1;
205 int source = 0; /* GCC flow analysis can't track enable */
206 int reg, reg_r;
207
208 /* We also need the same setting for L/R and only one path */
209 reg = snd_soc_read(codec, WM8995_DAC1_LEFT_MIXER_ROUTING);
210 switch (reg) {
211 case WM8995_AIF2DACL_TO_DAC1L:
212 dev_dbg(codec->dev, "Class W source AIF2DAC\n");
213 source = 2 << WM8995_CP_DYN_SRC_SEL_SHIFT;
214 break;
215 case WM8995_AIF1DAC2L_TO_DAC1L:
216 dev_dbg(codec->dev, "Class W source AIF1DAC2\n");
217 source = 1 << WM8995_CP_DYN_SRC_SEL_SHIFT;
218 break;
219 case WM8995_AIF1DAC1L_TO_DAC1L:
220 dev_dbg(codec->dev, "Class W source AIF1DAC1\n");
221 source = 0 << WM8995_CP_DYN_SRC_SEL_SHIFT;
222 break;
223 default:
224 dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg);
225 enable = 0;
226 break;
227 }
228
229 reg_r = snd_soc_read(codec, WM8995_DAC1_RIGHT_MIXER_ROUTING);
230 if (reg_r != reg) {
231 dev_dbg(codec->dev, "Left and right DAC mixers different\n");
232 enable = 0;
233 }
234
235 if (enable) {
236 dev_dbg(codec->dev, "Class W enabled\n");
237 snd_soc_update_bits(codec, WM8995_CLASS_W_1,
238 WM8995_CP_DYN_PWR_MASK |
239 WM8995_CP_DYN_SRC_SEL_MASK,
240 source | WM8995_CP_DYN_PWR);
241 } else {
242 dev_dbg(codec->dev, "Class W disabled\n");
243 snd_soc_update_bits(codec, WM8995_CLASS_W_1,
244 WM8995_CP_DYN_PWR_MASK, 0);
245 }
246}
247
248static int check_clk_sys(struct snd_soc_dapm_widget *source,
249 struct snd_soc_dapm_widget *sink)
250{
251 unsigned int reg;
252 const char *clk;
253
254 reg = snd_soc_read(source->codec, WM8995_CLOCKING_1);
255 /* Check what we're currently using for CLK_SYS */
256 if (reg & WM8995_SYSCLK_SRC)
257 clk = "AIF2CLK";
258 else
259 clk = "AIF1CLK";
260 return !strcmp(source->name, clk);
261}
262
263static int wm8995_put_class_w(struct snd_kcontrol *kcontrol,
264 struct snd_ctl_elem_value *ucontrol)
265{
266 struct snd_soc_dapm_widget *w;
267 struct snd_soc_codec *codec;
268 int ret;
269
270 w = snd_kcontrol_chip(kcontrol);
271 codec = w->codec;
272 ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol);
273 wm8995_update_class_w(codec);
274 return ret;
275}
276
277static int hp_supply_event(struct snd_soc_dapm_widget *w,
278 struct snd_kcontrol *kcontrol, int event)
279{
280 struct snd_soc_codec *codec;
281 struct wm8995_priv *wm8995;
282
283 codec = w->codec;
284 wm8995 = snd_soc_codec_get_drvdata(codec);
285
286 switch (event) {
287 case SND_SOC_DAPM_PRE_PMU:
288 /* Enable the headphone amp */
289 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
290 WM8995_HPOUT1L_ENA_MASK |
291 WM8995_HPOUT1R_ENA_MASK,
292 WM8995_HPOUT1L_ENA |
293 WM8995_HPOUT1R_ENA);
294
295 /* Enable the second stage */
296 snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
297 WM8995_HPOUT1L_DLY_MASK |
298 WM8995_HPOUT1R_DLY_MASK,
299 WM8995_HPOUT1L_DLY |
300 WM8995_HPOUT1R_DLY);
301 break;
302 case SND_SOC_DAPM_PRE_PMD:
303 snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1,
304 WM8995_CP_ENA_MASK, 0);
305 break;
306 }
307
308 return 0;
309}
310
311static void dc_servo_cmd(struct snd_soc_codec *codec,
312 unsigned int reg, unsigned int val, unsigned int mask)
313{
314 int timeout = 10;
315
316 dev_dbg(codec->dev, "%s: reg = %#x, val = %#x, mask = %#x\n",
317 __func__, reg, val, mask);
318
319 snd_soc_write(codec, reg, val);
320 while (timeout--) {
321 msleep(10);
322 val = snd_soc_read(codec, WM8995_DC_SERVO_READBACK_0);
323 if ((val & mask) == mask)
324 return;
325 }
326
327 dev_err(codec->dev, "Timed out waiting for DC Servo\n");
328}
329
330static int hp_event(struct snd_soc_dapm_widget *w,
331 struct snd_kcontrol *kcontrol, int event)
332{
333 struct snd_soc_codec *codec;
334 unsigned int reg;
335
336 codec = w->codec;
337 reg = snd_soc_read(codec, WM8995_ANALOGUE_HP_1);
338
339 switch (event) {
340 case SND_SOC_DAPM_POST_PMU:
341 snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1,
342 WM8995_CP_ENA_MASK, WM8995_CP_ENA);
343
344 msleep(5);
345
346 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
347 WM8995_HPOUT1L_ENA_MASK |
348 WM8995_HPOUT1R_ENA_MASK,
349 WM8995_HPOUT1L_ENA | WM8995_HPOUT1R_ENA);
350
351 udelay(20);
352
353 reg |= WM8995_HPOUT1L_DLY | WM8995_HPOUT1R_DLY;
354 snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg);
355
356 snd_soc_write(codec, WM8995_DC_SERVO_1, WM8995_DCS_ENA_CHAN_0 |
357 WM8995_DCS_ENA_CHAN_1);
358
359 dc_servo_cmd(codec, WM8995_DC_SERVO_2,
360 WM8995_DCS_TRIG_STARTUP_0 |
361 WM8995_DCS_TRIG_STARTUP_1,
362 WM8995_DCS_TRIG_DAC_WR_0 |
363 WM8995_DCS_TRIG_DAC_WR_1);
364
365 reg |= WM8995_HPOUT1R_OUTP | WM8995_HPOUT1R_RMV_SHORT |
366 WM8995_HPOUT1L_OUTP | WM8995_HPOUT1L_RMV_SHORT;
367 snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg);
368
369 break;
370 case SND_SOC_DAPM_PRE_PMD:
371 snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
372 WM8995_HPOUT1L_OUTP_MASK |
373 WM8995_HPOUT1R_OUTP_MASK |
374 WM8995_HPOUT1L_RMV_SHORT_MASK |
375 WM8995_HPOUT1R_RMV_SHORT_MASK, 0);
376
377 snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1,
378 WM8995_HPOUT1L_DLY_MASK |
379 WM8995_HPOUT1R_DLY_MASK, 0);
380
381 snd_soc_write(codec, WM8995_DC_SERVO_1, 0);
382
383 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
384 WM8995_HPOUT1L_ENA_MASK |
385 WM8995_HPOUT1R_ENA_MASK,
386 0);
387 break;
388 }
389
390 return 0;
391}
392
393static int configure_aif_clock(struct snd_soc_codec *codec, int aif)
394{
395 struct wm8995_priv *wm8995;
396 int rate;
397 int reg1 = 0;
398 int offset;
399
400 wm8995 = snd_soc_codec_get_drvdata(codec);
401
402 if (aif)
403 offset = 4;
404 else
405 offset = 0;
406
407 switch (wm8995->sysclk[aif]) {
408 case WM8995_SYSCLK_MCLK1:
409 rate = wm8995->mclk[0];
410 break;
411 case WM8995_SYSCLK_MCLK2:
412 reg1 |= 0x8;
413 rate = wm8995->mclk[1];
414 break;
415 case WM8995_SYSCLK_FLL1:
416 reg1 |= 0x10;
417 rate = wm8995->fll[0].out;
418 break;
419 case WM8995_SYSCLK_FLL2:
420 reg1 |= 0x18;
421 rate = wm8995->fll[1].out;
422 break;
423 default:
424 return -EINVAL;
425 }
426
427 if (rate >= 13500000) {
428 rate /= 2;
429 reg1 |= WM8995_AIF1CLK_DIV;
430
431 dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n",
432 aif + 1, rate);
433 }
434
435 wm8995->aifclk[aif] = rate;
436
437 snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1 + offset,
438 WM8995_AIF1CLK_SRC_MASK | WM8995_AIF1CLK_DIV_MASK,
439 reg1);
440 return 0;
441}
442
443static int configure_clock(struct snd_soc_codec *codec)
444{
445 struct wm8995_priv *wm8995;
446 int old, new;
447
448 wm8995 = snd_soc_codec_get_drvdata(codec);
449
450 /* Bring up the AIF clocks first */
451 configure_aif_clock(codec, 0);
452 configure_aif_clock(codec, 1);
453
454 /*
455 * Then switch CLK_SYS over to the higher of them; a change
456 * can only happen as a result of a clocking change which can
457 * only be made outside of DAPM so we can safely redo the
458 * clocking.
459 */
460
461 /* If they're equal it doesn't matter which is used */
462 if (wm8995->aifclk[0] == wm8995->aifclk[1])
463 return 0;
464
465 if (wm8995->aifclk[0] < wm8995->aifclk[1])
466 new = WM8995_SYSCLK_SRC;
467 else
468 new = 0;
469
470 old = snd_soc_read(codec, WM8995_CLOCKING_1) & WM8995_SYSCLK_SRC;
471
472 /* If there's no change then we're done. */
473 if (old == new)
474 return 0;
475
476 snd_soc_update_bits(codec, WM8995_CLOCKING_1,
477 WM8995_SYSCLK_SRC_MASK, new);
478
479 snd_soc_dapm_sync(&codec->dapm);
480
481 return 0;
482}
483
484static int clk_sys_event(struct snd_soc_dapm_widget *w,
485 struct snd_kcontrol *kcontrol, int event)
486{
487 struct snd_soc_codec *codec;
488
489 codec = w->codec;
490
491 switch (event) {
492 case SND_SOC_DAPM_PRE_PMU:
493 return configure_clock(codec);
494
495 case SND_SOC_DAPM_POST_PMD:
496 configure_clock(codec);
497 break;
498 }
499
500 return 0;
501}
502
503static const char *sidetone_text[] = {
504 "ADC/DMIC1", "DMIC2",
505};
506
507static const struct soc_enum sidetone1_enum =
508 SOC_ENUM_SINGLE(WM8995_SIDETONE, 0, 2, sidetone_text);
509
510static const struct snd_kcontrol_new sidetone1_mux =
511 SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum);
512
513static const struct soc_enum sidetone2_enum =
514 SOC_ENUM_SINGLE(WM8995_SIDETONE, 1, 2, sidetone_text);
515
516static const struct snd_kcontrol_new sidetone2_mux =
517 SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum);
518
519static const struct snd_kcontrol_new aif1adc1l_mix[] = {
520 SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING,
521 1, 1, 0),
522 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING,
523 0, 1, 0),
524};
525
526static const struct snd_kcontrol_new aif1adc1r_mix[] = {
527 SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING,
528 1, 1, 0),
529 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING,
530 0, 1, 0),
531};
532
533static const struct snd_kcontrol_new aif1adc2l_mix[] = {
534 SOC_DAPM_SINGLE("DMIC Switch", WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING,
535 1, 1, 0),
536 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING,
537 0, 1, 0),
538};
539
540static const struct snd_kcontrol_new aif1adc2r_mix[] = {
541 SOC_DAPM_SINGLE("DMIC Switch", WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING,
542 1, 1, 0),
543 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING,
544 0, 1, 0),
545};
546
547static const struct snd_kcontrol_new dac1l_mix[] = {
548 WM8995_CLASS_W_SWITCH("Right Sidetone Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
549 5, 1, 0),
550 WM8995_CLASS_W_SWITCH("Left Sidetone Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
551 4, 1, 0),
552 WM8995_CLASS_W_SWITCH("AIF2 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
553 2, 1, 0),
554 WM8995_CLASS_W_SWITCH("AIF1.2 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
555 1, 1, 0),
556 WM8995_CLASS_W_SWITCH("AIF1.1 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING,
557 0, 1, 0),
558};
559
560static const struct snd_kcontrol_new dac1r_mix[] = {
561 WM8995_CLASS_W_SWITCH("Right Sidetone Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
562 5, 1, 0),
563 WM8995_CLASS_W_SWITCH("Left Sidetone Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
564 4, 1, 0),
565 WM8995_CLASS_W_SWITCH("AIF2 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
566 2, 1, 0),
567 WM8995_CLASS_W_SWITCH("AIF1.2 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
568 1, 1, 0),
569 WM8995_CLASS_W_SWITCH("AIF1.1 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING,
570 0, 1, 0),
571};
572
573static const struct snd_kcontrol_new aif2dac2l_mix[] = {
574 SOC_DAPM_SINGLE("Right Sidetone Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
575 5, 1, 0),
576 SOC_DAPM_SINGLE("Left Sidetone Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
577 4, 1, 0),
578 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
579 2, 1, 0),
580 SOC_DAPM_SINGLE("AIF1.2 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
581 1, 1, 0),
582 SOC_DAPM_SINGLE("AIF1.1 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING,
583 0, 1, 0),
584};
585
586static const struct snd_kcontrol_new aif2dac2r_mix[] = {
587 SOC_DAPM_SINGLE("Right Sidetone Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
588 5, 1, 0),
589 SOC_DAPM_SINGLE("Left Sidetone Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
590 4, 1, 0),
591 SOC_DAPM_SINGLE("AIF2 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
592 2, 1, 0),
593 SOC_DAPM_SINGLE("AIF1.2 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
594 1, 1, 0),
595 SOC_DAPM_SINGLE("AIF1.1 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING,
596 0, 1, 0),
597};
598
599static const struct snd_kcontrol_new in1l_pga =
600 SOC_DAPM_SINGLE("IN1L Switch", WM8995_POWER_MANAGEMENT_2, 5, 1, 0);
601
602static const struct snd_kcontrol_new in1r_pga =
603 SOC_DAPM_SINGLE("IN1R Switch", WM8995_POWER_MANAGEMENT_2, 4, 1, 0);
604
605static const char *adc_mux_text[] = {
606 "ADC",
607 "DMIC",
608};
609
610static const struct soc_enum adc_enum =
611 SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text);
612
613static const struct snd_kcontrol_new adcl_mux =
614 SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum);
615
616static const struct snd_kcontrol_new adcr_mux =
617 SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum);
618
619static const char *spk_src_text[] = {
620 "DAC1L", "DAC1R", "DAC2L", "DAC2R"
621};
622
623static const SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1,
624 0, spk_src_text);
625static const SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1,
626 0, spk_src_text);
627static const SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2,
628 0, spk_src_text);
629static const SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2,
630 0, spk_src_text);
631
632static const struct snd_kcontrol_new spk1l_mux =
633 SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum);
634static const struct snd_kcontrol_new spk1r_mux =
635 SOC_DAPM_ENUM("SPK1R SRC", spk1r_src_enum);
636static const struct snd_kcontrol_new spk2l_mux =
637 SOC_DAPM_ENUM("SPK2L SRC", spk2l_src_enum);
638static const struct snd_kcontrol_new spk2r_mux =
639 SOC_DAPM_ENUM("SPK2R SRC", spk2r_src_enum);
640
641static const struct snd_soc_dapm_widget wm8995_dapm_widgets[] = {
642 SND_SOC_DAPM_INPUT("DMIC1DAT"),
643 SND_SOC_DAPM_INPUT("DMIC2DAT"),
644
645 SND_SOC_DAPM_INPUT("IN1L"),
646 SND_SOC_DAPM_INPUT("IN1R"),
647
648 SND_SOC_DAPM_MIXER("IN1L PGA", SND_SOC_NOPM, 0, 0,
649 &in1l_pga, 1),
650 SND_SOC_DAPM_MIXER("IN1R PGA", SND_SOC_NOPM, 0, 0,
651 &in1r_pga, 1),
652
653 SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0),
654 SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0),
655
656 SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8995_AIF1_CLOCKING_1, 0, 0, NULL, 0),
657 SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8995_AIF2_CLOCKING_1, 0, 0, NULL, 0),
658 SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8995_CLOCKING_1, 3, 0, NULL, 0),
659 SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8995_CLOCKING_1, 2, 0, NULL, 0),
660 SND_SOC_DAPM_SUPPLY("SYSDSPCLK", WM8995_CLOCKING_1, 1, 0, NULL, 0),
661 SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event,
662 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
663
664 SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture", 0,
665 WM8995_POWER_MANAGEMENT_3, 9, 0),
666 SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", 0,
667 WM8995_POWER_MANAGEMENT_3, 8, 0),
668 SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0,
669 SND_SOC_NOPM, 0, 0),
670 SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture",
671 0, WM8995_POWER_MANAGEMENT_3, 11, 0),
672 SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture",
673 0, WM8995_POWER_MANAGEMENT_3, 10, 0),
674
675 SND_SOC_DAPM_VIRT_MUX("ADCL Mux", SND_SOC_NOPM, 1, 0,
676 &adcl_mux),
677 SND_SOC_DAPM_VIRT_MUX("ADCR Mux", SND_SOC_NOPM, 0, 0,
678 &adcr_mux),
679
680 SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8995_POWER_MANAGEMENT_3, 5, 0),
681 SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8995_POWER_MANAGEMENT_3, 4, 0),
682 SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8995_POWER_MANAGEMENT_3, 3, 0),
683 SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8995_POWER_MANAGEMENT_3, 2, 0),
684
685 SND_SOC_DAPM_ADC("ADCL", NULL, WM8995_POWER_MANAGEMENT_3, 1, 0),
686 SND_SOC_DAPM_ADC("ADCR", NULL, WM8995_POWER_MANAGEMENT_3, 0, 0),
687
688 SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0,
689 aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)),
690 SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0,
691 aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)),
692 SND_SOC_DAPM_MIXER("AIF1ADC2L Mixer", SND_SOC_NOPM, 0, 0,
693 aif1adc2l_mix, ARRAY_SIZE(aif1adc2l_mix)),
694 SND_SOC_DAPM_MIXER("AIF1ADC2R Mixer", SND_SOC_NOPM, 0, 0,
695 aif1adc2r_mix, ARRAY_SIZE(aif1adc2r_mix)),
696
697 SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0, WM8995_POWER_MANAGEMENT_4,
698 9, 0),
699 SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0, WM8995_POWER_MANAGEMENT_4,
700 8, 0),
701 SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM,
702 0, 0),
703
704 SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0, WM8995_POWER_MANAGEMENT_4,
705 11, 0),
706 SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0, WM8995_POWER_MANAGEMENT_4,
707 10, 0),
708
709 SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0,
710 aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)),
711 SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0,
712 aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)),
713
714 SND_SOC_DAPM_DAC("DAC2L", NULL, WM8995_POWER_MANAGEMENT_4, 3, 0),
715 SND_SOC_DAPM_DAC("DAC2R", NULL, WM8995_POWER_MANAGEMENT_4, 2, 0),
716 SND_SOC_DAPM_DAC("DAC1L", NULL, WM8995_POWER_MANAGEMENT_4, 1, 0),
717 SND_SOC_DAPM_DAC("DAC1R", NULL, WM8995_POWER_MANAGEMENT_4, 0, 0),
718
719 SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0, dac1l_mix,
720 ARRAY_SIZE(dac1l_mix)),
721 SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, dac1r_mix,
722 ARRAY_SIZE(dac1r_mix)),
723
724 SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux),
725 SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux),
726
727 SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
728 hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
729
730 SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0,
731 hp_supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),
732
733 SND_SOC_DAPM_MUX("SPK1L Driver", WM8995_LEFT_PDM_SPEAKER_1,
734 4, 0, &spk1l_mux),
735 SND_SOC_DAPM_MUX("SPK1R Driver", WM8995_RIGHT_PDM_SPEAKER_1,
736 4, 0, &spk1r_mux),
737 SND_SOC_DAPM_MUX("SPK2L Driver", WM8995_LEFT_PDM_SPEAKER_2,
738 4, 0, &spk2l_mux),
739 SND_SOC_DAPM_MUX("SPK2R Driver", WM8995_RIGHT_PDM_SPEAKER_2,
740 4, 0, &spk2r_mux),
741
742 SND_SOC_DAPM_SUPPLY("LDO2", WM8995_POWER_MANAGEMENT_2, 1, 0, NULL, 0),
743
744 SND_SOC_DAPM_OUTPUT("HP1L"),
745 SND_SOC_DAPM_OUTPUT("HP1R"),
746 SND_SOC_DAPM_OUTPUT("SPK1L"),
747 SND_SOC_DAPM_OUTPUT("SPK1R"),
748 SND_SOC_DAPM_OUTPUT("SPK2L"),
749 SND_SOC_DAPM_OUTPUT("SPK2R")
750};
751
752static const struct snd_soc_dapm_route wm8995_intercon[] = {
753 { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys },
754 { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys },
755
756 { "DSP1CLK", NULL, "CLK_SYS" },
757 { "DSP2CLK", NULL, "CLK_SYS" },
758 { "SYSDSPCLK", NULL, "CLK_SYS" },
759
760 { "AIF1ADC1L", NULL, "AIF1CLK" },
761 { "AIF1ADC1L", NULL, "DSP1CLK" },
762 { "AIF1ADC1R", NULL, "AIF1CLK" },
763 { "AIF1ADC1R", NULL, "DSP1CLK" },
764 { "AIF1ADC1R", NULL, "SYSDSPCLK" },
765
766 { "AIF1ADC2L", NULL, "AIF1CLK" },
767 { "AIF1ADC2L", NULL, "DSP1CLK" },
768 { "AIF1ADC2R", NULL, "AIF1CLK" },
769 { "AIF1ADC2R", NULL, "DSP1CLK" },
770 { "AIF1ADC2R", NULL, "SYSDSPCLK" },
771
772 { "DMIC1L", NULL, "DMIC1DAT" },
773 { "DMIC1L", NULL, "CLK_SYS" },
774 { "DMIC1R", NULL, "DMIC1DAT" },
775 { "DMIC1R", NULL, "CLK_SYS" },
776 { "DMIC2L", NULL, "DMIC2DAT" },
777 { "DMIC2L", NULL, "CLK_SYS" },
778 { "DMIC2R", NULL, "DMIC2DAT" },
779 { "DMIC2R", NULL, "CLK_SYS" },
780
781 { "ADCL", NULL, "AIF1CLK" },
782 { "ADCL", NULL, "DSP1CLK" },
783 { "ADCL", NULL, "SYSDSPCLK" },
784
785 { "ADCR", NULL, "AIF1CLK" },
786 { "ADCR", NULL, "DSP1CLK" },
787 { "ADCR", NULL, "SYSDSPCLK" },
788
789 { "IN1L PGA", "IN1L Switch", "IN1L" },
790 { "IN1R PGA", "IN1R Switch", "IN1R" },
791 { "IN1L PGA", NULL, "LDO2" },
792 { "IN1R PGA", NULL, "LDO2" },
793
794 { "ADCL", NULL, "IN1L PGA" },
795 { "ADCR", NULL, "IN1R PGA" },
796
797 { "ADCL Mux", "ADC", "ADCL" },
798 { "ADCL Mux", "DMIC", "DMIC1L" },
799 { "ADCR Mux", "ADC", "ADCR" },
800 { "ADCR Mux", "DMIC", "DMIC1R" },
801
802 /* AIF1 outputs */
803 { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" },
804 { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" },
805
806 { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" },
807 { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" },
808
809 { "AIF1ADC2L", NULL, "AIF1ADC2L Mixer" },
810 { "AIF1ADC2L Mixer", "DMIC Switch", "DMIC2L" },
811
812 { "AIF1ADC2R", NULL, "AIF1ADC2R Mixer" },
813 { "AIF1ADC2R Mixer", "DMIC Switch", "DMIC2R" },
814
815 /* Sidetone */
816 { "Left Sidetone", "ADC/DMIC1", "AIF1ADC1L" },
817 { "Left Sidetone", "DMIC2", "AIF1ADC2L" },
818 { "Right Sidetone", "ADC/DMIC1", "AIF1ADC1R" },
819 { "Right Sidetone", "DMIC2", "AIF1ADC2R" },
820
821 { "AIF1DAC1L", NULL, "AIF1CLK" },
822 { "AIF1DAC1L", NULL, "DSP1CLK" },
823 { "AIF1DAC1R", NULL, "AIF1CLK" },
824 { "AIF1DAC1R", NULL, "DSP1CLK" },
825 { "AIF1DAC1R", NULL, "SYSDSPCLK" },
826
827 { "AIF1DAC2L", NULL, "AIF1CLK" },
828 { "AIF1DAC2L", NULL, "DSP1CLK" },
829 { "AIF1DAC2R", NULL, "AIF1CLK" },
830 { "AIF1DAC2R", NULL, "DSP1CLK" },
831 { "AIF1DAC2R", NULL, "SYSDSPCLK" },
832
833 { "DAC1L", NULL, "AIF1CLK" },
834 { "DAC1L", NULL, "DSP1CLK" },
835 { "DAC1L", NULL, "SYSDSPCLK" },
836
837 { "DAC1R", NULL, "AIF1CLK" },
838 { "DAC1R", NULL, "DSP1CLK" },
839 { "DAC1R", NULL, "SYSDSPCLK" },
840
841 { "AIF1DAC1L", NULL, "AIF1DACDAT" },
842 { "AIF1DAC1R", NULL, "AIF1DACDAT" },
843 { "AIF1DAC2L", NULL, "AIF1DACDAT" },
844 { "AIF1DAC2R", NULL, "AIF1DACDAT" },
845
846 /* DAC1 inputs */
847 { "DAC1L", NULL, "DAC1L Mixer" },
848 { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
849 { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
850 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },
851 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },
852
853 { "DAC1R", NULL, "DAC1R Mixer" },
854 { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
855 { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
856 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },
857 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },
858
859 /* DAC2/AIF2 outputs */
860 { "DAC2L", NULL, "AIF2DAC2L Mixer" },
861 { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" },
862 { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" },
863
864 { "DAC2R", NULL, "AIF2DAC2R Mixer" },
865 { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" },
866 { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" },
867
868 /* Output stages */
869 { "Headphone PGA", NULL, "DAC1L" },
870 { "Headphone PGA", NULL, "DAC1R" },
871
872 { "Headphone PGA", NULL, "DAC2L" },
873 { "Headphone PGA", NULL, "DAC2R" },
874
875 { "Headphone PGA", NULL, "Headphone Supply" },
876 { "Headphone PGA", NULL, "CLK_SYS" },
877 { "Headphone PGA", NULL, "LDO2" },
878
879 { "HP1L", NULL, "Headphone PGA" },
880 { "HP1R", NULL, "Headphone PGA" },
881
882 { "SPK1L Driver", "DAC1L", "DAC1L" },
883 { "SPK1L Driver", "DAC1R", "DAC1R" },
884 { "SPK1L Driver", "DAC2L", "DAC2L" },
885 { "SPK1L Driver", "DAC2R", "DAC2R" },
886 { "SPK1L Driver", NULL, "CLK_SYS" },
887
888 { "SPK1R Driver", "DAC1L", "DAC1L" },
889 { "SPK1R Driver", "DAC1R", "DAC1R" },
890 { "SPK1R Driver", "DAC2L", "DAC2L" },
891 { "SPK1R Driver", "DAC2R", "DAC2R" },
892 { "SPK1R Driver", NULL, "CLK_SYS" },
893
894 { "SPK2L Driver", "DAC1L", "DAC1L" },
895 { "SPK2L Driver", "DAC1R", "DAC1R" },
896 { "SPK2L Driver", "DAC2L", "DAC2L" },
897 { "SPK2L Driver", "DAC2R", "DAC2R" },
898 { "SPK2L Driver", NULL, "CLK_SYS" },
899
900 { "SPK2R Driver", "DAC1L", "DAC1L" },
901 { "SPK2R Driver", "DAC1R", "DAC1R" },
902 { "SPK2R Driver", "DAC2L", "DAC2L" },
903 { "SPK2R Driver", "DAC2R", "DAC2R" },
904 { "SPK2R Driver", NULL, "CLK_SYS" },
905
906 { "SPK1L", NULL, "SPK1L Driver" },
907 { "SPK1R", NULL, "SPK1R Driver" },
908 { "SPK2L", NULL, "SPK2L Driver" },
909 { "SPK2R", NULL, "SPK2R Driver" }
910};
911
912static int wm8995_volatile(unsigned int reg)
913{
914 /* out of bounds registers are generally considered
915 * volatile to support register banks that are partially
916 * owned by something else for e.g. a DSP
917 */
918 if (reg > WM8995_MAX_CACHED_REGISTER)
919 return 1;
920
921 switch (reg) {
922 case WM8995_SOFTWARE_RESET:
923 case WM8995_DC_SERVO_READBACK_0:
924 case WM8995_INTERRUPT_STATUS_1:
925 case WM8995_INTERRUPT_STATUS_2:
926 case WM8995_INTERRUPT_STATUS_1_MASK:
927 case WM8995_INTERRUPT_STATUS_2_MASK:
928 case WM8995_INTERRUPT_CONTROL:
929 case WM8995_ACCESSORY_DETECT_MODE1:
930 case WM8995_ACCESSORY_DETECT_MODE2:
931 case WM8995_HEADPHONE_DETECT1:
932 case WM8995_HEADPHONE_DETECT2:
933 return 1;
934 }
935
936 return 0;
937}
938
939static int wm8995_aif_mute(struct snd_soc_dai *dai, int mute)
940{
941 struct snd_soc_codec *codec = dai->codec;
942 int mute_reg;
943
944 switch (dai->id) {
945 case 0:
946 mute_reg = WM8995_AIF1_DAC1_FILTERS_1;
947 break;
948 case 1:
949 mute_reg = WM8995_AIF2_DAC_FILTERS_1;
950 break;
951 default:
952 return -EINVAL;
953 }
954
955 snd_soc_update_bits(codec, mute_reg, WM8995_AIF1DAC1_MUTE_MASK,
956 !!mute << WM8995_AIF1DAC1_MUTE_SHIFT);
957 return 0;
958}
959
960static int wm8995_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
961{
962 struct snd_soc_codec *codec;
963 int master;
964 int aif;
965
966 codec = dai->codec;
967
968 master = 0;
969 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
970 case SND_SOC_DAIFMT_CBS_CFS:
971 break;
972 case SND_SOC_DAIFMT_CBM_CFM:
973 master = WM8995_AIF1_MSTR;
974 break;
975 default:
976 dev_err(dai->dev, "Unknown master/slave configuration\n");
977 return -EINVAL;
978 }
979
980 aif = 0;
981 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
982 case SND_SOC_DAIFMT_DSP_B:
983 aif |= WM8995_AIF1_LRCLK_INV;
984 case SND_SOC_DAIFMT_DSP_A:
985 aif |= (0x3 << WM8995_AIF1_FMT_SHIFT);
986 break;
987 case SND_SOC_DAIFMT_I2S:
988 aif |= (0x2 << WM8995_AIF1_FMT_SHIFT);
989 break;
990 case SND_SOC_DAIFMT_RIGHT_J:
991 break;
992 case SND_SOC_DAIFMT_LEFT_J:
993 aif |= (0x1 << WM8995_AIF1_FMT_SHIFT);
994 break;
995 default:
996 dev_err(dai->dev, "Unknown dai format\n");
997 return -EINVAL;
998 }
999
1000 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1001 case SND_SOC_DAIFMT_DSP_A:
1002 case SND_SOC_DAIFMT_DSP_B:
1003 /* frame inversion not valid for DSP modes */
1004 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1005 case SND_SOC_DAIFMT_NB_NF:
1006 break;
1007 case SND_SOC_DAIFMT_IB_NF:
1008 aif |= WM8995_AIF1_BCLK_INV;
1009 break;
1010 default:
1011 return -EINVAL;
1012 }
1013 break;
1014
1015 case SND_SOC_DAIFMT_I2S:
1016 case SND_SOC_DAIFMT_RIGHT_J:
1017 case SND_SOC_DAIFMT_LEFT_J:
1018 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1019 case SND_SOC_DAIFMT_NB_NF:
1020 break;
1021 case SND_SOC_DAIFMT_IB_IF:
1022 aif |= WM8995_AIF1_BCLK_INV | WM8995_AIF1_LRCLK_INV;
1023 break;
1024 case SND_SOC_DAIFMT_IB_NF:
1025 aif |= WM8995_AIF1_BCLK_INV;
1026 break;
1027 case SND_SOC_DAIFMT_NB_IF:
1028 aif |= WM8995_AIF1_LRCLK_INV;
1029 break;
1030 default:
1031 return -EINVAL;
1032 }
1033 break;
1034 default:
1035 return -EINVAL;
1036 }
1037
1038 snd_soc_update_bits(codec, WM8995_AIF1_CONTROL_1,
1039 WM8995_AIF1_BCLK_INV_MASK |
1040 WM8995_AIF1_LRCLK_INV_MASK |
1041 WM8995_AIF1_FMT_MASK, aif);
1042 snd_soc_update_bits(codec, WM8995_AIF1_MASTER_SLAVE,
1043 WM8995_AIF1_MSTR_MASK, master);
1044 return 0;
1045}
1046
1047static const int srs[] = {
1048 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100,
1049 48000, 88200, 96000
1050};
1051
1052static const int fs_ratios[] = {
1053 -1 /* reserved */,
1054 128, 192, 256, 384, 512, 768, 1024, 1408, 1536
1055};
1056
1057static const int bclk_divs[] = {
1058 10, 15, 20, 30, 40, 55, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480
1059};
1060
1061static int wm8995_hw_params(struct snd_pcm_substream *substream,
1062 struct snd_pcm_hw_params *params,
1063 struct snd_soc_dai *dai)
1064{
1065 struct snd_soc_codec *codec;
1066 struct wm8995_priv *wm8995;
1067 int aif1_reg;
1068 int bclk_reg;
1069 int lrclk_reg;
1070 int rate_reg;
1071 int bclk_rate;
1072 int aif1;
1073 int lrclk, bclk;
1074 int i, rate_val, best, best_val, cur_val;
1075
1076 codec = dai->codec;
1077 wm8995 = snd_soc_codec_get_drvdata(codec);
1078
1079 switch (dai->id) {
1080 case 0:
1081 aif1_reg = WM8995_AIF1_CONTROL_1;
1082 bclk_reg = WM8995_AIF1_BCLK;
1083 rate_reg = WM8995_AIF1_RATE;
1084 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* ||
1085 wm8995->lrclk_shared[0] */) {
1086 lrclk_reg = WM8995_AIF1DAC_LRCLK;
1087 } else {
1088 lrclk_reg = WM8995_AIF1ADC_LRCLK;
1089 dev_dbg(codec->dev, "AIF1 using split LRCLK\n");
1090 }
1091 break;
1092 case 1:
1093 aif1_reg = WM8995_AIF2_CONTROL_1;
1094 bclk_reg = WM8995_AIF2_BCLK;
1095 rate_reg = WM8995_AIF2_RATE;
1096 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* ||
1097 wm8995->lrclk_shared[1] */) {
1098 lrclk_reg = WM8995_AIF2DAC_LRCLK;
1099 } else {
1100 lrclk_reg = WM8995_AIF2ADC_LRCLK;
1101 dev_dbg(codec->dev, "AIF2 using split LRCLK\n");
1102 }
1103 break;
1104 default:
1105 return -EINVAL;
1106 }
1107
1108 bclk_rate = snd_soc_params_to_bclk(params);
1109 if (bclk_rate < 0)
1110 return bclk_rate;
1111
1112 aif1 = 0;
1113 switch (params_format(params)) {
1114 case SNDRV_PCM_FORMAT_S16_LE:
1115 break;
1116 case SNDRV_PCM_FORMAT_S20_3LE:
1117 aif1 |= (0x1 << WM8995_AIF1_WL_SHIFT);
1118 break;
1119 case SNDRV_PCM_FORMAT_S24_LE:
1120 aif1 |= (0x2 << WM8995_AIF1_WL_SHIFT);
1121 break;
1122 case SNDRV_PCM_FORMAT_S32_LE:
1123 aif1 |= (0x3 << WM8995_AIF1_WL_SHIFT);
1124 break;
1125 default:
1126 dev_err(dai->dev, "Unsupported word length %u\n",
1127 params_format(params));
1128 return -EINVAL;
1129 }
1130
1131 /* try to find a suitable sample rate */
1132 for (i = 0; i < ARRAY_SIZE(srs); ++i)
1133 if (srs[i] == params_rate(params))
1134 break;
1135 if (i == ARRAY_SIZE(srs)) {
1136 dev_err(dai->dev, "Sample rate %d is not supported\n",
1137 params_rate(params));
1138 return -EINVAL;
1139 }
1140 rate_val = i << WM8995_AIF1_SR_SHIFT;
1141
1142 dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i]);
1143 dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n",
1144 dai->id + 1, wm8995->aifclk[dai->id], bclk_rate);
1145
1146 /* AIFCLK/fs ratio; look for a close match in either direction */
1147 best = 1;
1148 best_val = abs((fs_ratios[1] * params_rate(params))
1149 - wm8995->aifclk[dai->id]);
1150 for (i = 2; i < ARRAY_SIZE(fs_ratios); i++) {
1151 cur_val = abs((fs_ratios[i] * params_rate(params))
1152 - wm8995->aifclk[dai->id]);
1153 if (cur_val >= best_val)
1154 continue;
1155 best = i;
1156 best_val = cur_val;
1157 }
1158 rate_val |= best;
1159
1160 dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n",
1161 dai->id + 1, fs_ratios[best]);
1162
1163 /*
1164 * We may not get quite the right frequency if using
1165 * approximate clocks so look for the closest match that is
1166 * higher than the target (we need to ensure that there enough
1167 * BCLKs to clock out the samples).
1168 */
1169 best = 0;
1170 bclk = 0;
1171 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {
1172 cur_val = (wm8995->aifclk[dai->id] * 10 / bclk_divs[i]) - bclk_rate;
1173 if (cur_val < 0) /* BCLK table is sorted */
1174 break;
1175 best = i;
1176 }
1177 bclk |= best << WM8995_AIF1_BCLK_DIV_SHIFT;
1178
1179 bclk_rate = wm8995->aifclk[dai->id] * 10 / bclk_divs[best];
1180 dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",
1181 bclk_divs[best], bclk_rate);
1182
1183 lrclk = bclk_rate / params_rate(params);
1184 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",
1185 lrclk, bclk_rate / lrclk);
1186
1187 snd_soc_update_bits(codec, aif1_reg,
1188 WM8995_AIF1_WL_MASK, aif1);
1189 snd_soc_update_bits(codec, bclk_reg,
1190 WM8995_AIF1_BCLK_DIV_MASK, bclk);
1191 snd_soc_update_bits(codec, lrclk_reg,
1192 WM8995_AIF1DAC_RATE_MASK, lrclk);
1193 snd_soc_update_bits(codec, rate_reg,
1194 WM8995_AIF1_SR_MASK |
1195 WM8995_AIF1CLK_RATE_MASK, rate_val);
1196 return 0;
1197}
1198
1199static int wm8995_set_tristate(struct snd_soc_dai *codec_dai, int tristate)
1200{
1201 struct snd_soc_codec *codec = codec_dai->codec;
1202 int reg, val, mask;
1203
1204 switch (codec_dai->id) {
1205 case 0:
1206 reg = WM8995_AIF1_MASTER_SLAVE;
1207 mask = WM8995_AIF1_TRI;
1208 break;
1209 case 1:
1210 reg = WM8995_AIF2_MASTER_SLAVE;
1211 mask = WM8995_AIF2_TRI;
1212 break;
1213 case 2:
1214 reg = WM8995_POWER_MANAGEMENT_5;
1215 mask = WM8995_AIF3_TRI;
1216 break;
1217 default:
1218 return -EINVAL;
1219 }
1220
1221 if (tristate)
1222 val = mask;
1223 else
1224 val = 0;
1225
1226 return snd_soc_update_bits(codec, reg, mask, reg);
1227}
1228
1229/* The size in bits of the FLL divide multiplied by 10
1230 * to allow rounding later */
1231#define FIXED_FLL_SIZE ((1 << 16) * 10)
1232
1233struct fll_div {
1234 u16 outdiv;
1235 u16 n;
1236 u16 k;
1237 u16 clk_ref_div;
1238 u16 fll_fratio;
1239};
1240
1241static int wm8995_get_fll_config(struct fll_div *fll,
1242 int freq_in, int freq_out)
1243{
1244 u64 Kpart;
1245 unsigned int K, Ndiv, Nmod;
1246
1247 pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out);
1248
1249 /* Scale the input frequency down to <= 13.5MHz */
1250 fll->clk_ref_div = 0;
1251 while (freq_in > 13500000) {
1252 fll->clk_ref_div++;
1253 freq_in /= 2;
1254
1255 if (fll->clk_ref_div > 3)
1256 return -EINVAL;
1257 }
1258 pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in);
1259
1260 /* Scale the output to give 90MHz<=Fvco<=100MHz */
1261 fll->outdiv = 3;
1262 while (freq_out * (fll->outdiv + 1) < 90000000) {
1263 fll->outdiv++;
1264 if (fll->outdiv > 63)
1265 return -EINVAL;
1266 }
1267 freq_out *= fll->outdiv + 1;
1268 pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out);
1269
1270 if (freq_in > 1000000) {
1271 fll->fll_fratio = 0;
1272 } else if (freq_in > 256000) {
1273 fll->fll_fratio = 1;
1274 freq_in *= 2;
1275 } else if (freq_in > 128000) {
1276 fll->fll_fratio = 2;
1277 freq_in *= 4;
1278 } else if (freq_in > 64000) {
1279 fll->fll_fratio = 3;
1280 freq_in *= 8;
1281 } else {
1282 fll->fll_fratio = 4;
1283 freq_in *= 16;
1284 }
1285 pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in);
1286
1287 /* Now, calculate N.K */
1288 Ndiv = freq_out / freq_in;
1289
1290 fll->n = Ndiv;
1291 Nmod = freq_out % freq_in;
1292 pr_debug("Nmod=%d\n", Nmod);
1293
1294 /* Calculate fractional part - scale up so we can round. */
1295 Kpart = FIXED_FLL_SIZE * (long long)Nmod;
1296
1297 do_div(Kpart, freq_in);
1298
1299 K = Kpart & 0xFFFFFFFF;
1300
1301 if ((K % 10) >= 5)
1302 K += 5;
1303
1304 /* Move down to proper range now rounding is done */
1305 fll->k = K / 10;
1306
1307 pr_debug("N=%x K=%x\n", fll->n, fll->k);
1308
1309 return 0;
1310}
1311
1312static int wm8995_set_fll(struct snd_soc_dai *dai, int id,
1313 int src, unsigned int freq_in,
1314 unsigned int freq_out)
1315{
1316 struct snd_soc_codec *codec;
1317 struct wm8995_priv *wm8995;
1318 int reg_offset, ret;
1319 struct fll_div fll;
1320 u16 reg, aif1, aif2;
1321
1322 codec = dai->codec;
1323 wm8995 = snd_soc_codec_get_drvdata(codec);
1324
1325 aif1 = snd_soc_read(codec, WM8995_AIF1_CLOCKING_1)
1326 & WM8995_AIF1CLK_ENA;
1327
1328 aif2 = snd_soc_read(codec, WM8995_AIF2_CLOCKING_1)
1329 & WM8995_AIF2CLK_ENA;
1330
1331 switch (id) {
1332 case WM8995_FLL1:
1333 reg_offset = 0;
1334 id = 0;
1335 break;
1336 case WM8995_FLL2:
1337 reg_offset = 0x20;
1338 id = 1;
1339 break;
1340 default:
1341 return -EINVAL;
1342 }
1343
1344 switch (src) {
1345 case 0:
1346 /* Allow no source specification when stopping */
1347 if (freq_out)
1348 return -EINVAL;
1349 break;
1350 case WM8995_FLL_SRC_MCLK1:
1351 case WM8995_FLL_SRC_MCLK2:
1352 case WM8995_FLL_SRC_LRCLK:
1353 case WM8995_FLL_SRC_BCLK:
1354 break;
1355 default:
1356 return -EINVAL;
1357 }
1358
1359 /* Are we changing anything? */
1360 if (wm8995->fll[id].src == src &&
1361 wm8995->fll[id].in == freq_in && wm8995->fll[id].out == freq_out)
1362 return 0;
1363
1364 /* If we're stopping the FLL redo the old config - no
1365 * registers will actually be written but we avoid GCC flow
1366 * analysis bugs spewing warnings.
1367 */
1368 if (freq_out)
1369 ret = wm8995_get_fll_config(&fll, freq_in, freq_out);
1370 else
1371 ret = wm8995_get_fll_config(&fll, wm8995->fll[id].in,
1372 wm8995->fll[id].out);
1373 if (ret < 0)
1374 return ret;
1375
1376 /* Gate the AIF clocks while we reclock */
1377 snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1,
1378 WM8995_AIF1CLK_ENA_MASK, 0);
1379 snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1,
1380 WM8995_AIF2CLK_ENA_MASK, 0);
1381
1382 /* We always need to disable the FLL while reconfiguring */
1383 snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset,
1384 WM8995_FLL1_ENA_MASK, 0);
1385
1386 reg = (fll.outdiv << WM8995_FLL1_OUTDIV_SHIFT) |
1387 (fll.fll_fratio << WM8995_FLL1_FRATIO_SHIFT);
1388 snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_2 + reg_offset,
1389 WM8995_FLL1_OUTDIV_MASK |
1390 WM8995_FLL1_FRATIO_MASK, reg);
1391
1392 snd_soc_write(codec, WM8995_FLL1_CONTROL_3 + reg_offset, fll.k);
1393
1394 snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_4 + reg_offset,
1395 WM8995_FLL1_N_MASK,
1396 fll.n << WM8995_FLL1_N_SHIFT);
1397
1398 snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_5 + reg_offset,
1399 WM8995_FLL1_REFCLK_DIV_MASK |
1400 WM8995_FLL1_REFCLK_SRC_MASK,
1401 (fll.clk_ref_div << WM8995_FLL1_REFCLK_DIV_SHIFT) |
1402 (src - 1));
1403
1404 if (freq_out)
1405 snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset,
1406 WM8995_FLL1_ENA_MASK, WM8995_FLL1_ENA);
1407
1408 wm8995->fll[id].in = freq_in;
1409 wm8995->fll[id].out = freq_out;
1410 wm8995->fll[id].src = src;
1411
1412 /* Enable any gated AIF clocks */
1413 snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1,
1414 WM8995_AIF1CLK_ENA_MASK, aif1);
1415 snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1,
1416 WM8995_AIF2CLK_ENA_MASK, aif2);
1417
1418 configure_clock(codec);
1419
1420 return 0;
1421}
1422
1423static int wm8995_set_dai_sysclk(struct snd_soc_dai *dai,
1424 int clk_id, unsigned int freq, int dir)
1425{
1426 struct snd_soc_codec *codec;
1427 struct wm8995_priv *wm8995;
1428
1429 codec = dai->codec;
1430 wm8995 = snd_soc_codec_get_drvdata(codec);
1431
1432 switch (dai->id) {
1433 case 0:
1434 case 1:
1435 break;
1436 default:
1437 /* AIF3 shares clocking with AIF1/2 */
1438 return -EINVAL;
1439 }
1440
1441 switch (clk_id) {
1442 case WM8995_SYSCLK_MCLK1:
1443 wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1;
1444 wm8995->mclk[0] = freq;
1445 dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n",
1446 dai->id + 1, freq);
1447 break;
1448 case WM8995_SYSCLK_MCLK2:
1449 wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1;
1450 wm8995->mclk[1] = freq;
1451 dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n",
1452 dai->id + 1, freq);
1453 break;
1454 case WM8995_SYSCLK_FLL1:
1455 wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL1;
1456 dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id + 1);
1457 break;
1458 case WM8995_SYSCLK_FLL2:
1459 wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL2;
1460 dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id + 1);
1461 break;
1462 case WM8995_SYSCLK_OPCLK:
1463 default:
1464 dev_err(dai->dev, "Unknown clock source %d\n", clk_id);
1465 return -EINVAL;
1466 }
1467
1468 configure_clock(codec);
1469
1470 return 0;
1471}
1472
1473static int wm8995_set_bias_level(struct snd_soc_codec *codec,
1474 enum snd_soc_bias_level level)
1475{
1476 struct wm8995_priv *wm8995;
1477 int ret;
1478
1479 wm8995 = snd_soc_codec_get_drvdata(codec);
1480 switch (level) {
1481 case SND_SOC_BIAS_ON:
1482 case SND_SOC_BIAS_PREPARE:
1483 break;
1484 case SND_SOC_BIAS_STANDBY:
1485 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1486 ret = snd_soc_cache_sync(codec);
1487 if (ret) {
1488 dev_err(codec->dev,
1489 "Failed to sync cache: %d\n", ret);
1490 return ret;
1491 }
1492
1493 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
1494 WM8995_BG_ENA_MASK, WM8995_BG_ENA);
1495
1496 }
1497 break;
1498 case SND_SOC_BIAS_OFF:
1499 snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1,
1500 WM8995_BG_ENA_MASK, 0);
1501 break;
1502 }
1503
1504 codec->dapm.bias_level = level;
1505 return 0;
1506}
1507
1508#ifdef CONFIG_PM
1509static int wm8995_suspend(struct snd_soc_codec *codec, pm_message_t state)
1510{
1511 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
1512 return 0;
1513}
1514
1515static int wm8995_resume(struct snd_soc_codec *codec)
1516{
1517 wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1518 return 0;
1519}
1520#else
1521#define wm8995_suspend NULL
1522#define wm8995_resume NULL
1523#endif
1524
1525static int wm8995_remove(struct snd_soc_codec *codec)
1526{
1527 struct wm8995_priv *wm8995;
1528 struct i2c_client *i2c;
1529
1530 i2c = container_of(codec->dev, struct i2c_client, dev);
1531 wm8995 = snd_soc_codec_get_drvdata(codec);
1532 wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF);
1533 return 0;
1534}
1535
1536static int wm8995_probe(struct snd_soc_codec *codec)
1537{
1538 struct wm8995_priv *wm8995;
1539 int ret;
1540
1541 codec->dapm.idle_bias_off = 1;
1542 wm8995 = snd_soc_codec_get_drvdata(codec);
1543
1544 ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type);
1545 if (ret < 0) {
1546 dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret);
1547 return ret;
1548 }
1549
1550 ret = snd_soc_read(codec, WM8995_SOFTWARE_RESET);
1551 if (ret < 0) {
1552 dev_err(codec->dev, "Failed to read device ID: %d\n", ret);
1553 return ret;
1554 }
1555
1556 if (ret != 0x8995) {
1557 dev_err(codec->dev, "Invalid device ID: %#x\n", ret);
1558 return -EINVAL;
1559 }
1560
1561 ret = snd_soc_write(codec, WM8995_SOFTWARE_RESET, 0);
1562 if (ret < 0) {
1563 dev_err(codec->dev, "Failed to issue reset: %d\n", ret);
1564 return ret;
1565 }
1566
1567 wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1568
1569 /* Latch volume updates (right only; we always do left then right). */
1570 snd_soc_update_bits(codec, WM8995_AIF1_DAC1_RIGHT_VOLUME,
1571 WM8995_AIF1DAC1_VU_MASK, WM8995_AIF1DAC1_VU);
1572 snd_soc_update_bits(codec, WM8995_AIF1_DAC2_RIGHT_VOLUME,
1573 WM8995_AIF1DAC2_VU_MASK, WM8995_AIF1DAC2_VU);
1574 snd_soc_update_bits(codec, WM8995_AIF2_DAC_RIGHT_VOLUME,
1575 WM8995_AIF2DAC_VU_MASK, WM8995_AIF2DAC_VU);
1576 snd_soc_update_bits(codec, WM8995_AIF1_ADC1_RIGHT_VOLUME,
1577 WM8995_AIF1ADC1_VU_MASK, WM8995_AIF1ADC1_VU);
1578 snd_soc_update_bits(codec, WM8995_AIF1_ADC2_RIGHT_VOLUME,
1579 WM8995_AIF1ADC2_VU_MASK, WM8995_AIF1ADC2_VU);
1580 snd_soc_update_bits(codec, WM8995_AIF2_ADC_RIGHT_VOLUME,
1581 WM8995_AIF2ADC_VU_MASK, WM8995_AIF1ADC2_VU);
1582 snd_soc_update_bits(codec, WM8995_DAC1_RIGHT_VOLUME,
1583 WM8995_DAC1_VU_MASK, WM8995_DAC1_VU);
1584 snd_soc_update_bits(codec, WM8995_DAC2_RIGHT_VOLUME,
1585 WM8995_DAC2_VU_MASK, WM8995_DAC2_VU);
1586 snd_soc_update_bits(codec, WM8995_RIGHT_LINE_INPUT_1_VOLUME,
1587 WM8995_IN1_VU_MASK, WM8995_IN1_VU);
1588
1589 wm8995_update_class_w(codec);
1590
1591 snd_soc_add_controls(codec, wm8995_snd_controls,
1592 ARRAY_SIZE(wm8995_snd_controls));
1593 snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets,
1594 ARRAY_SIZE(wm8995_dapm_widgets));
1595 snd_soc_dapm_add_routes(&codec->dapm, wm8995_intercon,
1596 ARRAY_SIZE(wm8995_intercon));
1597
1598 return 0;
1599}
1600
1601#define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
1602 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1603
1604static struct snd_soc_dai_ops wm8995_aif1_dai_ops = {
1605 .set_sysclk = wm8995_set_dai_sysclk,
1606 .set_fmt = wm8995_set_dai_fmt,
1607 .hw_params = wm8995_hw_params,
1608 .digital_mute = wm8995_aif_mute,
1609 .set_pll = wm8995_set_fll,
1610 .set_tristate = wm8995_set_tristate,
1611};
1612
1613static struct snd_soc_dai_ops wm8995_aif2_dai_ops = {
1614 .set_sysclk = wm8995_set_dai_sysclk,
1615 .set_fmt = wm8995_set_dai_fmt,
1616 .hw_params = wm8995_hw_params,
1617 .digital_mute = wm8995_aif_mute,
1618 .set_pll = wm8995_set_fll,
1619 .set_tristate = wm8995_set_tristate,
1620};
1621
1622static struct snd_soc_dai_ops wm8995_aif3_dai_ops = {
1623 .set_tristate = wm8995_set_tristate,
1624};
1625
1626static struct snd_soc_dai_driver wm8995_dai[] = {
1627 {
1628 .name = "wm8995-aif1",
1629 .playback = {
1630 .stream_name = "AIF1 Playback",
1631 .channels_min = 2,
1632 .channels_max = 2,
1633 .rates = SNDRV_PCM_RATE_8000_96000,
1634 .formats = WM8995_FORMATS
1635 },
1636 .capture = {
1637 .stream_name = "AIF1 Capture",
1638 .channels_min = 2,
1639 .channels_max = 2,
1640 .rates = SNDRV_PCM_RATE_8000_48000,
1641 .formats = WM8995_FORMATS
1642 },
1643 .ops = &wm8995_aif1_dai_ops
1644 },
1645 {
1646 .name = "wm8995-aif2",
1647 .playback = {
1648 .stream_name = "AIF2 Playback",
1649 .channels_min = 2,
1650 .channels_max = 2,
1651 .rates = SNDRV_PCM_RATE_8000_96000,
1652 .formats = WM8995_FORMATS
1653 },
1654 .capture = {
1655 .stream_name = "AIF2 Capture",
1656 .channels_min = 2,
1657 .channels_max = 2,
1658 .rates = SNDRV_PCM_RATE_8000_48000,
1659 .formats = WM8995_FORMATS
1660 },
1661 .ops = &wm8995_aif2_dai_ops
1662 },
1663 {
1664 .name = "wm8995-aif3",
1665 .playback = {
1666 .stream_name = "AIF3 Playback",
1667 .channels_min = 2,
1668 .channels_max = 2,
1669 .rates = SNDRV_PCM_RATE_8000_96000,
1670 .formats = WM8995_FORMATS
1671 },
1672 .capture = {
1673 .stream_name = "AIF3 Capture",
1674 .channels_min = 2,
1675 .channels_max = 2,
1676 .rates = SNDRV_PCM_RATE_8000_48000,
1677 .formats = WM8995_FORMATS
1678 },
1679 .ops = &wm8995_aif3_dai_ops
1680 }
1681};
1682
1683static struct snd_soc_codec_driver soc_codec_dev_wm8995 = {
1684 .probe = wm8995_probe,
1685 .remove = wm8995_remove,
1686 .suspend = wm8995_suspend,
1687 .resume = wm8995_resume,
1688 .set_bias_level = wm8995_set_bias_level,
1689 .reg_cache_size = ARRAY_SIZE(wm8995_reg_defs),
1690 .reg_word_size = sizeof(u16),
1691 .reg_cache_default = wm8995_reg_defs,
1692 .volatile_register = wm8995_volatile,
1693 .compress_type = SND_SOC_RBTREE_COMPRESSION
1694};
1695
1696#if defined(CONFIG_SPI_MASTER)
1697static int __devinit wm8995_spi_probe(struct spi_device *spi)
1698{
1699 struct wm8995_priv *wm8995;
1700 int ret;
1701
1702 wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL);
1703 if (!wm8995)
1704 return -ENOMEM;
1705
1706 wm8995->control_type = SND_SOC_SPI;
1707 spi_set_drvdata(spi, wm8995);
1708
1709 ret = snd_soc_register_codec(&spi->dev,
1710 &soc_codec_dev_wm8995, wm8995_dai,
1711 ARRAY_SIZE(wm8995_dai));
1712 if (ret < 0)
1713 kfree(wm8995);
1714 return ret;
1715}
1716
1717static int __devexit wm8995_spi_remove(struct spi_device *spi)
1718{
1719 snd_soc_unregister_codec(&spi->dev);
1720 kfree(spi_get_drvdata(spi));
1721 return 0;
1722}
1723
1724static struct spi_driver wm8995_spi_driver = {
1725 .driver = {
1726 .name = "wm8995",
1727 .owner = THIS_MODULE,
1728 },
1729 .probe = wm8995_spi_probe,
1730 .remove = __devexit_p(wm8995_spi_remove)
1731};
1732#endif
1733
1734#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1735static __devinit int wm8995_i2c_probe(struct i2c_client *i2c,
1736 const struct i2c_device_id *id)
1737{
1738 struct wm8995_priv *wm8995;
1739 int ret;
1740
1741 wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL);
1742 if (!wm8995)
1743 return -ENOMEM;
1744
1745 wm8995->control_type = SND_SOC_I2C;
1746 i2c_set_clientdata(i2c, wm8995);
1747
1748 ret = snd_soc_register_codec(&i2c->dev,
1749 &soc_codec_dev_wm8995, wm8995_dai,
1750 ARRAY_SIZE(wm8995_dai));
1751 if (ret < 0)
1752 kfree(wm8995);
1753 return ret;
1754}
1755
1756static __devexit int wm8995_i2c_remove(struct i2c_client *client)
1757{
1758 snd_soc_unregister_codec(&client->dev);
1759 kfree(i2c_get_clientdata(client));
1760 return 0;
1761}
1762
1763static const struct i2c_device_id wm8995_i2c_id[] = {
1764 {"wm8995", 0},
1765 {}
1766};
1767
1768MODULE_DEVICE_TABLE(i2c, wm8995_i2c_id);
1769
1770static struct i2c_driver wm8995_i2c_driver = {
1771 .driver = {
1772 .name = "wm8995",
1773 .owner = THIS_MODULE,
1774 },
1775 .probe = wm8995_i2c_probe,
1776 .remove = __devexit_p(wm8995_i2c_remove),
1777 .id_table = wm8995_i2c_id
1778};
1779#endif
1780
1781static int __init wm8995_modinit(void)
1782{
1783 int ret = 0;
1784
1785#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1786 ret = i2c_add_driver(&wm8995_i2c_driver);
1787 if (ret) {
1788 printk(KERN_ERR "Failed to register wm8995 I2C driver: %d\n",
1789 ret);
1790 }
1791#endif
1792#if defined(CONFIG_SPI_MASTER)
1793 ret = spi_register_driver(&wm8995_spi_driver);
1794 if (ret) {
1795 printk(KERN_ERR "Failed to register wm8995 SPI driver: %d\n",
1796 ret);
1797 }
1798#endif
1799 return ret;
1800}
1801
1802module_init(wm8995_modinit);
1803
1804static void __exit wm8995_exit(void)
1805{
1806#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
1807 i2c_del_driver(&wm8995_i2c_driver);
1808#endif
1809#if defined(CONFIG_SPI_MASTER)
1810 spi_unregister_driver(&wm8995_spi_driver);
1811#endif
1812}
1813
1814module_exit(wm8995_exit);
1815
1816MODULE_DESCRIPTION("ASoC WM8995 driver");
1817MODULE_AUTHOR("Dimitris Papastamos <dp@opensource.wolfsonmicro.com>");
1818MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/wm8995.h b/sound/soc/codecs/wm8995.h
new file mode 100644
index 000000000000..5642121c4977
--- /dev/null
+++ b/sound/soc/codecs/wm8995.h
@@ -0,0 +1,4269 @@
1/*
2 * wm8995.h -- WM8995 ALSA SoC Audio driver
3 *
4 * Copyright 2010 Wolfson Microelectronics plc
5 *
6 * Author: Dimitris Papastamos <dp@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 _WM8995_H
14#define _WM8995_H
15
16#include <asm/types.h>
17
18/*
19 * Register values.
20 */
21#define WM8995_SOFTWARE_RESET 0x00
22#define WM8995_POWER_MANAGEMENT_1 0x01
23#define WM8995_POWER_MANAGEMENT_2 0x02
24#define WM8995_POWER_MANAGEMENT_3 0x03
25#define WM8995_POWER_MANAGEMENT_4 0x04
26#define WM8995_POWER_MANAGEMENT_5 0x05
27#define WM8995_LEFT_LINE_INPUT_1_VOLUME 0x10
28#define WM8995_RIGHT_LINE_INPUT_1_VOLUME 0x11
29#define WM8995_LEFT_LINE_INPUT_CONTROL 0x12
30#define WM8995_DAC1_LEFT_VOLUME 0x18
31#define WM8995_DAC1_RIGHT_VOLUME 0x19
32#define WM8995_DAC2_LEFT_VOLUME 0x1A
33#define WM8995_DAC2_RIGHT_VOLUME 0x1B
34#define WM8995_OUTPUT_VOLUME_ZC_1 0x1C
35#define WM8995_MICBIAS_1 0x20
36#define WM8995_MICBIAS_2 0x21
37#define WM8995_LDO_1 0x28
38#define WM8995_LDO_2 0x29
39#define WM8995_ACCESSORY_DETECT_MODE1 0x30
40#define WM8995_ACCESSORY_DETECT_MODE2 0x31
41#define WM8995_HEADPHONE_DETECT1 0x34
42#define WM8995_HEADPHONE_DETECT2 0x35
43#define WM8995_MIC_DETECT_1 0x38
44#define WM8995_MIC_DETECT_2 0x39
45#define WM8995_CHARGE_PUMP_1 0x40
46#define WM8995_CLASS_W_1 0x45
47#define WM8995_DC_SERVO_1 0x50
48#define WM8995_DC_SERVO_2 0x51
49#define WM8995_DC_SERVO_3 0x52
50#define WM8995_DC_SERVO_5 0x54
51#define WM8995_DC_SERVO_6 0x55
52#define WM8995_DC_SERVO_7 0x56
53#define WM8995_DC_SERVO_READBACK_0 0x57
54#define WM8995_ANALOGUE_HP_1 0x60
55#define WM8995_ANALOGUE_HP_2 0x61
56#define WM8995_CHIP_REVISION 0x100
57#define WM8995_CONTROL_INTERFACE_1 0x101
58#define WM8995_CONTROL_INTERFACE_2 0x102
59#define WM8995_WRITE_SEQUENCER_CTRL_1 0x110
60#define WM8995_WRITE_SEQUENCER_CTRL_2 0x111
61#define WM8995_AIF1_CLOCKING_1 0x200
62#define WM8995_AIF1_CLOCKING_2 0x201
63#define WM8995_AIF2_CLOCKING_1 0x204
64#define WM8995_AIF2_CLOCKING_2 0x205
65#define WM8995_CLOCKING_1 0x208
66#define WM8995_CLOCKING_2 0x209
67#define WM8995_AIF1_RATE 0x210
68#define WM8995_AIF2_RATE 0x211
69#define WM8995_RATE_STATUS 0x212
70#define WM8995_FLL1_CONTROL_1 0x220
71#define WM8995_FLL1_CONTROL_2 0x221
72#define WM8995_FLL1_CONTROL_3 0x222
73#define WM8995_FLL1_CONTROL_4 0x223
74#define WM8995_FLL1_CONTROL_5 0x224
75#define WM8995_FLL2_CONTROL_1 0x240
76#define WM8995_FLL2_CONTROL_2 0x241
77#define WM8995_FLL2_CONTROL_3 0x242
78#define WM8995_FLL2_CONTROL_4 0x243
79#define WM8995_FLL2_CONTROL_5 0x244
80#define WM8995_AIF1_CONTROL_1 0x300
81#define WM8995_AIF1_CONTROL_2 0x301
82#define WM8995_AIF1_MASTER_SLAVE 0x302
83#define WM8995_AIF1_BCLK 0x303
84#define WM8995_AIF1ADC_LRCLK 0x304
85#define WM8995_AIF1DAC_LRCLK 0x305
86#define WM8995_AIF1DAC_DATA 0x306
87#define WM8995_AIF1ADC_DATA 0x307
88#define WM8995_AIF2_CONTROL_1 0x310
89#define WM8995_AIF2_CONTROL_2 0x311
90#define WM8995_AIF2_MASTER_SLAVE 0x312
91#define WM8995_AIF2_BCLK 0x313
92#define WM8995_AIF2ADC_LRCLK 0x314
93#define WM8995_AIF2DAC_LRCLK 0x315
94#define WM8995_AIF2DAC_DATA 0x316
95#define WM8995_AIF2ADC_DATA 0x317
96#define WM8995_AIF1_ADC1_LEFT_VOLUME 0x400
97#define WM8995_AIF1_ADC1_RIGHT_VOLUME 0x401
98#define WM8995_AIF1_DAC1_LEFT_VOLUME 0x402
99#define WM8995_AIF1_DAC1_RIGHT_VOLUME 0x403
100#define WM8995_AIF1_ADC2_LEFT_VOLUME 0x404
101#define WM8995_AIF1_ADC2_RIGHT_VOLUME 0x405
102#define WM8995_AIF1_DAC2_LEFT_VOLUME 0x406
103#define WM8995_AIF1_DAC2_RIGHT_VOLUME 0x407
104#define WM8995_AIF1_ADC1_FILTERS 0x410
105#define WM8995_AIF1_ADC2_FILTERS 0x411
106#define WM8995_AIF1_DAC1_FILTERS_1 0x420
107#define WM8995_AIF1_DAC1_FILTERS_2 0x421
108#define WM8995_AIF1_DAC2_FILTERS_1 0x422
109#define WM8995_AIF1_DAC2_FILTERS_2 0x423
110#define WM8995_AIF1_DRC1_1 0x440
111#define WM8995_AIF1_DRC1_2 0x441
112#define WM8995_AIF1_DRC1_3 0x442
113#define WM8995_AIF1_DRC1_4 0x443
114#define WM8995_AIF1_DRC1_5 0x444
115#define WM8995_AIF1_DRC2_1 0x450
116#define WM8995_AIF1_DRC2_2 0x451
117#define WM8995_AIF1_DRC2_3 0x452
118#define WM8995_AIF1_DRC2_4 0x453
119#define WM8995_AIF1_DRC2_5 0x454
120#define WM8995_AIF1_DAC1_EQ_GAINS_1 0x480
121#define WM8995_AIF1_DAC1_EQ_GAINS_2 0x481
122#define WM8995_AIF1_DAC1_EQ_BAND_1_A 0x482
123#define WM8995_AIF1_DAC1_EQ_BAND_1_B 0x483
124#define WM8995_AIF1_DAC1_EQ_BAND_1_PG 0x484
125#define WM8995_AIF1_DAC1_EQ_BAND_2_A 0x485
126#define WM8995_AIF1_DAC1_EQ_BAND_2_B 0x486
127#define WM8995_AIF1_DAC1_EQ_BAND_2_C 0x487
128#define WM8995_AIF1_DAC1_EQ_BAND_2_PG 0x488
129#define WM8995_AIF1_DAC1_EQ_BAND_3_A 0x489
130#define WM8995_AIF1_DAC1_EQ_BAND_3_B 0x48A
131#define WM8995_AIF1_DAC1_EQ_BAND_3_C 0x48B
132#define WM8995_AIF1_DAC1_EQ_BAND_3_PG 0x48C
133#define WM8995_AIF1_DAC1_EQ_BAND_4_A 0x48D
134#define WM8995_AIF1_DAC1_EQ_BAND_4_B 0x48E
135#define WM8995_AIF1_DAC1_EQ_BAND_4_C 0x48F
136#define WM8995_AIF1_DAC1_EQ_BAND_4_PG 0x490
137#define WM8995_AIF1_DAC1_EQ_BAND_5_A 0x491
138#define WM8995_AIF1_DAC1_EQ_BAND_5_B 0x492
139#define WM8995_AIF1_DAC1_EQ_BAND_5_PG 0x493
140#define WM8995_AIF1_DAC2_EQ_GAINS_1 0x4A0
141#define WM8995_AIF1_DAC2_EQ_GAINS_2 0x4A1
142#define WM8995_AIF1_DAC2_EQ_BAND_1_A 0x4A2
143#define WM8995_AIF1_DAC2_EQ_BAND_1_B 0x4A3
144#define WM8995_AIF1_DAC2_EQ_BAND_1_PG 0x4A4
145#define WM8995_AIF1_DAC2_EQ_BAND_2_A 0x4A5
146#define WM8995_AIF1_DAC2_EQ_BAND_2_B 0x4A6
147#define WM8995_AIF1_DAC2_EQ_BAND_2_C 0x4A7
148#define WM8995_AIF1_DAC2_EQ_BAND_2_PG 0x4A8
149#define WM8995_AIF1_DAC2_EQ_BAND_3_A 0x4A9
150#define WM8995_AIF1_DAC2_EQ_BAND_3_B 0x4AA
151#define WM8995_AIF1_DAC2_EQ_BAND_3_C 0x4AB
152#define WM8995_AIF1_DAC2_EQ_BAND_3_PG 0x4AC
153#define WM8995_AIF1_DAC2_EQ_BAND_4_A 0x4AD
154#define WM8995_AIF1_DAC2_EQ_BAND_4_B 0x4AE
155#define WM8995_AIF1_DAC2_EQ_BAND_4_C 0x4AF
156#define WM8995_AIF1_DAC2_EQ_BAND_4_PG 0x4B0
157#define WM8995_AIF1_DAC2_EQ_BAND_5_A 0x4B1
158#define WM8995_AIF1_DAC2_EQ_BAND_5_B 0x4B2
159#define WM8995_AIF1_DAC2_EQ_BAND_5_PG 0x4B3
160#define WM8995_AIF2_ADC_LEFT_VOLUME 0x500
161#define WM8995_AIF2_ADC_RIGHT_VOLUME 0x501
162#define WM8995_AIF2_DAC_LEFT_VOLUME 0x502
163#define WM8995_AIF2_DAC_RIGHT_VOLUME 0x503
164#define WM8995_AIF2_ADC_FILTERS 0x510
165#define WM8995_AIF2_DAC_FILTERS_1 0x520
166#define WM8995_AIF2_DAC_FILTERS_2 0x521
167#define WM8995_AIF2_DRC_1 0x540
168#define WM8995_AIF2_DRC_2 0x541
169#define WM8995_AIF2_DRC_3 0x542
170#define WM8995_AIF2_DRC_4 0x543
171#define WM8995_AIF2_DRC_5 0x544
172#define WM8995_AIF2_EQ_GAINS_1 0x580
173#define WM8995_AIF2_EQ_GAINS_2 0x581
174#define WM8995_AIF2_EQ_BAND_1_A 0x582
175#define WM8995_AIF2_EQ_BAND_1_B 0x583
176#define WM8995_AIF2_EQ_BAND_1_PG 0x584
177#define WM8995_AIF2_EQ_BAND_2_A 0x585
178#define WM8995_AIF2_EQ_BAND_2_B 0x586
179#define WM8995_AIF2_EQ_BAND_2_C 0x587
180#define WM8995_AIF2_EQ_BAND_2_PG 0x588
181#define WM8995_AIF2_EQ_BAND_3_A 0x589
182#define WM8995_AIF2_EQ_BAND_3_B 0x58A
183#define WM8995_AIF2_EQ_BAND_3_C 0x58B
184#define WM8995_AIF2_EQ_BAND_3_PG 0x58C
185#define WM8995_AIF2_EQ_BAND_4_A 0x58D
186#define WM8995_AIF2_EQ_BAND_4_B 0x58E
187#define WM8995_AIF2_EQ_BAND_4_C 0x58F
188#define WM8995_AIF2_EQ_BAND_4_PG 0x590
189#define WM8995_AIF2_EQ_BAND_5_A 0x591
190#define WM8995_AIF2_EQ_BAND_5_B 0x592
191#define WM8995_AIF2_EQ_BAND_5_PG 0x593
192#define WM8995_DAC1_MIXER_VOLUMES 0x600
193#define WM8995_DAC1_LEFT_MIXER_ROUTING 0x601
194#define WM8995_DAC1_RIGHT_MIXER_ROUTING 0x602
195#define WM8995_DAC2_MIXER_VOLUMES 0x603
196#define WM8995_DAC2_LEFT_MIXER_ROUTING 0x604
197#define WM8995_DAC2_RIGHT_MIXER_ROUTING 0x605
198#define WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING 0x606
199#define WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING 0x607
200#define WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING 0x608
201#define WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING 0x609
202#define WM8995_DAC_SOFTMUTE 0x610
203#define WM8995_OVERSAMPLING 0x620
204#define WM8995_SIDETONE 0x621
205#define WM8995_GPIO_1 0x700
206#define WM8995_GPIO_2 0x701
207#define WM8995_GPIO_3 0x702
208#define WM8995_GPIO_4 0x703
209#define WM8995_GPIO_5 0x704
210#define WM8995_GPIO_6 0x705
211#define WM8995_GPIO_7 0x706
212#define WM8995_GPIO_8 0x707
213#define WM8995_GPIO_9 0x708
214#define WM8995_GPIO_10 0x709
215#define WM8995_GPIO_11 0x70A
216#define WM8995_GPIO_12 0x70B
217#define WM8995_GPIO_13 0x70C
218#define WM8995_GPIO_14 0x70D
219#define WM8995_PULL_CONTROL_1 0x720
220#define WM8995_PULL_CONTROL_2 0x721
221#define WM8995_INTERRUPT_STATUS_1 0x730
222#define WM8995_INTERRUPT_STATUS_2 0x731
223#define WM8995_INTERRUPT_RAW_STATUS_2 0x732
224#define WM8995_INTERRUPT_STATUS_1_MASK 0x738
225#define WM8995_INTERRUPT_STATUS_2_MASK 0x739
226#define WM8995_INTERRUPT_CONTROL 0x740
227#define WM8995_LEFT_PDM_SPEAKER_1 0x800
228#define WM8995_RIGHT_PDM_SPEAKER_1 0x801
229#define WM8995_PDM_SPEAKER_1_MUTE_SEQUENCE 0x802
230#define WM8995_LEFT_PDM_SPEAKER_2 0x808
231#define WM8995_RIGHT_PDM_SPEAKER_2 0x809
232#define WM8995_PDM_SPEAKER_2_MUTE_SEQUENCE 0x80A
233#define WM8995_WRITE_SEQUENCER_0 0x3000
234#define WM8995_WRITE_SEQUENCER_1 0x3001
235#define WM8995_WRITE_SEQUENCER_2 0x3002
236#define WM8995_WRITE_SEQUENCER_3 0x3003
237#define WM8995_WRITE_SEQUENCER_4 0x3004
238#define WM8995_WRITE_SEQUENCER_5 0x3005
239#define WM8995_WRITE_SEQUENCER_6 0x3006
240#define WM8995_WRITE_SEQUENCER_7 0x3007
241#define WM8995_WRITE_SEQUENCER_8 0x3008
242#define WM8995_WRITE_SEQUENCER_9 0x3009
243#define WM8995_WRITE_SEQUENCER_10 0x300A
244#define WM8995_WRITE_SEQUENCER_11 0x300B
245#define WM8995_WRITE_SEQUENCER_12 0x300C
246#define WM8995_WRITE_SEQUENCER_13 0x300D
247#define WM8995_WRITE_SEQUENCER_14 0x300E
248#define WM8995_WRITE_SEQUENCER_15 0x300F
249#define WM8995_WRITE_SEQUENCER_16 0x3010
250#define WM8995_WRITE_SEQUENCER_17 0x3011
251#define WM8995_WRITE_SEQUENCER_18 0x3012
252#define WM8995_WRITE_SEQUENCER_19 0x3013
253#define WM8995_WRITE_SEQUENCER_20 0x3014
254#define WM8995_WRITE_SEQUENCER_21 0x3015
255#define WM8995_WRITE_SEQUENCER_22 0x3016
256#define WM8995_WRITE_SEQUENCER_23 0x3017
257#define WM8995_WRITE_SEQUENCER_24 0x3018
258#define WM8995_WRITE_SEQUENCER_25 0x3019
259#define WM8995_WRITE_SEQUENCER_26 0x301A
260#define WM8995_WRITE_SEQUENCER_27 0x301B
261#define WM8995_WRITE_SEQUENCER_28 0x301C
262#define WM8995_WRITE_SEQUENCER_29 0x301D
263#define WM8995_WRITE_SEQUENCER_30 0x301E
264#define WM8995_WRITE_SEQUENCER_31 0x301F
265#define WM8995_WRITE_SEQUENCER_32 0x3020
266#define WM8995_WRITE_SEQUENCER_33 0x3021
267#define WM8995_WRITE_SEQUENCER_34 0x3022
268#define WM8995_WRITE_SEQUENCER_35 0x3023
269#define WM8995_WRITE_SEQUENCER_36 0x3024
270#define WM8995_WRITE_SEQUENCER_37 0x3025
271#define WM8995_WRITE_SEQUENCER_38 0x3026
272#define WM8995_WRITE_SEQUENCER_39 0x3027
273#define WM8995_WRITE_SEQUENCER_40 0x3028
274#define WM8995_WRITE_SEQUENCER_41 0x3029
275#define WM8995_WRITE_SEQUENCER_42 0x302A
276#define WM8995_WRITE_SEQUENCER_43 0x302B
277#define WM8995_WRITE_SEQUENCER_44 0x302C
278#define WM8995_WRITE_SEQUENCER_45 0x302D
279#define WM8995_WRITE_SEQUENCER_46 0x302E
280#define WM8995_WRITE_SEQUENCER_47 0x302F
281#define WM8995_WRITE_SEQUENCER_48 0x3030
282#define WM8995_WRITE_SEQUENCER_49 0x3031
283#define WM8995_WRITE_SEQUENCER_50 0x3032
284#define WM8995_WRITE_SEQUENCER_51 0x3033
285#define WM8995_WRITE_SEQUENCER_52 0x3034
286#define WM8995_WRITE_SEQUENCER_53 0x3035
287#define WM8995_WRITE_SEQUENCER_54 0x3036
288#define WM8995_WRITE_SEQUENCER_55 0x3037
289#define WM8995_WRITE_SEQUENCER_56 0x3038
290#define WM8995_WRITE_SEQUENCER_57 0x3039
291#define WM8995_WRITE_SEQUENCER_58 0x303A
292#define WM8995_WRITE_SEQUENCER_59 0x303B
293#define WM8995_WRITE_SEQUENCER_60 0x303C
294#define WM8995_WRITE_SEQUENCER_61 0x303D
295#define WM8995_WRITE_SEQUENCER_62 0x303E
296#define WM8995_WRITE_SEQUENCER_63 0x303F
297#define WM8995_WRITE_SEQUENCER_64 0x3040
298#define WM8995_WRITE_SEQUENCER_65 0x3041
299#define WM8995_WRITE_SEQUENCER_66 0x3042
300#define WM8995_WRITE_SEQUENCER_67 0x3043
301#define WM8995_WRITE_SEQUENCER_68 0x3044
302#define WM8995_WRITE_SEQUENCER_69 0x3045
303#define WM8995_WRITE_SEQUENCER_70 0x3046
304#define WM8995_WRITE_SEQUENCER_71 0x3047
305#define WM8995_WRITE_SEQUENCER_72 0x3048
306#define WM8995_WRITE_SEQUENCER_73 0x3049
307#define WM8995_WRITE_SEQUENCER_74 0x304A
308#define WM8995_WRITE_SEQUENCER_75 0x304B
309#define WM8995_WRITE_SEQUENCER_76 0x304C
310#define WM8995_WRITE_SEQUENCER_77 0x304D
311#define WM8995_WRITE_SEQUENCER_78 0x304E
312#define WM8995_WRITE_SEQUENCER_79 0x304F
313#define WM8995_WRITE_SEQUENCER_80 0x3050
314#define WM8995_WRITE_SEQUENCER_81 0x3051
315#define WM8995_WRITE_SEQUENCER_82 0x3052
316#define WM8995_WRITE_SEQUENCER_83 0x3053
317#define WM8995_WRITE_SEQUENCER_84 0x3054
318#define WM8995_WRITE_SEQUENCER_85 0x3055
319#define WM8995_WRITE_SEQUENCER_86 0x3056
320#define WM8995_WRITE_SEQUENCER_87 0x3057
321#define WM8995_WRITE_SEQUENCER_88 0x3058
322#define WM8995_WRITE_SEQUENCER_89 0x3059
323#define WM8995_WRITE_SEQUENCER_90 0x305A
324#define WM8995_WRITE_SEQUENCER_91 0x305B
325#define WM8995_WRITE_SEQUENCER_92 0x305C
326#define WM8995_WRITE_SEQUENCER_93 0x305D
327#define WM8995_WRITE_SEQUENCER_94 0x305E
328#define WM8995_WRITE_SEQUENCER_95 0x305F
329#define WM8995_WRITE_SEQUENCER_96 0x3060
330#define WM8995_WRITE_SEQUENCER_97 0x3061
331#define WM8995_WRITE_SEQUENCER_98 0x3062
332#define WM8995_WRITE_SEQUENCER_99 0x3063
333#define WM8995_WRITE_SEQUENCER_100 0x3064
334#define WM8995_WRITE_SEQUENCER_101 0x3065
335#define WM8995_WRITE_SEQUENCER_102 0x3066
336#define WM8995_WRITE_SEQUENCER_103 0x3067
337#define WM8995_WRITE_SEQUENCER_104 0x3068
338#define WM8995_WRITE_SEQUENCER_105 0x3069
339#define WM8995_WRITE_SEQUENCER_106 0x306A
340#define WM8995_WRITE_SEQUENCER_107 0x306B
341#define WM8995_WRITE_SEQUENCER_108 0x306C
342#define WM8995_WRITE_SEQUENCER_109 0x306D
343#define WM8995_WRITE_SEQUENCER_110 0x306E
344#define WM8995_WRITE_SEQUENCER_111 0x306F
345#define WM8995_WRITE_SEQUENCER_112 0x3070
346#define WM8995_WRITE_SEQUENCER_113 0x3071
347#define WM8995_WRITE_SEQUENCER_114 0x3072
348#define WM8995_WRITE_SEQUENCER_115 0x3073
349#define WM8995_WRITE_SEQUENCER_116 0x3074
350#define WM8995_WRITE_SEQUENCER_117 0x3075
351#define WM8995_WRITE_SEQUENCER_118 0x3076
352#define WM8995_WRITE_SEQUENCER_119 0x3077
353#define WM8995_WRITE_SEQUENCER_120 0x3078
354#define WM8995_WRITE_SEQUENCER_121 0x3079
355#define WM8995_WRITE_SEQUENCER_122 0x307A
356#define WM8995_WRITE_SEQUENCER_123 0x307B
357#define WM8995_WRITE_SEQUENCER_124 0x307C
358#define WM8995_WRITE_SEQUENCER_125 0x307D
359#define WM8995_WRITE_SEQUENCER_126 0x307E
360#define WM8995_WRITE_SEQUENCER_127 0x307F
361#define WM8995_WRITE_SEQUENCER_128 0x3080
362#define WM8995_WRITE_SEQUENCER_129 0x3081
363#define WM8995_WRITE_SEQUENCER_130 0x3082
364#define WM8995_WRITE_SEQUENCER_131 0x3083
365#define WM8995_WRITE_SEQUENCER_132 0x3084
366#define WM8995_WRITE_SEQUENCER_133 0x3085
367#define WM8995_WRITE_SEQUENCER_134 0x3086
368#define WM8995_WRITE_SEQUENCER_135 0x3087
369#define WM8995_WRITE_SEQUENCER_136 0x3088
370#define WM8995_WRITE_SEQUENCER_137 0x3089
371#define WM8995_WRITE_SEQUENCER_138 0x308A
372#define WM8995_WRITE_SEQUENCER_139 0x308B
373#define WM8995_WRITE_SEQUENCER_140 0x308C
374#define WM8995_WRITE_SEQUENCER_141 0x308D
375#define WM8995_WRITE_SEQUENCER_142 0x308E
376#define WM8995_WRITE_SEQUENCER_143 0x308F
377#define WM8995_WRITE_SEQUENCER_144 0x3090
378#define WM8995_WRITE_SEQUENCER_145 0x3091
379#define WM8995_WRITE_SEQUENCER_146 0x3092
380#define WM8995_WRITE_SEQUENCER_147 0x3093
381#define WM8995_WRITE_SEQUENCER_148 0x3094
382#define WM8995_WRITE_SEQUENCER_149 0x3095
383#define WM8995_WRITE_SEQUENCER_150 0x3096
384#define WM8995_WRITE_SEQUENCER_151 0x3097
385#define WM8995_WRITE_SEQUENCER_152 0x3098
386#define WM8995_WRITE_SEQUENCER_153 0x3099
387#define WM8995_WRITE_SEQUENCER_154 0x309A
388#define WM8995_WRITE_SEQUENCER_155 0x309B
389#define WM8995_WRITE_SEQUENCER_156 0x309C
390#define WM8995_WRITE_SEQUENCER_157 0x309D
391#define WM8995_WRITE_SEQUENCER_158 0x309E
392#define WM8995_WRITE_SEQUENCER_159 0x309F
393#define WM8995_WRITE_SEQUENCER_160 0x30A0
394#define WM8995_WRITE_SEQUENCER_161 0x30A1
395#define WM8995_WRITE_SEQUENCER_162 0x30A2
396#define WM8995_WRITE_SEQUENCER_163 0x30A3
397#define WM8995_WRITE_SEQUENCER_164 0x30A4
398#define WM8995_WRITE_SEQUENCER_165 0x30A5
399#define WM8995_WRITE_SEQUENCER_166 0x30A6
400#define WM8995_WRITE_SEQUENCER_167 0x30A7
401#define WM8995_WRITE_SEQUENCER_168 0x30A8
402#define WM8995_WRITE_SEQUENCER_169 0x30A9
403#define WM8995_WRITE_SEQUENCER_170 0x30AA
404#define WM8995_WRITE_SEQUENCER_171 0x30AB
405#define WM8995_WRITE_SEQUENCER_172 0x30AC
406#define WM8995_WRITE_SEQUENCER_173 0x30AD
407#define WM8995_WRITE_SEQUENCER_174 0x30AE
408#define WM8995_WRITE_SEQUENCER_175 0x30AF
409#define WM8995_WRITE_SEQUENCER_176 0x30B0
410#define WM8995_WRITE_SEQUENCER_177 0x30B1
411#define WM8995_WRITE_SEQUENCER_178 0x30B2
412#define WM8995_WRITE_SEQUENCER_179 0x30B3
413#define WM8995_WRITE_SEQUENCER_180 0x30B4
414#define WM8995_WRITE_SEQUENCER_181 0x30B5
415#define WM8995_WRITE_SEQUENCER_182 0x30B6
416#define WM8995_WRITE_SEQUENCER_183 0x30B7
417#define WM8995_WRITE_SEQUENCER_184 0x30B8
418#define WM8995_WRITE_SEQUENCER_185 0x30B9
419#define WM8995_WRITE_SEQUENCER_186 0x30BA
420#define WM8995_WRITE_SEQUENCER_187 0x30BB
421#define WM8995_WRITE_SEQUENCER_188 0x30BC
422#define WM8995_WRITE_SEQUENCER_189 0x30BD
423#define WM8995_WRITE_SEQUENCER_190 0x30BE
424#define WM8995_WRITE_SEQUENCER_191 0x30BF
425#define WM8995_WRITE_SEQUENCER_192 0x30C0
426#define WM8995_WRITE_SEQUENCER_193 0x30C1
427#define WM8995_WRITE_SEQUENCER_194 0x30C2
428#define WM8995_WRITE_SEQUENCER_195 0x30C3
429#define WM8995_WRITE_SEQUENCER_196 0x30C4
430#define WM8995_WRITE_SEQUENCER_197 0x30C5
431#define WM8995_WRITE_SEQUENCER_198 0x30C6
432#define WM8995_WRITE_SEQUENCER_199 0x30C7
433#define WM8995_WRITE_SEQUENCER_200 0x30C8
434#define WM8995_WRITE_SEQUENCER_201 0x30C9
435#define WM8995_WRITE_SEQUENCER_202 0x30CA
436#define WM8995_WRITE_SEQUENCER_203 0x30CB
437#define WM8995_WRITE_SEQUENCER_204 0x30CC
438#define WM8995_WRITE_SEQUENCER_205 0x30CD
439#define WM8995_WRITE_SEQUENCER_206 0x30CE
440#define WM8995_WRITE_SEQUENCER_207 0x30CF
441#define WM8995_WRITE_SEQUENCER_208 0x30D0
442#define WM8995_WRITE_SEQUENCER_209 0x30D1
443#define WM8995_WRITE_SEQUENCER_210 0x30D2
444#define WM8995_WRITE_SEQUENCER_211 0x30D3
445#define WM8995_WRITE_SEQUENCER_212 0x30D4
446#define WM8995_WRITE_SEQUENCER_213 0x30D5
447#define WM8995_WRITE_SEQUENCER_214 0x30D6
448#define WM8995_WRITE_SEQUENCER_215 0x30D7
449#define WM8995_WRITE_SEQUENCER_216 0x30D8
450#define WM8995_WRITE_SEQUENCER_217 0x30D9
451#define WM8995_WRITE_SEQUENCER_218 0x30DA
452#define WM8995_WRITE_SEQUENCER_219 0x30DB
453#define WM8995_WRITE_SEQUENCER_220 0x30DC
454#define WM8995_WRITE_SEQUENCER_221 0x30DD
455#define WM8995_WRITE_SEQUENCER_222 0x30DE
456#define WM8995_WRITE_SEQUENCER_223 0x30DF
457#define WM8995_WRITE_SEQUENCER_224 0x30E0
458#define WM8995_WRITE_SEQUENCER_225 0x30E1
459#define WM8995_WRITE_SEQUENCER_226 0x30E2
460#define WM8995_WRITE_SEQUENCER_227 0x30E3
461#define WM8995_WRITE_SEQUENCER_228 0x30E4
462#define WM8995_WRITE_SEQUENCER_229 0x30E5
463#define WM8995_WRITE_SEQUENCER_230 0x30E6
464#define WM8995_WRITE_SEQUENCER_231 0x30E7
465#define WM8995_WRITE_SEQUENCER_232 0x30E8
466#define WM8995_WRITE_SEQUENCER_233 0x30E9
467#define WM8995_WRITE_SEQUENCER_234 0x30EA
468#define WM8995_WRITE_SEQUENCER_235 0x30EB
469#define WM8995_WRITE_SEQUENCER_236 0x30EC
470#define WM8995_WRITE_SEQUENCER_237 0x30ED
471#define WM8995_WRITE_SEQUENCER_238 0x30EE
472#define WM8995_WRITE_SEQUENCER_239 0x30EF
473#define WM8995_WRITE_SEQUENCER_240 0x30F0
474#define WM8995_WRITE_SEQUENCER_241 0x30F1
475#define WM8995_WRITE_SEQUENCER_242 0x30F2
476#define WM8995_WRITE_SEQUENCER_243 0x30F3
477#define WM8995_WRITE_SEQUENCER_244 0x30F4
478#define WM8995_WRITE_SEQUENCER_245 0x30F5
479#define WM8995_WRITE_SEQUENCER_246 0x30F6
480#define WM8995_WRITE_SEQUENCER_247 0x30F7
481#define WM8995_WRITE_SEQUENCER_248 0x30F8
482#define WM8995_WRITE_SEQUENCER_249 0x30F9
483#define WM8995_WRITE_SEQUENCER_250 0x30FA
484#define WM8995_WRITE_SEQUENCER_251 0x30FB
485#define WM8995_WRITE_SEQUENCER_252 0x30FC
486#define WM8995_WRITE_SEQUENCER_253 0x30FD
487#define WM8995_WRITE_SEQUENCER_254 0x30FE
488#define WM8995_WRITE_SEQUENCER_255 0x30FF
489#define WM8995_WRITE_SEQUENCER_256 0x3100
490#define WM8995_WRITE_SEQUENCER_257 0x3101
491#define WM8995_WRITE_SEQUENCER_258 0x3102
492#define WM8995_WRITE_SEQUENCER_259 0x3103
493#define WM8995_WRITE_SEQUENCER_260 0x3104
494#define WM8995_WRITE_SEQUENCER_261 0x3105
495#define WM8995_WRITE_SEQUENCER_262 0x3106
496#define WM8995_WRITE_SEQUENCER_263 0x3107
497#define WM8995_WRITE_SEQUENCER_264 0x3108
498#define WM8995_WRITE_SEQUENCER_265 0x3109
499#define WM8995_WRITE_SEQUENCER_266 0x310A
500#define WM8995_WRITE_SEQUENCER_267 0x310B
501#define WM8995_WRITE_SEQUENCER_268 0x310C
502#define WM8995_WRITE_SEQUENCER_269 0x310D
503#define WM8995_WRITE_SEQUENCER_270 0x310E
504#define WM8995_WRITE_SEQUENCER_271 0x310F
505#define WM8995_WRITE_SEQUENCER_272 0x3110
506#define WM8995_WRITE_SEQUENCER_273 0x3111
507#define WM8995_WRITE_SEQUENCER_274 0x3112
508#define WM8995_WRITE_SEQUENCER_275 0x3113
509#define WM8995_WRITE_SEQUENCER_276 0x3114
510#define WM8995_WRITE_SEQUENCER_277 0x3115
511#define WM8995_WRITE_SEQUENCER_278 0x3116
512#define WM8995_WRITE_SEQUENCER_279 0x3117
513#define WM8995_WRITE_SEQUENCER_280 0x3118
514#define WM8995_WRITE_SEQUENCER_281 0x3119
515#define WM8995_WRITE_SEQUENCER_282 0x311A
516#define WM8995_WRITE_SEQUENCER_283 0x311B
517#define WM8995_WRITE_SEQUENCER_284 0x311C
518#define WM8995_WRITE_SEQUENCER_285 0x311D
519#define WM8995_WRITE_SEQUENCER_286 0x311E
520#define WM8995_WRITE_SEQUENCER_287 0x311F
521#define WM8995_WRITE_SEQUENCER_288 0x3120
522#define WM8995_WRITE_SEQUENCER_289 0x3121
523#define WM8995_WRITE_SEQUENCER_290 0x3122
524#define WM8995_WRITE_SEQUENCER_291 0x3123
525#define WM8995_WRITE_SEQUENCER_292 0x3124
526#define WM8995_WRITE_SEQUENCER_293 0x3125
527#define WM8995_WRITE_SEQUENCER_294 0x3126
528#define WM8995_WRITE_SEQUENCER_295 0x3127
529#define WM8995_WRITE_SEQUENCER_296 0x3128
530#define WM8995_WRITE_SEQUENCER_297 0x3129
531#define WM8995_WRITE_SEQUENCER_298 0x312A
532#define WM8995_WRITE_SEQUENCER_299 0x312B
533#define WM8995_WRITE_SEQUENCER_300 0x312C
534#define WM8995_WRITE_SEQUENCER_301 0x312D
535#define WM8995_WRITE_SEQUENCER_302 0x312E
536#define WM8995_WRITE_SEQUENCER_303 0x312F
537#define WM8995_WRITE_SEQUENCER_304 0x3130
538#define WM8995_WRITE_SEQUENCER_305 0x3131
539#define WM8995_WRITE_SEQUENCER_306 0x3132
540#define WM8995_WRITE_SEQUENCER_307 0x3133
541#define WM8995_WRITE_SEQUENCER_308 0x3134
542#define WM8995_WRITE_SEQUENCER_309 0x3135
543#define WM8995_WRITE_SEQUENCER_310 0x3136
544#define WM8995_WRITE_SEQUENCER_311 0x3137
545#define WM8995_WRITE_SEQUENCER_312 0x3138
546#define WM8995_WRITE_SEQUENCER_313 0x3139
547#define WM8995_WRITE_SEQUENCER_314 0x313A
548#define WM8995_WRITE_SEQUENCER_315 0x313B
549#define WM8995_WRITE_SEQUENCER_316 0x313C
550#define WM8995_WRITE_SEQUENCER_317 0x313D
551#define WM8995_WRITE_SEQUENCER_318 0x313E
552#define WM8995_WRITE_SEQUENCER_319 0x313F
553#define WM8995_WRITE_SEQUENCER_320 0x3140
554#define WM8995_WRITE_SEQUENCER_321 0x3141
555#define WM8995_WRITE_SEQUENCER_322 0x3142
556#define WM8995_WRITE_SEQUENCER_323 0x3143
557#define WM8995_WRITE_SEQUENCER_324 0x3144
558#define WM8995_WRITE_SEQUENCER_325 0x3145
559#define WM8995_WRITE_SEQUENCER_326 0x3146
560#define WM8995_WRITE_SEQUENCER_327 0x3147
561#define WM8995_WRITE_SEQUENCER_328 0x3148
562#define WM8995_WRITE_SEQUENCER_329 0x3149
563#define WM8995_WRITE_SEQUENCER_330 0x314A
564#define WM8995_WRITE_SEQUENCER_331 0x314B
565#define WM8995_WRITE_SEQUENCER_332 0x314C
566#define WM8995_WRITE_SEQUENCER_333 0x314D
567#define WM8995_WRITE_SEQUENCER_334 0x314E
568#define WM8995_WRITE_SEQUENCER_335 0x314F
569#define WM8995_WRITE_SEQUENCER_336 0x3150
570#define WM8995_WRITE_SEQUENCER_337 0x3151
571#define WM8995_WRITE_SEQUENCER_338 0x3152
572#define WM8995_WRITE_SEQUENCER_339 0x3153
573#define WM8995_WRITE_SEQUENCER_340 0x3154
574#define WM8995_WRITE_SEQUENCER_341 0x3155
575#define WM8995_WRITE_SEQUENCER_342 0x3156
576#define WM8995_WRITE_SEQUENCER_343 0x3157
577#define WM8995_WRITE_SEQUENCER_344 0x3158
578#define WM8995_WRITE_SEQUENCER_345 0x3159
579#define WM8995_WRITE_SEQUENCER_346 0x315A
580#define WM8995_WRITE_SEQUENCER_347 0x315B
581#define WM8995_WRITE_SEQUENCER_348 0x315C
582#define WM8995_WRITE_SEQUENCER_349 0x315D
583#define WM8995_WRITE_SEQUENCER_350 0x315E
584#define WM8995_WRITE_SEQUENCER_351 0x315F
585#define WM8995_WRITE_SEQUENCER_352 0x3160
586#define WM8995_WRITE_SEQUENCER_353 0x3161
587#define WM8995_WRITE_SEQUENCER_354 0x3162
588#define WM8995_WRITE_SEQUENCER_355 0x3163
589#define WM8995_WRITE_SEQUENCER_356 0x3164
590#define WM8995_WRITE_SEQUENCER_357 0x3165
591#define WM8995_WRITE_SEQUENCER_358 0x3166
592#define WM8995_WRITE_SEQUENCER_359 0x3167
593#define WM8995_WRITE_SEQUENCER_360 0x3168
594#define WM8995_WRITE_SEQUENCER_361 0x3169
595#define WM8995_WRITE_SEQUENCER_362 0x316A
596#define WM8995_WRITE_SEQUENCER_363 0x316B
597#define WM8995_WRITE_SEQUENCER_364 0x316C
598#define WM8995_WRITE_SEQUENCER_365 0x316D
599#define WM8995_WRITE_SEQUENCER_366 0x316E
600#define WM8995_WRITE_SEQUENCER_367 0x316F
601#define WM8995_WRITE_SEQUENCER_368 0x3170
602#define WM8995_WRITE_SEQUENCER_369 0x3171
603#define WM8995_WRITE_SEQUENCER_370 0x3172
604#define WM8995_WRITE_SEQUENCER_371 0x3173
605#define WM8995_WRITE_SEQUENCER_372 0x3174
606#define WM8995_WRITE_SEQUENCER_373 0x3175
607#define WM8995_WRITE_SEQUENCER_374 0x3176
608#define WM8995_WRITE_SEQUENCER_375 0x3177
609#define WM8995_WRITE_SEQUENCER_376 0x3178
610#define WM8995_WRITE_SEQUENCER_377 0x3179
611#define WM8995_WRITE_SEQUENCER_378 0x317A
612#define WM8995_WRITE_SEQUENCER_379 0x317B
613#define WM8995_WRITE_SEQUENCER_380 0x317C
614#define WM8995_WRITE_SEQUENCER_381 0x317D
615#define WM8995_WRITE_SEQUENCER_382 0x317E
616#define WM8995_WRITE_SEQUENCER_383 0x317F
617#define WM8995_WRITE_SEQUENCER_384 0x3180
618#define WM8995_WRITE_SEQUENCER_385 0x3181
619#define WM8995_WRITE_SEQUENCER_386 0x3182
620#define WM8995_WRITE_SEQUENCER_387 0x3183
621#define WM8995_WRITE_SEQUENCER_388 0x3184
622#define WM8995_WRITE_SEQUENCER_389 0x3185
623#define WM8995_WRITE_SEQUENCER_390 0x3186
624#define WM8995_WRITE_SEQUENCER_391 0x3187
625#define WM8995_WRITE_SEQUENCER_392 0x3188
626#define WM8995_WRITE_SEQUENCER_393 0x3189
627#define WM8995_WRITE_SEQUENCER_394 0x318A
628#define WM8995_WRITE_SEQUENCER_395 0x318B
629#define WM8995_WRITE_SEQUENCER_396 0x318C
630#define WM8995_WRITE_SEQUENCER_397 0x318D
631#define WM8995_WRITE_SEQUENCER_398 0x318E
632#define WM8995_WRITE_SEQUENCER_399 0x318F
633#define WM8995_WRITE_SEQUENCER_400 0x3190
634#define WM8995_WRITE_SEQUENCER_401 0x3191
635#define WM8995_WRITE_SEQUENCER_402 0x3192
636#define WM8995_WRITE_SEQUENCER_403 0x3193
637#define WM8995_WRITE_SEQUENCER_404 0x3194
638#define WM8995_WRITE_SEQUENCER_405 0x3195
639#define WM8995_WRITE_SEQUENCER_406 0x3196
640#define WM8995_WRITE_SEQUENCER_407 0x3197
641#define WM8995_WRITE_SEQUENCER_408 0x3198
642#define WM8995_WRITE_SEQUENCER_409 0x3199
643#define WM8995_WRITE_SEQUENCER_410 0x319A
644#define WM8995_WRITE_SEQUENCER_411 0x319B
645#define WM8995_WRITE_SEQUENCER_412 0x319C
646#define WM8995_WRITE_SEQUENCER_413 0x319D
647#define WM8995_WRITE_SEQUENCER_414 0x319E
648#define WM8995_WRITE_SEQUENCER_415 0x319F
649#define WM8995_WRITE_SEQUENCER_416 0x31A0
650#define WM8995_WRITE_SEQUENCER_417 0x31A1
651#define WM8995_WRITE_SEQUENCER_418 0x31A2
652#define WM8995_WRITE_SEQUENCER_419 0x31A3
653#define WM8995_WRITE_SEQUENCER_420 0x31A4
654#define WM8995_WRITE_SEQUENCER_421 0x31A5
655#define WM8995_WRITE_SEQUENCER_422 0x31A6
656#define WM8995_WRITE_SEQUENCER_423 0x31A7
657#define WM8995_WRITE_SEQUENCER_424 0x31A8
658#define WM8995_WRITE_SEQUENCER_425 0x31A9
659#define WM8995_WRITE_SEQUENCER_426 0x31AA
660#define WM8995_WRITE_SEQUENCER_427 0x31AB
661#define WM8995_WRITE_SEQUENCER_428 0x31AC
662#define WM8995_WRITE_SEQUENCER_429 0x31AD
663#define WM8995_WRITE_SEQUENCER_430 0x31AE
664#define WM8995_WRITE_SEQUENCER_431 0x31AF
665#define WM8995_WRITE_SEQUENCER_432 0x31B0
666#define WM8995_WRITE_SEQUENCER_433 0x31B1
667#define WM8995_WRITE_SEQUENCER_434 0x31B2
668#define WM8995_WRITE_SEQUENCER_435 0x31B3
669#define WM8995_WRITE_SEQUENCER_436 0x31B4
670#define WM8995_WRITE_SEQUENCER_437 0x31B5
671#define WM8995_WRITE_SEQUENCER_438 0x31B6
672#define WM8995_WRITE_SEQUENCER_439 0x31B7
673#define WM8995_WRITE_SEQUENCER_440 0x31B8
674#define WM8995_WRITE_SEQUENCER_441 0x31B9
675#define WM8995_WRITE_SEQUENCER_442 0x31BA
676#define WM8995_WRITE_SEQUENCER_443 0x31BB
677#define WM8995_WRITE_SEQUENCER_444 0x31BC
678#define WM8995_WRITE_SEQUENCER_445 0x31BD
679#define WM8995_WRITE_SEQUENCER_446 0x31BE
680#define WM8995_WRITE_SEQUENCER_447 0x31BF
681#define WM8995_WRITE_SEQUENCER_448 0x31C0
682#define WM8995_WRITE_SEQUENCER_449 0x31C1
683#define WM8995_WRITE_SEQUENCER_450 0x31C2
684#define WM8995_WRITE_SEQUENCER_451 0x31C3
685#define WM8995_WRITE_SEQUENCER_452 0x31C4
686#define WM8995_WRITE_SEQUENCER_453 0x31C5
687#define WM8995_WRITE_SEQUENCER_454 0x31C6
688#define WM8995_WRITE_SEQUENCER_455 0x31C7
689#define WM8995_WRITE_SEQUENCER_456 0x31C8
690#define WM8995_WRITE_SEQUENCER_457 0x31C9
691#define WM8995_WRITE_SEQUENCER_458 0x31CA
692#define WM8995_WRITE_SEQUENCER_459 0x31CB
693#define WM8995_WRITE_SEQUENCER_460 0x31CC
694#define WM8995_WRITE_SEQUENCER_461 0x31CD
695#define WM8995_WRITE_SEQUENCER_462 0x31CE
696#define WM8995_WRITE_SEQUENCER_463 0x31CF
697#define WM8995_WRITE_SEQUENCER_464 0x31D0
698#define WM8995_WRITE_SEQUENCER_465 0x31D1
699#define WM8995_WRITE_SEQUENCER_466 0x31D2
700#define WM8995_WRITE_SEQUENCER_467 0x31D3
701#define WM8995_WRITE_SEQUENCER_468 0x31D4
702#define WM8995_WRITE_SEQUENCER_469 0x31D5
703#define WM8995_WRITE_SEQUENCER_470 0x31D6
704#define WM8995_WRITE_SEQUENCER_471 0x31D7
705#define WM8995_WRITE_SEQUENCER_472 0x31D8
706#define WM8995_WRITE_SEQUENCER_473 0x31D9
707#define WM8995_WRITE_SEQUENCER_474 0x31DA
708#define WM8995_WRITE_SEQUENCER_475 0x31DB
709#define WM8995_WRITE_SEQUENCER_476 0x31DC
710#define WM8995_WRITE_SEQUENCER_477 0x31DD
711#define WM8995_WRITE_SEQUENCER_478 0x31DE
712#define WM8995_WRITE_SEQUENCER_479 0x31DF
713#define WM8995_WRITE_SEQUENCER_480 0x31E0
714#define WM8995_WRITE_SEQUENCER_481 0x31E1
715#define WM8995_WRITE_SEQUENCER_482 0x31E2
716#define WM8995_WRITE_SEQUENCER_483 0x31E3
717#define WM8995_WRITE_SEQUENCER_484 0x31E4
718#define WM8995_WRITE_SEQUENCER_485 0x31E5
719#define WM8995_WRITE_SEQUENCER_486 0x31E6
720#define WM8995_WRITE_SEQUENCER_487 0x31E7
721#define WM8995_WRITE_SEQUENCER_488 0x31E8
722#define WM8995_WRITE_SEQUENCER_489 0x31E9
723#define WM8995_WRITE_SEQUENCER_490 0x31EA
724#define WM8995_WRITE_SEQUENCER_491 0x31EB
725#define WM8995_WRITE_SEQUENCER_492 0x31EC
726#define WM8995_WRITE_SEQUENCER_493 0x31ED
727#define WM8995_WRITE_SEQUENCER_494 0x31EE
728#define WM8995_WRITE_SEQUENCER_495 0x31EF
729#define WM8995_WRITE_SEQUENCER_496 0x31F0
730#define WM8995_WRITE_SEQUENCER_497 0x31F1
731#define WM8995_WRITE_SEQUENCER_498 0x31F2
732#define WM8995_WRITE_SEQUENCER_499 0x31F3
733#define WM8995_WRITE_SEQUENCER_500 0x31F4
734#define WM8995_WRITE_SEQUENCER_501 0x31F5
735#define WM8995_WRITE_SEQUENCER_502 0x31F6
736#define WM8995_WRITE_SEQUENCER_503 0x31F7
737#define WM8995_WRITE_SEQUENCER_504 0x31F8
738#define WM8995_WRITE_SEQUENCER_505 0x31F9
739#define WM8995_WRITE_SEQUENCER_506 0x31FA
740#define WM8995_WRITE_SEQUENCER_507 0x31FB
741#define WM8995_WRITE_SEQUENCER_508 0x31FC
742#define WM8995_WRITE_SEQUENCER_509 0x31FD
743#define WM8995_WRITE_SEQUENCER_510 0x31FE
744#define WM8995_WRITE_SEQUENCER_511 0x31FF
745
746#define WM8995_REGISTER_COUNT 725
747#define WM8995_MAX_REGISTER 0x31FF
748
749#define WM8995_MAX_CACHED_REGISTER WM8995_MAX_REGISTER
750
751/*
752 * Field Definitions.
753 */
754
755/*
756 * R0 (0x00) - Software Reset
757 */
758#define WM8995_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */
759#define WM8995_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */
760#define WM8995_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */
761
762/*
763 * R1 (0x01) - Power Management (1)
764 */
765#define WM8995_MICB2_ENA 0x0200 /* MICB2_ENA */
766#define WM8995_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */
767#define WM8995_MICB2_ENA_SHIFT 9 /* MICB2_ENA */
768#define WM8995_MICB2_ENA_WIDTH 1 /* MICB2_ENA */
769#define WM8995_MICB1_ENA 0x0100 /* MICB1_ENA */
770#define WM8995_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */
771#define WM8995_MICB1_ENA_SHIFT 8 /* MICB1_ENA */
772#define WM8995_MICB1_ENA_WIDTH 1 /* MICB1_ENA */
773#define WM8995_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */
774#define WM8995_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */
775#define WM8995_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */
776#define WM8995_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */
777#define WM8995_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */
778#define WM8995_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */
779#define WM8995_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */
780#define WM8995_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */
781#define WM8995_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */
782#define WM8995_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */
783#define WM8995_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */
784#define WM8995_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */
785#define WM8995_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */
786#define WM8995_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */
787#define WM8995_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */
788#define WM8995_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */
789#define WM8995_BG_ENA 0x0001 /* BG_ENA */
790#define WM8995_BG_ENA_MASK 0x0001 /* BG_ENA */
791#define WM8995_BG_ENA_SHIFT 0 /* BG_ENA */
792#define WM8995_BG_ENA_WIDTH 1 /* BG_ENA */
793
794/*
795 * R2 (0x02) - Power Management (2)
796 */
797#define WM8995_OPCLK_ENA 0x0800 /* OPCLK_ENA */
798#define WM8995_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */
799#define WM8995_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */
800#define WM8995_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */
801#define WM8995_IN1L_ENA 0x0020 /* IN1L_ENA */
802#define WM8995_IN1L_ENA_MASK 0x0020 /* IN1L_ENA */
803#define WM8995_IN1L_ENA_SHIFT 5 /* IN1L_ENA */
804#define WM8995_IN1L_ENA_WIDTH 1 /* IN1L_ENA */
805#define WM8995_IN1R_ENA 0x0010 /* IN1R_ENA */
806#define WM8995_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */
807#define WM8995_IN1R_ENA_SHIFT 4 /* IN1R_ENA */
808#define WM8995_IN1R_ENA_WIDTH 1 /* IN1R_ENA */
809#define WM8995_LDO2_ENA 0x0002 /* LDO2_ENA */
810#define WM8995_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */
811#define WM8995_LDO2_ENA_SHIFT 1 /* LDO2_ENA */
812#define WM8995_LDO2_ENA_WIDTH 1 /* LDO2_ENA */
813
814/*
815 * R3 (0x03) - Power Management (3)
816 */
817#define WM8995_AIF2ADCL_ENA 0x2000 /* AIF2ADCL_ENA */
818#define WM8995_AIF2ADCL_ENA_MASK 0x2000 /* AIF2ADCL_ENA */
819#define WM8995_AIF2ADCL_ENA_SHIFT 13 /* AIF2ADCL_ENA */
820#define WM8995_AIF2ADCL_ENA_WIDTH 1 /* AIF2ADCL_ENA */
821#define WM8995_AIF2ADCR_ENA 0x1000 /* AIF2ADCR_ENA */
822#define WM8995_AIF2ADCR_ENA_MASK 0x1000 /* AIF2ADCR_ENA */
823#define WM8995_AIF2ADCR_ENA_SHIFT 12 /* AIF2ADCR_ENA */
824#define WM8995_AIF2ADCR_ENA_WIDTH 1 /* AIF2ADCR_ENA */
825#define WM8995_AIF1ADC2L_ENA 0x0800 /* AIF1ADC2L_ENA */
826#define WM8995_AIF1ADC2L_ENA_MASK 0x0800 /* AIF1ADC2L_ENA */
827#define WM8995_AIF1ADC2L_ENA_SHIFT 11 /* AIF1ADC2L_ENA */
828#define WM8995_AIF1ADC2L_ENA_WIDTH 1 /* AIF1ADC2L_ENA */
829#define WM8995_AIF1ADC2R_ENA 0x0400 /* AIF1ADC2R_ENA */
830#define WM8995_AIF1ADC2R_ENA_MASK 0x0400 /* AIF1ADC2R_ENA */
831#define WM8995_AIF1ADC2R_ENA_SHIFT 10 /* AIF1ADC2R_ENA */
832#define WM8995_AIF1ADC2R_ENA_WIDTH 1 /* AIF1ADC2R_ENA */
833#define WM8995_AIF1ADC1L_ENA 0x0200 /* AIF1ADC1L_ENA */
834#define WM8995_AIF1ADC1L_ENA_MASK 0x0200 /* AIF1ADC1L_ENA */
835#define WM8995_AIF1ADC1L_ENA_SHIFT 9 /* AIF1ADC1L_ENA */
836#define WM8995_AIF1ADC1L_ENA_WIDTH 1 /* AIF1ADC1L_ENA */
837#define WM8995_AIF1ADC1R_ENA 0x0100 /* AIF1ADC1R_ENA */
838#define WM8995_AIF1ADC1R_ENA_MASK 0x0100 /* AIF1ADC1R_ENA */
839#define WM8995_AIF1ADC1R_ENA_SHIFT 8 /* AIF1ADC1R_ENA */
840#define WM8995_AIF1ADC1R_ENA_WIDTH 1 /* AIF1ADC1R_ENA */
841#define WM8995_DMIC3L_ENA 0x0080 /* DMIC3L_ENA */
842#define WM8995_DMIC3L_ENA_MASK 0x0080 /* DMIC3L_ENA */
843#define WM8995_DMIC3L_ENA_SHIFT 7 /* DMIC3L_ENA */
844#define WM8995_DMIC3L_ENA_WIDTH 1 /* DMIC3L_ENA */
845#define WM8995_DMIC3R_ENA 0x0040 /* DMIC3R_ENA */
846#define WM8995_DMIC3R_ENA_MASK 0x0040 /* DMIC3R_ENA */
847#define WM8995_DMIC3R_ENA_SHIFT 6 /* DMIC3R_ENA */
848#define WM8995_DMIC3R_ENA_WIDTH 1 /* DMIC3R_ENA */
849#define WM8995_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */
850#define WM8995_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */
851#define WM8995_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */
852#define WM8995_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */
853#define WM8995_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */
854#define WM8995_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */
855#define WM8995_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */
856#define WM8995_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */
857#define WM8995_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */
858#define WM8995_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */
859#define WM8995_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */
860#define WM8995_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */
861#define WM8995_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */
862#define WM8995_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */
863#define WM8995_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */
864#define WM8995_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */
865#define WM8995_ADCL_ENA 0x0002 /* ADCL_ENA */
866#define WM8995_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */
867#define WM8995_ADCL_ENA_SHIFT 1 /* ADCL_ENA */
868#define WM8995_ADCL_ENA_WIDTH 1 /* ADCL_ENA */
869#define WM8995_ADCR_ENA 0x0001 /* ADCR_ENA */
870#define WM8995_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */
871#define WM8995_ADCR_ENA_SHIFT 0 /* ADCR_ENA */
872#define WM8995_ADCR_ENA_WIDTH 1 /* ADCR_ENA */
873
874/*
875 * R4 (0x04) - Power Management (4)
876 */
877#define WM8995_AIF2DACL_ENA 0x2000 /* AIF2DACL_ENA */
878#define WM8995_AIF2DACL_ENA_MASK 0x2000 /* AIF2DACL_ENA */
879#define WM8995_AIF2DACL_ENA_SHIFT 13 /* AIF2DACL_ENA */
880#define WM8995_AIF2DACL_ENA_WIDTH 1 /* AIF2DACL_ENA */
881#define WM8995_AIF2DACR_ENA 0x1000 /* AIF2DACR_ENA */
882#define WM8995_AIF2DACR_ENA_MASK 0x1000 /* AIF2DACR_ENA */
883#define WM8995_AIF2DACR_ENA_SHIFT 12 /* AIF2DACR_ENA */
884#define WM8995_AIF2DACR_ENA_WIDTH 1 /* AIF2DACR_ENA */
885#define WM8995_AIF1DAC2L_ENA 0x0800 /* AIF1DAC2L_ENA */
886#define WM8995_AIF1DAC2L_ENA_MASK 0x0800 /* AIF1DAC2L_ENA */
887#define WM8995_AIF1DAC2L_ENA_SHIFT 11 /* AIF1DAC2L_ENA */
888#define WM8995_AIF1DAC2L_ENA_WIDTH 1 /* AIF1DAC2L_ENA */
889#define WM8995_AIF1DAC2R_ENA 0x0400 /* AIF1DAC2R_ENA */
890#define WM8995_AIF1DAC2R_ENA_MASK 0x0400 /* AIF1DAC2R_ENA */
891#define WM8995_AIF1DAC2R_ENA_SHIFT 10 /* AIF1DAC2R_ENA */
892#define WM8995_AIF1DAC2R_ENA_WIDTH 1 /* AIF1DAC2R_ENA */
893#define WM8995_AIF1DAC1L_ENA 0x0200 /* AIF1DAC1L_ENA */
894#define WM8995_AIF1DAC1L_ENA_MASK 0x0200 /* AIF1DAC1L_ENA */
895#define WM8995_AIF1DAC1L_ENA_SHIFT 9 /* AIF1DAC1L_ENA */
896#define WM8995_AIF1DAC1L_ENA_WIDTH 1 /* AIF1DAC1L_ENA */
897#define WM8995_AIF1DAC1R_ENA 0x0100 /* AIF1DAC1R_ENA */
898#define WM8995_AIF1DAC1R_ENA_MASK 0x0100 /* AIF1DAC1R_ENA */
899#define WM8995_AIF1DAC1R_ENA_SHIFT 8 /* AIF1DAC1R_ENA */
900#define WM8995_AIF1DAC1R_ENA_WIDTH 1 /* AIF1DAC1R_ENA */
901#define WM8995_DAC2L_ENA 0x0008 /* DAC2L_ENA */
902#define WM8995_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */
903#define WM8995_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */
904#define WM8995_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */
905#define WM8995_DAC2R_ENA 0x0004 /* DAC2R_ENA */
906#define WM8995_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */
907#define WM8995_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */
908#define WM8995_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */
909#define WM8995_DAC1L_ENA 0x0002 /* DAC1L_ENA */
910#define WM8995_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */
911#define WM8995_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */
912#define WM8995_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */
913#define WM8995_DAC1R_ENA 0x0001 /* DAC1R_ENA */
914#define WM8995_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */
915#define WM8995_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */
916#define WM8995_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */
917
918/*
919 * R5 (0x05) - Power Management (5)
920 */
921#define WM8995_DMIC_SRC2_MASK 0x0300 /* DMIC_SRC2 - [9:8] */
922#define WM8995_DMIC_SRC2_SHIFT 8 /* DMIC_SRC2 - [9:8] */
923#define WM8995_DMIC_SRC2_WIDTH 2 /* DMIC_SRC2 - [9:8] */
924#define WM8995_DMIC_SRC1_MASK 0x00C0 /* DMIC_SRC1 - [7:6] */
925#define WM8995_DMIC_SRC1_SHIFT 6 /* DMIC_SRC1 - [7:6] */
926#define WM8995_DMIC_SRC1_WIDTH 2 /* DMIC_SRC1 - [7:6] */
927#define WM8995_AIF3_TRI 0x0020 /* AIF3_TRI */
928#define WM8995_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */
929#define WM8995_AIF3_TRI_SHIFT 5 /* AIF3_TRI */
930#define WM8995_AIF3_TRI_WIDTH 1 /* AIF3_TRI */
931#define WM8995_AIF3_ADCDAT_SRC_MASK 0x0018 /* AIF3_ADCDAT_SRC - [4:3] */
932#define WM8995_AIF3_ADCDAT_SRC_SHIFT 3 /* AIF3_ADCDAT_SRC - [4:3] */
933#define WM8995_AIF3_ADCDAT_SRC_WIDTH 2 /* AIF3_ADCDAT_SRC - [4:3] */
934#define WM8995_AIF2_ADCDAT_SRC 0x0004 /* AIF2_ADCDAT_SRC */
935#define WM8995_AIF2_ADCDAT_SRC_MASK 0x0004 /* AIF2_ADCDAT_SRC */
936#define WM8995_AIF2_ADCDAT_SRC_SHIFT 2 /* AIF2_ADCDAT_SRC */
937#define WM8995_AIF2_ADCDAT_SRC_WIDTH 1 /* AIF2_ADCDAT_SRC */
938#define WM8995_AIF2_DACDAT_SRC 0x0002 /* AIF2_DACDAT_SRC */
939#define WM8995_AIF2_DACDAT_SRC_MASK 0x0002 /* AIF2_DACDAT_SRC */
940#define WM8995_AIF2_DACDAT_SRC_SHIFT 1 /* AIF2_DACDAT_SRC */
941#define WM8995_AIF2_DACDAT_SRC_WIDTH 1 /* AIF2_DACDAT_SRC */
942#define WM8995_AIF1_DACDAT_SRC 0x0001 /* AIF1_DACDAT_SRC */
943#define WM8995_AIF1_DACDAT_SRC_MASK 0x0001 /* AIF1_DACDAT_SRC */
944#define WM8995_AIF1_DACDAT_SRC_SHIFT 0 /* AIF1_DACDAT_SRC */
945#define WM8995_AIF1_DACDAT_SRC_WIDTH 1 /* AIF1_DACDAT_SRC */
946
947/*
948 * R16 (0x10) - Left Line Input 1 Volume
949 */
950#define WM8995_IN1_VU 0x0080 /* IN1_VU */
951#define WM8995_IN1_VU_MASK 0x0080 /* IN1_VU */
952#define WM8995_IN1_VU_SHIFT 7 /* IN1_VU */
953#define WM8995_IN1_VU_WIDTH 1 /* IN1_VU */
954#define WM8995_IN1L_ZC 0x0020 /* IN1L_ZC */
955#define WM8995_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */
956#define WM8995_IN1L_ZC_SHIFT 5 /* IN1L_ZC */
957#define WM8995_IN1L_ZC_WIDTH 1 /* IN1L_ZC */
958#define WM8995_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */
959#define WM8995_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */
960#define WM8995_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */
961
962/*
963 * R17 (0x11) - Right Line Input 1 Volume
964 */
965#define WM8995_IN1_VU 0x0080 /* IN1_VU */
966#define WM8995_IN1_VU_MASK 0x0080 /* IN1_VU */
967#define WM8995_IN1_VU_SHIFT 7 /* IN1_VU */
968#define WM8995_IN1_VU_WIDTH 1 /* IN1_VU */
969#define WM8995_IN1R_ZC 0x0020 /* IN1R_ZC */
970#define WM8995_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */
971#define WM8995_IN1R_ZC_SHIFT 5 /* IN1R_ZC */
972#define WM8995_IN1R_ZC_WIDTH 1 /* IN1R_ZC */
973#define WM8995_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */
974#define WM8995_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */
975#define WM8995_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */
976
977/*
978 * R18 (0x12) - Left Line Input Control
979 */
980#define WM8995_IN1L_BOOST_MASK 0x0030 /* IN1L_BOOST - [5:4] */
981#define WM8995_IN1L_BOOST_SHIFT 4 /* IN1L_BOOST - [5:4] */
982#define WM8995_IN1L_BOOST_WIDTH 2 /* IN1L_BOOST - [5:4] */
983#define WM8995_IN1L_MODE_MASK 0x000C /* IN1L_MODE - [3:2] */
984#define WM8995_IN1L_MODE_SHIFT 2 /* IN1L_MODE - [3:2] */
985#define WM8995_IN1L_MODE_WIDTH 2 /* IN1L_MODE - [3:2] */
986#define WM8995_IN1R_MODE_MASK 0x0003 /* IN1R_MODE - [1:0] */
987#define WM8995_IN1R_MODE_SHIFT 0 /* IN1R_MODE - [1:0] */
988#define WM8995_IN1R_MODE_WIDTH 2 /* IN1R_MODE - [1:0] */
989
990/*
991 * R24 (0x18) - DAC1 Left Volume
992 */
993#define WM8995_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */
994#define WM8995_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */
995#define WM8995_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */
996#define WM8995_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */
997#define WM8995_DAC1_VU 0x0100 /* DAC1_VU */
998#define WM8995_DAC1_VU_MASK 0x0100 /* DAC1_VU */
999#define WM8995_DAC1_VU_SHIFT 8 /* DAC1_VU */
1000#define WM8995_DAC1_VU_WIDTH 1 /* DAC1_VU */
1001#define WM8995_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */
1002#define WM8995_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */
1003#define WM8995_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */
1004
1005/*
1006 * R25 (0x19) - DAC1 Right Volume
1007 */
1008#define WM8995_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */
1009#define WM8995_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */
1010#define WM8995_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */
1011#define WM8995_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */
1012#define WM8995_DAC1_VU 0x0100 /* DAC1_VU */
1013#define WM8995_DAC1_VU_MASK 0x0100 /* DAC1_VU */
1014#define WM8995_DAC1_VU_SHIFT 8 /* DAC1_VU */
1015#define WM8995_DAC1_VU_WIDTH 1 /* DAC1_VU */
1016#define WM8995_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */
1017#define WM8995_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */
1018#define WM8995_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */
1019
1020/*
1021 * R26 (0x1A) - DAC2 Left Volume
1022 */
1023#define WM8995_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */
1024#define WM8995_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */
1025#define WM8995_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */
1026#define WM8995_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */
1027#define WM8995_DAC2_VU 0x0100 /* DAC2_VU */
1028#define WM8995_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1029#define WM8995_DAC2_VU_SHIFT 8 /* DAC2_VU */
1030#define WM8995_DAC2_VU_WIDTH 1 /* DAC2_VU */
1031#define WM8995_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */
1032#define WM8995_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */
1033#define WM8995_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */
1034
1035/*
1036 * R27 (0x1B) - DAC2 Right Volume
1037 */
1038#define WM8995_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */
1039#define WM8995_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */
1040#define WM8995_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */
1041#define WM8995_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */
1042#define WM8995_DAC2_VU 0x0100 /* DAC2_VU */
1043#define WM8995_DAC2_VU_MASK 0x0100 /* DAC2_VU */
1044#define WM8995_DAC2_VU_SHIFT 8 /* DAC2_VU */
1045#define WM8995_DAC2_VU_WIDTH 1 /* DAC2_VU */
1046#define WM8995_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */
1047#define WM8995_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */
1048#define WM8995_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */
1049
1050/*
1051 * R28 (0x1C) - Output Volume ZC (1)
1052 */
1053#define WM8995_HPOUT2L_ZC 0x0008 /* HPOUT2L_ZC */
1054#define WM8995_HPOUT2L_ZC_MASK 0x0008 /* HPOUT2L_ZC */
1055#define WM8995_HPOUT2L_ZC_SHIFT 3 /* HPOUT2L_ZC */
1056#define WM8995_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */
1057#define WM8995_HPOUT2R_ZC 0x0004 /* HPOUT2R_ZC */
1058#define WM8995_HPOUT2R_ZC_MASK 0x0004 /* HPOUT2R_ZC */
1059#define WM8995_HPOUT2R_ZC_SHIFT 2 /* HPOUT2R_ZC */
1060#define WM8995_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */
1061#define WM8995_HPOUT1L_ZC 0x0002 /* HPOUT1L_ZC */
1062#define WM8995_HPOUT1L_ZC_MASK 0x0002 /* HPOUT1L_ZC */
1063#define WM8995_HPOUT1L_ZC_SHIFT 1 /* HPOUT1L_ZC */
1064#define WM8995_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */
1065#define WM8995_HPOUT1R_ZC 0x0001 /* HPOUT1R_ZC */
1066#define WM8995_HPOUT1R_ZC_MASK 0x0001 /* HPOUT1R_ZC */
1067#define WM8995_HPOUT1R_ZC_SHIFT 0 /* HPOUT1R_ZC */
1068#define WM8995_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */
1069
1070/*
1071 * R32 (0x20) - MICBIAS (1)
1072 */
1073#define WM8995_MICB1_MODE 0x0008 /* MICB1_MODE */
1074#define WM8995_MICB1_MODE_MASK 0x0008 /* MICB1_MODE */
1075#define WM8995_MICB1_MODE_SHIFT 3 /* MICB1_MODE */
1076#define WM8995_MICB1_MODE_WIDTH 1 /* MICB1_MODE */
1077#define WM8995_MICB1_LVL_MASK 0x0006 /* MICB1_LVL - [2:1] */
1078#define WM8995_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [2:1] */
1079#define WM8995_MICB1_LVL_WIDTH 2 /* MICB1_LVL - [2:1] */
1080#define WM8995_MICB1_DISCH 0x0001 /* MICB1_DISCH */
1081#define WM8995_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */
1082#define WM8995_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */
1083#define WM8995_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */
1084
1085/*
1086 * R33 (0x21) - MICBIAS (2)
1087 */
1088#define WM8995_MICB2_MODE 0x0008 /* MICB2_MODE */
1089#define WM8995_MICB2_MODE_MASK 0x0008 /* MICB2_MODE */
1090#define WM8995_MICB2_MODE_SHIFT 3 /* MICB2_MODE */
1091#define WM8995_MICB2_MODE_WIDTH 1 /* MICB2_MODE */
1092#define WM8995_MICB2_LVL_MASK 0x0006 /* MICB2_LVL - [2:1] */
1093#define WM8995_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [2:1] */
1094#define WM8995_MICB2_LVL_WIDTH 2 /* MICB2_LVL - [2:1] */
1095#define WM8995_MICB2_DISCH 0x0001 /* MICB2_DISCH */
1096#define WM8995_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */
1097#define WM8995_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */
1098#define WM8995_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */
1099
1100/*
1101 * R40 (0x28) - LDO 1
1102 */
1103#define WM8995_LDO1_MODE 0x0020 /* LDO1_MODE */
1104#define WM8995_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */
1105#define WM8995_LDO1_MODE_SHIFT 5 /* LDO1_MODE */
1106#define WM8995_LDO1_MODE_WIDTH 1 /* LDO1_MODE */
1107#define WM8995_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */
1108#define WM8995_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */
1109#define WM8995_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */
1110#define WM8995_LDO1_DISCH 0x0001 /* LDO1_DISCH */
1111#define WM8995_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */
1112#define WM8995_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */
1113#define WM8995_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */
1114
1115/*
1116 * R41 (0x29) - LDO 2
1117 */
1118#define WM8995_LDO2_MODE 0x0020 /* LDO2_MODE */
1119#define WM8995_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */
1120#define WM8995_LDO2_MODE_SHIFT 5 /* LDO2_MODE */
1121#define WM8995_LDO2_MODE_WIDTH 1 /* LDO2_MODE */
1122#define WM8995_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */
1123#define WM8995_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */
1124#define WM8995_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */
1125#define WM8995_LDO2_DISCH 0x0001 /* LDO2_DISCH */
1126#define WM8995_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */
1127#define WM8995_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */
1128#define WM8995_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */
1129
1130/*
1131 * R48 (0x30) - Accessory Detect Mode1
1132 */
1133#define WM8995_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */
1134#define WM8995_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */
1135#define WM8995_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */
1136
1137/*
1138 * R49 (0x31) - Accessory Detect Mode2
1139 */
1140#define WM8995_VID_ENA 0x0001 /* VID_ENA */
1141#define WM8995_VID_ENA_MASK 0x0001 /* VID_ENA */
1142#define WM8995_VID_ENA_SHIFT 0 /* VID_ENA */
1143#define WM8995_VID_ENA_WIDTH 1 /* VID_ENA */
1144
1145/*
1146 * R52 (0x34) - Headphone Detect1
1147 */
1148#define WM8995_HP_RAMPRATE 0x0002 /* HP_RAMPRATE */
1149#define WM8995_HP_RAMPRATE_MASK 0x0002 /* HP_RAMPRATE */
1150#define WM8995_HP_RAMPRATE_SHIFT 1 /* HP_RAMPRATE */
1151#define WM8995_HP_RAMPRATE_WIDTH 1 /* HP_RAMPRATE */
1152#define WM8995_HP_POLL 0x0001 /* HP_POLL */
1153#define WM8995_HP_POLL_MASK 0x0001 /* HP_POLL */
1154#define WM8995_HP_POLL_SHIFT 0 /* HP_POLL */
1155#define WM8995_HP_POLL_WIDTH 1 /* HP_POLL */
1156
1157/*
1158 * R53 (0x35) - Headphone Detect2
1159 */
1160#define WM8995_HP_DONE 0x0080 /* HP_DONE */
1161#define WM8995_HP_DONE_MASK 0x0080 /* HP_DONE */
1162#define WM8995_HP_DONE_SHIFT 7 /* HP_DONE */
1163#define WM8995_HP_DONE_WIDTH 1 /* HP_DONE */
1164#define WM8995_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */
1165#define WM8995_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */
1166#define WM8995_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */
1167
1168/*
1169 * R56 (0x38) - Mic Detect (1)
1170 */
1171#define WM8995_MICD_RATE_MASK 0x7800 /* MICD_RATE - [14:11] */
1172#define WM8995_MICD_RATE_SHIFT 11 /* MICD_RATE - [14:11] */
1173#define WM8995_MICD_RATE_WIDTH 4 /* MICD_RATE - [14:11] */
1174#define WM8995_MICD_LVL_SEL_MASK 0x01F8 /* MICD_LVL_SEL - [8:3] */
1175#define WM8995_MICD_LVL_SEL_SHIFT 3 /* MICD_LVL_SEL - [8:3] */
1176#define WM8995_MICD_LVL_SEL_WIDTH 6 /* MICD_LVL_SEL - [8:3] */
1177#define WM8995_MICD_DBTIME 0x0002 /* MICD_DBTIME */
1178#define WM8995_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */
1179#define WM8995_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */
1180#define WM8995_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */
1181#define WM8995_MICD_ENA 0x0001 /* MICD_ENA */
1182#define WM8995_MICD_ENA_MASK 0x0001 /* MICD_ENA */
1183#define WM8995_MICD_ENA_SHIFT 0 /* MICD_ENA */
1184#define WM8995_MICD_ENA_WIDTH 1 /* MICD_ENA */
1185
1186/*
1187 * R57 (0x39) - Mic Detect (2)
1188 */
1189#define WM8995_MICD_LVL_MASK 0x01FC /* MICD_LVL - [8:2] */
1190#define WM8995_MICD_LVL_SHIFT 2 /* MICD_LVL - [8:2] */
1191#define WM8995_MICD_LVL_WIDTH 7 /* MICD_LVL - [8:2] */
1192#define WM8995_MICD_VALID 0x0002 /* MICD_VALID */
1193#define WM8995_MICD_VALID_MASK 0x0002 /* MICD_VALID */
1194#define WM8995_MICD_VALID_SHIFT 1 /* MICD_VALID */
1195#define WM8995_MICD_VALID_WIDTH 1 /* MICD_VALID */
1196#define WM8995_MICD_STS 0x0001 /* MICD_STS */
1197#define WM8995_MICD_STS_MASK 0x0001 /* MICD_STS */
1198#define WM8995_MICD_STS_SHIFT 0 /* MICD_STS */
1199#define WM8995_MICD_STS_WIDTH 1 /* MICD_STS */
1200
1201/*
1202 * R64 (0x40) - Charge Pump (1)
1203 */
1204#define WM8995_CP_ENA 0x8000 /* CP_ENA */
1205#define WM8995_CP_ENA_MASK 0x8000 /* CP_ENA */
1206#define WM8995_CP_ENA_SHIFT 15 /* CP_ENA */
1207#define WM8995_CP_ENA_WIDTH 1 /* CP_ENA */
1208
1209/*
1210 * R69 (0x45) - Class W (1)
1211 */
1212#define WM8995_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */
1213#define WM8995_CP_DYN_SRC_SEL_SHIFT 8 /* CP_DYN_SRC_SEL - [9:8] */
1214#define WM8995_CP_DYN_SRC_SEL_WIDTH 2 /* CP_DYN_SRC_SEL - [9:8] */
1215#define WM8995_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */
1216#define WM8995_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */
1217#define WM8995_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */
1218#define WM8995_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */
1219
1220/*
1221 * R80 (0x50) - DC Servo (1)
1222 */
1223#define WM8995_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */
1224#define WM8995_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */
1225#define WM8995_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */
1226#define WM8995_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */
1227#define WM8995_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */
1228#define WM8995_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */
1229#define WM8995_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */
1230#define WM8995_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */
1231#define WM8995_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */
1232#define WM8995_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */
1233#define WM8995_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */
1234#define WM8995_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */
1235#define WM8995_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */
1236#define WM8995_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */
1237#define WM8995_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */
1238#define WM8995_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */
1239
1240/*
1241 * R81 (0x51) - DC Servo (2)
1242 */
1243#define WM8995_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */
1244#define WM8995_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */
1245#define WM8995_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */
1246#define WM8995_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */
1247#define WM8995_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */
1248#define WM8995_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */
1249#define WM8995_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */
1250#define WM8995_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */
1251#define WM8995_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */
1252#define WM8995_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */
1253#define WM8995_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */
1254#define WM8995_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */
1255#define WM8995_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */
1256#define WM8995_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */
1257#define WM8995_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */
1258#define WM8995_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */
1259#define WM8995_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */
1260#define WM8995_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */
1261#define WM8995_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */
1262#define WM8995_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */
1263#define WM8995_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */
1264#define WM8995_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */
1265#define WM8995_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */
1266#define WM8995_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */
1267#define WM8995_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */
1268#define WM8995_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */
1269#define WM8995_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */
1270#define WM8995_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */
1271#define WM8995_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */
1272#define WM8995_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */
1273#define WM8995_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */
1274#define WM8995_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */
1275#define WM8995_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */
1276#define WM8995_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */
1277#define WM8995_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */
1278#define WM8995_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */
1279#define WM8995_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */
1280#define WM8995_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */
1281#define WM8995_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */
1282#define WM8995_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */
1283#define WM8995_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */
1284#define WM8995_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */
1285#define WM8995_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */
1286#define WM8995_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */
1287#define WM8995_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */
1288#define WM8995_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */
1289#define WM8995_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */
1290#define WM8995_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */
1291#define WM8995_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */
1292#define WM8995_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */
1293#define WM8995_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */
1294#define WM8995_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */
1295#define WM8995_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */
1296#define WM8995_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */
1297#define WM8995_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */
1298#define WM8995_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */
1299#define WM8995_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */
1300#define WM8995_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */
1301#define WM8995_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */
1302#define WM8995_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */
1303#define WM8995_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */
1304#define WM8995_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */
1305#define WM8995_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */
1306#define WM8995_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */
1307
1308/*
1309 * R82 (0x52) - DC Servo (3)
1310 */
1311#define WM8995_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */
1312#define WM8995_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */
1313#define WM8995_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */
1314#define WM8995_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */
1315#define WM8995_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */
1316#define WM8995_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */
1317
1318/*
1319 * R84 (0x54) - DC Servo (5)
1320 */
1321#define WM8995_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */
1322#define WM8995_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */
1323#define WM8995_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */
1324#define WM8995_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */
1325#define WM8995_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */
1326#define WM8995_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */
1327
1328/*
1329 * R85 (0x55) - DC Servo (6)
1330 */
1331#define WM8995_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */
1332#define WM8995_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1333#define WM8995_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */
1334#define WM8995_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */
1335#define WM8995_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */
1336#define WM8995_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */
1337
1338/*
1339 * R86 (0x56) - DC Servo (7)
1340 */
1341#define WM8995_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */
1342#define WM8995_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1343#define WM8995_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */
1344#define WM8995_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */
1345#define WM8995_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */
1346#define WM8995_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */
1347
1348/*
1349 * R87 (0x57) - DC Servo Readback 0
1350 */
1351#define WM8995_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */
1352#define WM8995_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */
1353#define WM8995_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */
1354#define WM8995_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */
1355#define WM8995_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1356#define WM8995_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */
1357#define WM8995_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */
1358#define WM8995_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */
1359#define WM8995_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */
1360
1361/*
1362 * R96 (0x60) - Analogue HP (1)
1363 */
1364#define WM8995_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */
1365#define WM8995_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */
1366#define WM8995_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */
1367#define WM8995_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */
1368#define WM8995_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */
1369#define WM8995_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */
1370#define WM8995_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */
1371#define WM8995_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */
1372#define WM8995_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */
1373#define WM8995_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */
1374#define WM8995_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */
1375#define WM8995_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */
1376#define WM8995_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */
1377#define WM8995_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */
1378#define WM8995_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */
1379#define WM8995_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */
1380#define WM8995_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */
1381#define WM8995_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */
1382#define WM8995_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */
1383#define WM8995_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */
1384#define WM8995_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */
1385#define WM8995_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */
1386#define WM8995_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */
1387#define WM8995_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */
1388
1389/*
1390 * R97 (0x61) - Analogue HP (2)
1391 */
1392#define WM8995_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */
1393#define WM8995_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */
1394#define WM8995_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */
1395#define WM8995_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */
1396#define WM8995_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */
1397#define WM8995_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */
1398#define WM8995_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */
1399#define WM8995_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */
1400#define WM8995_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */
1401#define WM8995_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */
1402#define WM8995_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */
1403#define WM8995_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */
1404#define WM8995_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */
1405#define WM8995_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */
1406#define WM8995_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */
1407#define WM8995_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */
1408#define WM8995_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */
1409#define WM8995_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */
1410#define WM8995_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */
1411#define WM8995_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */
1412#define WM8995_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */
1413#define WM8995_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */
1414#define WM8995_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */
1415#define WM8995_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */
1416
1417/*
1418 * R256 (0x100) - Chip Revision
1419 */
1420#define WM8995_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */
1421#define WM8995_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */
1422#define WM8995_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */
1423
1424/*
1425 * R257 (0x101) - Control Interface (1)
1426 */
1427#define WM8995_REG_SYNC 0x8000 /* REG_SYNC */
1428#define WM8995_REG_SYNC_MASK 0x8000 /* REG_SYNC */
1429#define WM8995_REG_SYNC_SHIFT 15 /* REG_SYNC */
1430#define WM8995_REG_SYNC_WIDTH 1 /* REG_SYNC */
1431#define WM8995_SPI_CONTRD 0x0040 /* SPI_CONTRD */
1432#define WM8995_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */
1433#define WM8995_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */
1434#define WM8995_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */
1435#define WM8995_SPI_4WIRE 0x0020 /* SPI_4WIRE */
1436#define WM8995_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */
1437#define WM8995_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */
1438#define WM8995_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */
1439#define WM8995_SPI_CFG 0x0010 /* SPI_CFG */
1440#define WM8995_SPI_CFG_MASK 0x0010 /* SPI_CFG */
1441#define WM8995_SPI_CFG_SHIFT 4 /* SPI_CFG */
1442#define WM8995_SPI_CFG_WIDTH 1 /* SPI_CFG */
1443#define WM8995_AUTO_INC 0x0004 /* AUTO_INC */
1444#define WM8995_AUTO_INC_MASK 0x0004 /* AUTO_INC */
1445#define WM8995_AUTO_INC_SHIFT 2 /* AUTO_INC */
1446#define WM8995_AUTO_INC_WIDTH 1 /* AUTO_INC */
1447
1448/*
1449 * R258 (0x102) - Control Interface (2)
1450 */
1451#define WM8995_CTRL_IF_SRC 0x0001 /* CTRL_IF_SRC */
1452#define WM8995_CTRL_IF_SRC_MASK 0x0001 /* CTRL_IF_SRC */
1453#define WM8995_CTRL_IF_SRC_SHIFT 0 /* CTRL_IF_SRC */
1454#define WM8995_CTRL_IF_SRC_WIDTH 1 /* CTRL_IF_SRC */
1455
1456/*
1457 * R272 (0x110) - Write Sequencer Ctrl (1)
1458 */
1459#define WM8995_WSEQ_ENA 0x8000 /* WSEQ_ENA */
1460#define WM8995_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */
1461#define WM8995_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */
1462#define WM8995_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */
1463#define WM8995_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */
1464#define WM8995_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */
1465#define WM8995_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */
1466#define WM8995_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */
1467#define WM8995_WSEQ_START 0x0100 /* WSEQ_START */
1468#define WM8995_WSEQ_START_MASK 0x0100 /* WSEQ_START */
1469#define WM8995_WSEQ_START_SHIFT 8 /* WSEQ_START */
1470#define WM8995_WSEQ_START_WIDTH 1 /* WSEQ_START */
1471#define WM8995_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */
1472#define WM8995_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */
1473#define WM8995_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */
1474
1475/*
1476 * R273 (0x111) - Write Sequencer Ctrl (2)
1477 */
1478#define WM8995_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */
1479#define WM8995_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */
1480#define WM8995_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */
1481#define WM8995_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */
1482#define WM8995_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */
1483#define WM8995_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */
1484#define WM8995_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */
1485
1486/*
1487 * R512 (0x200) - AIF1 Clocking (1)
1488 */
1489#define WM8995_AIF1CLK_SRC_MASK 0x0018 /* AIF1CLK_SRC - [4:3] */
1490#define WM8995_AIF1CLK_SRC_SHIFT 3 /* AIF1CLK_SRC - [4:3] */
1491#define WM8995_AIF1CLK_SRC_WIDTH 2 /* AIF1CLK_SRC - [4:3] */
1492#define WM8995_AIF1CLK_INV 0x0004 /* AIF1CLK_INV */
1493#define WM8995_AIF1CLK_INV_MASK 0x0004 /* AIF1CLK_INV */
1494#define WM8995_AIF1CLK_INV_SHIFT 2 /* AIF1CLK_INV */
1495#define WM8995_AIF1CLK_INV_WIDTH 1 /* AIF1CLK_INV */
1496#define WM8995_AIF1CLK_DIV 0x0002 /* AIF1CLK_DIV */
1497#define WM8995_AIF1CLK_DIV_MASK 0x0002 /* AIF1CLK_DIV */
1498#define WM8995_AIF1CLK_DIV_SHIFT 1 /* AIF1CLK_DIV */
1499#define WM8995_AIF1CLK_DIV_WIDTH 1 /* AIF1CLK_DIV */
1500#define WM8995_AIF1CLK_ENA 0x0001 /* AIF1CLK_ENA */
1501#define WM8995_AIF1CLK_ENA_MASK 0x0001 /* AIF1CLK_ENA */
1502#define WM8995_AIF1CLK_ENA_SHIFT 0 /* AIF1CLK_ENA */
1503#define WM8995_AIF1CLK_ENA_WIDTH 1 /* AIF1CLK_ENA */
1504
1505/*
1506 * R513 (0x201) - AIF1 Clocking (2)
1507 */
1508#define WM8995_AIF1DAC_DIV_MASK 0x0038 /* AIF1DAC_DIV - [5:3] */
1509#define WM8995_AIF1DAC_DIV_SHIFT 3 /* AIF1DAC_DIV - [5:3] */
1510#define WM8995_AIF1DAC_DIV_WIDTH 3 /* AIF1DAC_DIV - [5:3] */
1511#define WM8995_AIF1ADC_DIV_MASK 0x0007 /* AIF1ADC_DIV - [2:0] */
1512#define WM8995_AIF1ADC_DIV_SHIFT 0 /* AIF1ADC_DIV - [2:0] */
1513#define WM8995_AIF1ADC_DIV_WIDTH 3 /* AIF1ADC_DIV - [2:0] */
1514
1515/*
1516 * R516 (0x204) - AIF2 Clocking (1)
1517 */
1518#define WM8995_AIF2CLK_SRC_MASK 0x0018 /* AIF2CLK_SRC - [4:3] */
1519#define WM8995_AIF2CLK_SRC_SHIFT 3 /* AIF2CLK_SRC - [4:3] */
1520#define WM8995_AIF2CLK_SRC_WIDTH 2 /* AIF2CLK_SRC - [4:3] */
1521#define WM8995_AIF2CLK_INV 0x0004 /* AIF2CLK_INV */
1522#define WM8995_AIF2CLK_INV_MASK 0x0004 /* AIF2CLK_INV */
1523#define WM8995_AIF2CLK_INV_SHIFT 2 /* AIF2CLK_INV */
1524#define WM8995_AIF2CLK_INV_WIDTH 1 /* AIF2CLK_INV */
1525#define WM8995_AIF2CLK_DIV 0x0002 /* AIF2CLK_DIV */
1526#define WM8995_AIF2CLK_DIV_MASK 0x0002 /* AIF2CLK_DIV */
1527#define WM8995_AIF2CLK_DIV_SHIFT 1 /* AIF2CLK_DIV */
1528#define WM8995_AIF2CLK_DIV_WIDTH 1 /* AIF2CLK_DIV */
1529#define WM8995_AIF2CLK_ENA 0x0001 /* AIF2CLK_ENA */
1530#define WM8995_AIF2CLK_ENA_MASK 0x0001 /* AIF2CLK_ENA */
1531#define WM8995_AIF2CLK_ENA_SHIFT 0 /* AIF2CLK_ENA */
1532#define WM8995_AIF2CLK_ENA_WIDTH 1 /* AIF2CLK_ENA */
1533
1534/*
1535 * R517 (0x205) - AIF2 Clocking (2)
1536 */
1537#define WM8995_AIF2DAC_DIV_MASK 0x0038 /* AIF2DAC_DIV - [5:3] */
1538#define WM8995_AIF2DAC_DIV_SHIFT 3 /* AIF2DAC_DIV - [5:3] */
1539#define WM8995_AIF2DAC_DIV_WIDTH 3 /* AIF2DAC_DIV - [5:3] */
1540#define WM8995_AIF2ADC_DIV_MASK 0x0007 /* AIF2ADC_DIV - [2:0] */
1541#define WM8995_AIF2ADC_DIV_SHIFT 0 /* AIF2ADC_DIV - [2:0] */
1542#define WM8995_AIF2ADC_DIV_WIDTH 3 /* AIF2ADC_DIV - [2:0] */
1543
1544/*
1545 * R520 (0x208) - Clocking (1)
1546 */
1547#define WM8995_LFCLK_ENA 0x0020 /* LFCLK_ENA */
1548#define WM8995_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */
1549#define WM8995_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */
1550#define WM8995_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */
1551#define WM8995_TOCLK_ENA 0x0010 /* TOCLK_ENA */
1552#define WM8995_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */
1553#define WM8995_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */
1554#define WM8995_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */
1555#define WM8995_AIF1DSPCLK_ENA 0x0008 /* AIF1DSPCLK_ENA */
1556#define WM8995_AIF1DSPCLK_ENA_MASK 0x0008 /* AIF1DSPCLK_ENA */
1557#define WM8995_AIF1DSPCLK_ENA_SHIFT 3 /* AIF1DSPCLK_ENA */
1558#define WM8995_AIF1DSPCLK_ENA_WIDTH 1 /* AIF1DSPCLK_ENA */
1559#define WM8995_AIF2DSPCLK_ENA 0x0004 /* AIF2DSPCLK_ENA */
1560#define WM8995_AIF2DSPCLK_ENA_MASK 0x0004 /* AIF2DSPCLK_ENA */
1561#define WM8995_AIF2DSPCLK_ENA_SHIFT 2 /* AIF2DSPCLK_ENA */
1562#define WM8995_AIF2DSPCLK_ENA_WIDTH 1 /* AIF2DSPCLK_ENA */
1563#define WM8995_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */
1564#define WM8995_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */
1565#define WM8995_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */
1566#define WM8995_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */
1567#define WM8995_SYSCLK_SRC 0x0001 /* SYSCLK_SRC */
1568#define WM8995_SYSCLK_SRC_MASK 0x0001 /* SYSCLK_SRC */
1569#define WM8995_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC */
1570#define WM8995_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */
1571
1572/*
1573 * R521 (0x209) - Clocking (2)
1574 */
1575#define WM8995_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */
1576#define WM8995_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */
1577#define WM8995_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */
1578#define WM8995_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */
1579#define WM8995_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */
1580#define WM8995_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */
1581#define WM8995_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */
1582#define WM8995_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */
1583#define WM8995_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */
1584
1585/*
1586 * R528 (0x210) - AIF1 Rate
1587 */
1588#define WM8995_AIF1_SR_MASK 0x00F0 /* AIF1_SR - [7:4] */
1589#define WM8995_AIF1_SR_SHIFT 4 /* AIF1_SR - [7:4] */
1590#define WM8995_AIF1_SR_WIDTH 4 /* AIF1_SR - [7:4] */
1591#define WM8995_AIF1CLK_RATE_MASK 0x000F /* AIF1CLK_RATE - [3:0] */
1592#define WM8995_AIF1CLK_RATE_SHIFT 0 /* AIF1CLK_RATE - [3:0] */
1593#define WM8995_AIF1CLK_RATE_WIDTH 4 /* AIF1CLK_RATE - [3:0] */
1594
1595/*
1596 * R529 (0x211) - AIF2 Rate
1597 */
1598#define WM8995_AIF2_SR_MASK 0x00F0 /* AIF2_SR - [7:4] */
1599#define WM8995_AIF2_SR_SHIFT 4 /* AIF2_SR - [7:4] */
1600#define WM8995_AIF2_SR_WIDTH 4 /* AIF2_SR - [7:4] */
1601#define WM8995_AIF2CLK_RATE_MASK 0x000F /* AIF2CLK_RATE - [3:0] */
1602#define WM8995_AIF2CLK_RATE_SHIFT 0 /* AIF2CLK_RATE - [3:0] */
1603#define WM8995_AIF2CLK_RATE_WIDTH 4 /* AIF2CLK_RATE - [3:0] */
1604
1605/*
1606 * R530 (0x212) - Rate Status
1607 */
1608#define WM8995_SR_ERROR_MASK 0x000F /* SR_ERROR - [3:0] */
1609#define WM8995_SR_ERROR_SHIFT 0 /* SR_ERROR - [3:0] */
1610#define WM8995_SR_ERROR_WIDTH 4 /* SR_ERROR - [3:0] */
1611
1612/*
1613 * R544 (0x220) - FLL1 Control (1)
1614 */
1615#define WM8995_FLL1_OSC_ENA 0x0002 /* FLL1_OSC_ENA */
1616#define WM8995_FLL1_OSC_ENA_MASK 0x0002 /* FLL1_OSC_ENA */
1617#define WM8995_FLL1_OSC_ENA_SHIFT 1 /* FLL1_OSC_ENA */
1618#define WM8995_FLL1_OSC_ENA_WIDTH 1 /* FLL1_OSC_ENA */
1619#define WM8995_FLL1_ENA 0x0001 /* FLL1_ENA */
1620#define WM8995_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */
1621#define WM8995_FLL1_ENA_SHIFT 0 /* FLL1_ENA */
1622#define WM8995_FLL1_ENA_WIDTH 1 /* FLL1_ENA */
1623
1624/*
1625 * R545 (0x221) - FLL1 Control (2)
1626 */
1627#define WM8995_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */
1628#define WM8995_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */
1629#define WM8995_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */
1630#define WM8995_FLL1_CTRL_RATE_MASK 0x0070 /* FLL1_CTRL_RATE - [6:4] */
1631#define WM8995_FLL1_CTRL_RATE_SHIFT 4 /* FLL1_CTRL_RATE - [6:4] */
1632#define WM8995_FLL1_CTRL_RATE_WIDTH 3 /* FLL1_CTRL_RATE - [6:4] */
1633#define WM8995_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */
1634#define WM8995_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */
1635#define WM8995_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */
1636
1637/*
1638 * R546 (0x222) - FLL1 Control (3)
1639 */
1640#define WM8995_FLL1_K_MASK 0xFFFF /* FLL1_K - [15:0] */
1641#define WM8995_FLL1_K_SHIFT 0 /* FLL1_K - [15:0] */
1642#define WM8995_FLL1_K_WIDTH 16 /* FLL1_K - [15:0] */
1643
1644/*
1645 * R547 (0x223) - FLL1 Control (4)
1646 */
1647#define WM8995_FLL1_N_MASK 0x7FE0 /* FLL1_N - [14:5] */
1648#define WM8995_FLL1_N_SHIFT 5 /* FLL1_N - [14:5] */
1649#define WM8995_FLL1_N_WIDTH 10 /* FLL1_N - [14:5] */
1650#define WM8995_FLL1_LOOP_GAIN_MASK 0x000F /* FLL1_LOOP_GAIN - [3:0] */
1651#define WM8995_FLL1_LOOP_GAIN_SHIFT 0 /* FLL1_LOOP_GAIN - [3:0] */
1652#define WM8995_FLL1_LOOP_GAIN_WIDTH 4 /* FLL1_LOOP_GAIN - [3:0] */
1653
1654/*
1655 * R548 (0x224) - FLL1 Control (5)
1656 */
1657#define WM8995_FLL1_FRC_NCO_VAL_MASK 0x1F80 /* FLL1_FRC_NCO_VAL - [12:7] */
1658#define WM8995_FLL1_FRC_NCO_VAL_SHIFT 7 /* FLL1_FRC_NCO_VAL - [12:7] */
1659#define WM8995_FLL1_FRC_NCO_VAL_WIDTH 6 /* FLL1_FRC_NCO_VAL - [12:7] */
1660#define WM8995_FLL1_FRC_NCO 0x0040 /* FLL1_FRC_NCO */
1661#define WM8995_FLL1_FRC_NCO_MASK 0x0040 /* FLL1_FRC_NCO */
1662#define WM8995_FLL1_FRC_NCO_SHIFT 6 /* FLL1_FRC_NCO */
1663#define WM8995_FLL1_FRC_NCO_WIDTH 1 /* FLL1_FRC_NCO */
1664#define WM8995_FLL1_REFCLK_DIV_MASK 0x0018 /* FLL1_REFCLK_DIV - [4:3] */
1665#define WM8995_FLL1_REFCLK_DIV_SHIFT 3 /* FLL1_REFCLK_DIV - [4:3] */
1666#define WM8995_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [4:3] */
1667#define WM8995_FLL1_REFCLK_SRC_MASK 0x0003 /* FLL1_REFCLK_SRC - [1:0] */
1668#define WM8995_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [1:0] */
1669#define WM8995_FLL1_REFCLK_SRC_WIDTH 2 /* FLL1_REFCLK_SRC - [1:0] */
1670
1671/*
1672 * R576 (0x240) - FLL2 Control (1)
1673 */
1674#define WM8995_FLL2_OSC_ENA 0x0002 /* FLL2_OSC_ENA */
1675#define WM8995_FLL2_OSC_ENA_MASK 0x0002 /* FLL2_OSC_ENA */
1676#define WM8995_FLL2_OSC_ENA_SHIFT 1 /* FLL2_OSC_ENA */
1677#define WM8995_FLL2_OSC_ENA_WIDTH 1 /* FLL2_OSC_ENA */
1678#define WM8995_FLL2_ENA 0x0001 /* FLL2_ENA */
1679#define WM8995_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */
1680#define WM8995_FLL2_ENA_SHIFT 0 /* FLL2_ENA */
1681#define WM8995_FLL2_ENA_WIDTH 1 /* FLL2_ENA */
1682
1683/*
1684 * R577 (0x241) - FLL2 Control (2)
1685 */
1686#define WM8995_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */
1687#define WM8995_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */
1688#define WM8995_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */
1689#define WM8995_FLL2_CTRL_RATE_MASK 0x0070 /* FLL2_CTRL_RATE - [6:4] */
1690#define WM8995_FLL2_CTRL_RATE_SHIFT 4 /* FLL2_CTRL_RATE - [6:4] */
1691#define WM8995_FLL2_CTRL_RATE_WIDTH 3 /* FLL2_CTRL_RATE - [6:4] */
1692#define WM8995_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */
1693#define WM8995_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */
1694#define WM8995_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */
1695
1696/*
1697 * R578 (0x242) - FLL2 Control (3)
1698 */
1699#define WM8995_FLL2_K_MASK 0xFFFF /* FLL2_K - [15:0] */
1700#define WM8995_FLL2_K_SHIFT 0 /* FLL2_K - [15:0] */
1701#define WM8995_FLL2_K_WIDTH 16 /* FLL2_K - [15:0] */
1702
1703/*
1704 * R579 (0x243) - FLL2 Control (4)
1705 */
1706#define WM8995_FLL2_N_MASK 0x7FE0 /* FLL2_N - [14:5] */
1707#define WM8995_FLL2_N_SHIFT 5 /* FLL2_N - [14:5] */
1708#define WM8995_FLL2_N_WIDTH 10 /* FLL2_N - [14:5] */
1709#define WM8995_FLL2_LOOP_GAIN_MASK 0x000F /* FLL2_LOOP_GAIN - [3:0] */
1710#define WM8995_FLL2_LOOP_GAIN_SHIFT 0 /* FLL2_LOOP_GAIN - [3:0] */
1711#define WM8995_FLL2_LOOP_GAIN_WIDTH 4 /* FLL2_LOOP_GAIN - [3:0] */
1712
1713/*
1714 * R580 (0x244) - FLL2 Control (5)
1715 */
1716#define WM8995_FLL2_FRC_NCO_VAL_MASK 0x1F80 /* FLL2_FRC_NCO_VAL - [12:7] */
1717#define WM8995_FLL2_FRC_NCO_VAL_SHIFT 7 /* FLL2_FRC_NCO_VAL - [12:7] */
1718#define WM8995_FLL2_FRC_NCO_VAL_WIDTH 6 /* FLL2_FRC_NCO_VAL - [12:7] */
1719#define WM8995_FLL2_FRC_NCO 0x0040 /* FLL2_FRC_NCO */
1720#define WM8995_FLL2_FRC_NCO_MASK 0x0040 /* FLL2_FRC_NCO */
1721#define WM8995_FLL2_FRC_NCO_SHIFT 6 /* FLL2_FRC_NCO */
1722#define WM8995_FLL2_FRC_NCO_WIDTH 1 /* FLL2_FRC_NCO */
1723#define WM8995_FLL2_REFCLK_DIV_MASK 0x0018 /* FLL2_REFCLK_DIV - [4:3] */
1724#define WM8995_FLL2_REFCLK_DIV_SHIFT 3 /* FLL2_REFCLK_DIV - [4:3] */
1725#define WM8995_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [4:3] */
1726#define WM8995_FLL2_REFCLK_SRC_MASK 0x0003 /* FLL2_REFCLK_SRC - [1:0] */
1727#define WM8995_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [1:0] */
1728#define WM8995_FLL2_REFCLK_SRC_WIDTH 2 /* FLL2_REFCLK_SRC - [1:0] */
1729
1730/*
1731 * R768 (0x300) - AIF1 Control (1)
1732 */
1733#define WM8995_AIF1ADCL_SRC 0x8000 /* AIF1ADCL_SRC */
1734#define WM8995_AIF1ADCL_SRC_MASK 0x8000 /* AIF1ADCL_SRC */
1735#define WM8995_AIF1ADCL_SRC_SHIFT 15 /* AIF1ADCL_SRC */
1736#define WM8995_AIF1ADCL_SRC_WIDTH 1 /* AIF1ADCL_SRC */
1737#define WM8995_AIF1ADCR_SRC 0x4000 /* AIF1ADCR_SRC */
1738#define WM8995_AIF1ADCR_SRC_MASK 0x4000 /* AIF1ADCR_SRC */
1739#define WM8995_AIF1ADCR_SRC_SHIFT 14 /* AIF1ADCR_SRC */
1740#define WM8995_AIF1ADCR_SRC_WIDTH 1 /* AIF1ADCR_SRC */
1741#define WM8995_AIF1ADC_TDM 0x2000 /* AIF1ADC_TDM */
1742#define WM8995_AIF1ADC_TDM_MASK 0x2000 /* AIF1ADC_TDM */
1743#define WM8995_AIF1ADC_TDM_SHIFT 13 /* AIF1ADC_TDM */
1744#define WM8995_AIF1ADC_TDM_WIDTH 1 /* AIF1ADC_TDM */
1745#define WM8995_AIF1_BCLK_INV 0x0100 /* AIF1_BCLK_INV */
1746#define WM8995_AIF1_BCLK_INV_MASK 0x0100 /* AIF1_BCLK_INV */
1747#define WM8995_AIF1_BCLK_INV_SHIFT 8 /* AIF1_BCLK_INV */
1748#define WM8995_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */
1749#define WM8995_AIF1_LRCLK_INV 0x0080 /* AIF1_LRCLK_INV */
1750#define WM8995_AIF1_LRCLK_INV_MASK 0x0080 /* AIF1_LRCLK_INV */
1751#define WM8995_AIF1_LRCLK_INV_SHIFT 7 /* AIF1_LRCLK_INV */
1752#define WM8995_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */
1753#define WM8995_AIF1_WL_MASK 0x0060 /* AIF1_WL - [6:5] */
1754#define WM8995_AIF1_WL_SHIFT 5 /* AIF1_WL - [6:5] */
1755#define WM8995_AIF1_WL_WIDTH 2 /* AIF1_WL - [6:5] */
1756#define WM8995_AIF1_FMT_MASK 0x0018 /* AIF1_FMT - [4:3] */
1757#define WM8995_AIF1_FMT_SHIFT 3 /* AIF1_FMT - [4:3] */
1758#define WM8995_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [4:3] */
1759
1760/*
1761 * R769 (0x301) - AIF1 Control (2)
1762 */
1763#define WM8995_AIF1DACL_SRC 0x8000 /* AIF1DACL_SRC */
1764#define WM8995_AIF1DACL_SRC_MASK 0x8000 /* AIF1DACL_SRC */
1765#define WM8995_AIF1DACL_SRC_SHIFT 15 /* AIF1DACL_SRC */
1766#define WM8995_AIF1DACL_SRC_WIDTH 1 /* AIF1DACL_SRC */
1767#define WM8995_AIF1DACR_SRC 0x4000 /* AIF1DACR_SRC */
1768#define WM8995_AIF1DACR_SRC_MASK 0x4000 /* AIF1DACR_SRC */
1769#define WM8995_AIF1DACR_SRC_SHIFT 14 /* AIF1DACR_SRC */
1770#define WM8995_AIF1DACR_SRC_WIDTH 1 /* AIF1DACR_SRC */
1771#define WM8995_AIF1DAC_BOOST_MASK 0x0C00 /* AIF1DAC_BOOST - [11:10] */
1772#define WM8995_AIF1DAC_BOOST_SHIFT 10 /* AIF1DAC_BOOST - [11:10] */
1773#define WM8995_AIF1DAC_BOOST_WIDTH 2 /* AIF1DAC_BOOST - [11:10] */
1774#define WM8995_AIF1DAC_COMP 0x0010 /* AIF1DAC_COMP */
1775#define WM8995_AIF1DAC_COMP_MASK 0x0010 /* AIF1DAC_COMP */
1776#define WM8995_AIF1DAC_COMP_SHIFT 4 /* AIF1DAC_COMP */
1777#define WM8995_AIF1DAC_COMP_WIDTH 1 /* AIF1DAC_COMP */
1778#define WM8995_AIF1DAC_COMPMODE 0x0008 /* AIF1DAC_COMPMODE */
1779#define WM8995_AIF1DAC_COMPMODE_MASK 0x0008 /* AIF1DAC_COMPMODE */
1780#define WM8995_AIF1DAC_COMPMODE_SHIFT 3 /* AIF1DAC_COMPMODE */
1781#define WM8995_AIF1DAC_COMPMODE_WIDTH 1 /* AIF1DAC_COMPMODE */
1782#define WM8995_AIF1ADC_COMP 0x0004 /* AIF1ADC_COMP */
1783#define WM8995_AIF1ADC_COMP_MASK 0x0004 /* AIF1ADC_COMP */
1784#define WM8995_AIF1ADC_COMP_SHIFT 2 /* AIF1ADC_COMP */
1785#define WM8995_AIF1ADC_COMP_WIDTH 1 /* AIF1ADC_COMP */
1786#define WM8995_AIF1ADC_COMPMODE 0x0002 /* AIF1ADC_COMPMODE */
1787#define WM8995_AIF1ADC_COMPMODE_MASK 0x0002 /* AIF1ADC_COMPMODE */
1788#define WM8995_AIF1ADC_COMPMODE_SHIFT 1 /* AIF1ADC_COMPMODE */
1789#define WM8995_AIF1ADC_COMPMODE_WIDTH 1 /* AIF1ADC_COMPMODE */
1790#define WM8995_AIF1_LOOPBACK 0x0001 /* AIF1_LOOPBACK */
1791#define WM8995_AIF1_LOOPBACK_MASK 0x0001 /* AIF1_LOOPBACK */
1792#define WM8995_AIF1_LOOPBACK_SHIFT 0 /* AIF1_LOOPBACK */
1793#define WM8995_AIF1_LOOPBACK_WIDTH 1 /* AIF1_LOOPBACK */
1794
1795/*
1796 * R770 (0x302) - AIF1 Master/Slave
1797 */
1798#define WM8995_AIF1_TRI 0x8000 /* AIF1_TRI */
1799#define WM8995_AIF1_TRI_MASK 0x8000 /* AIF1_TRI */
1800#define WM8995_AIF1_TRI_SHIFT 15 /* AIF1_TRI */
1801#define WM8995_AIF1_TRI_WIDTH 1 /* AIF1_TRI */
1802#define WM8995_AIF1_MSTR 0x4000 /* AIF1_MSTR */
1803#define WM8995_AIF1_MSTR_MASK 0x4000 /* AIF1_MSTR */
1804#define WM8995_AIF1_MSTR_SHIFT 14 /* AIF1_MSTR */
1805#define WM8995_AIF1_MSTR_WIDTH 1 /* AIF1_MSTR */
1806#define WM8995_AIF1_CLK_FRC 0x2000 /* AIF1_CLK_FRC */
1807#define WM8995_AIF1_CLK_FRC_MASK 0x2000 /* AIF1_CLK_FRC */
1808#define WM8995_AIF1_CLK_FRC_SHIFT 13 /* AIF1_CLK_FRC */
1809#define WM8995_AIF1_CLK_FRC_WIDTH 1 /* AIF1_CLK_FRC */
1810#define WM8995_AIF1_LRCLK_FRC 0x1000 /* AIF1_LRCLK_FRC */
1811#define WM8995_AIF1_LRCLK_FRC_MASK 0x1000 /* AIF1_LRCLK_FRC */
1812#define WM8995_AIF1_LRCLK_FRC_SHIFT 12 /* AIF1_LRCLK_FRC */
1813#define WM8995_AIF1_LRCLK_FRC_WIDTH 1 /* AIF1_LRCLK_FRC */
1814
1815/*
1816 * R771 (0x303) - AIF1 BCLK
1817 */
1818#define WM8995_AIF1_BCLK_DIV_MASK 0x00F0 /* AIF1_BCLK_DIV - [7:4] */
1819#define WM8995_AIF1_BCLK_DIV_SHIFT 4 /* AIF1_BCLK_DIV - [7:4] */
1820#define WM8995_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [7:4] */
1821
1822/*
1823 * R772 (0x304) - AIF1ADC LRCLK
1824 */
1825#define WM8995_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */
1826#define WM8995_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */
1827#define WM8995_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */
1828#define WM8995_AIF1ADC_LRCLK_DIR_WIDTH 1 /* AIF1ADC_LRCLK_DIR */
1829#define WM8995_AIF1ADC_RATE_MASK 0x07FF /* AIF1ADC_RATE - [10:0] */
1830#define WM8995_AIF1ADC_RATE_SHIFT 0 /* AIF1ADC_RATE - [10:0] */
1831#define WM8995_AIF1ADC_RATE_WIDTH 11 /* AIF1ADC_RATE - [10:0] */
1832
1833/*
1834 * R773 (0x305) - AIF1DAC LRCLK
1835 */
1836#define WM8995_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */
1837#define WM8995_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */
1838#define WM8995_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */
1839#define WM8995_AIF1DAC_LRCLK_DIR_WIDTH 1 /* AIF1DAC_LRCLK_DIR */
1840#define WM8995_AIF1DAC_RATE_MASK 0x07FF /* AIF1DAC_RATE - [10:0] */
1841#define WM8995_AIF1DAC_RATE_SHIFT 0 /* AIF1DAC_RATE - [10:0] */
1842#define WM8995_AIF1DAC_RATE_WIDTH 11 /* AIF1DAC_RATE - [10:0] */
1843
1844/*
1845 * R774 (0x306) - AIF1DAC Data
1846 */
1847#define WM8995_AIF1DACL_DAT_INV 0x0002 /* AIF1DACL_DAT_INV */
1848#define WM8995_AIF1DACL_DAT_INV_MASK 0x0002 /* AIF1DACL_DAT_INV */
1849#define WM8995_AIF1DACL_DAT_INV_SHIFT 1 /* AIF1DACL_DAT_INV */
1850#define WM8995_AIF1DACL_DAT_INV_WIDTH 1 /* AIF1DACL_DAT_INV */
1851#define WM8995_AIF1DACR_DAT_INV 0x0001 /* AIF1DACR_DAT_INV */
1852#define WM8995_AIF1DACR_DAT_INV_MASK 0x0001 /* AIF1DACR_DAT_INV */
1853#define WM8995_AIF1DACR_DAT_INV_SHIFT 0 /* AIF1DACR_DAT_INV */
1854#define WM8995_AIF1DACR_DAT_INV_WIDTH 1 /* AIF1DACR_DAT_INV */
1855
1856/*
1857 * R775 (0x307) - AIF1ADC Data
1858 */
1859#define WM8995_AIF1ADCL_DAT_INV 0x0002 /* AIF1ADCL_DAT_INV */
1860#define WM8995_AIF1ADCL_DAT_INV_MASK 0x0002 /* AIF1ADCL_DAT_INV */
1861#define WM8995_AIF1ADCL_DAT_INV_SHIFT 1 /* AIF1ADCL_DAT_INV */
1862#define WM8995_AIF1ADCL_DAT_INV_WIDTH 1 /* AIF1ADCL_DAT_INV */
1863#define WM8995_AIF1ADCR_DAT_INV 0x0001 /* AIF1ADCR_DAT_INV */
1864#define WM8995_AIF1ADCR_DAT_INV_MASK 0x0001 /* AIF1ADCR_DAT_INV */
1865#define WM8995_AIF1ADCR_DAT_INV_SHIFT 0 /* AIF1ADCR_DAT_INV */
1866#define WM8995_AIF1ADCR_DAT_INV_WIDTH 1 /* AIF1ADCR_DAT_INV */
1867
1868/*
1869 * R784 (0x310) - AIF2 Control (1)
1870 */
1871#define WM8995_AIF2ADCL_SRC 0x8000 /* AIF2ADCL_SRC */
1872#define WM8995_AIF2ADCL_SRC_MASK 0x8000 /* AIF2ADCL_SRC */
1873#define WM8995_AIF2ADCL_SRC_SHIFT 15 /* AIF2ADCL_SRC */
1874#define WM8995_AIF2ADCL_SRC_WIDTH 1 /* AIF2ADCL_SRC */
1875#define WM8995_AIF2ADCR_SRC 0x4000 /* AIF2ADCR_SRC */
1876#define WM8995_AIF2ADCR_SRC_MASK 0x4000 /* AIF2ADCR_SRC */
1877#define WM8995_AIF2ADCR_SRC_SHIFT 14 /* AIF2ADCR_SRC */
1878#define WM8995_AIF2ADCR_SRC_WIDTH 1 /* AIF2ADCR_SRC */
1879#define WM8995_AIF2ADC_TDM 0x2000 /* AIF2ADC_TDM */
1880#define WM8995_AIF2ADC_TDM_MASK 0x2000 /* AIF2ADC_TDM */
1881#define WM8995_AIF2ADC_TDM_SHIFT 13 /* AIF2ADC_TDM */
1882#define WM8995_AIF2ADC_TDM_WIDTH 1 /* AIF2ADC_TDM */
1883#define WM8995_AIF2ADC_TDM_CHAN 0x1000 /* AIF2ADC_TDM_CHAN */
1884#define WM8995_AIF2ADC_TDM_CHAN_MASK 0x1000 /* AIF2ADC_TDM_CHAN */
1885#define WM8995_AIF2ADC_TDM_CHAN_SHIFT 12 /* AIF2ADC_TDM_CHAN */
1886#define WM8995_AIF2ADC_TDM_CHAN_WIDTH 1 /* AIF2ADC_TDM_CHAN */
1887#define WM8995_AIF2_BCLK_INV 0x0100 /* AIF2_BCLK_INV */
1888#define WM8995_AIF2_BCLK_INV_MASK 0x0100 /* AIF2_BCLK_INV */
1889#define WM8995_AIF2_BCLK_INV_SHIFT 8 /* AIF2_BCLK_INV */
1890#define WM8995_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */
1891#define WM8995_AIF2_LRCLK_INV 0x0080 /* AIF2_LRCLK_INV */
1892#define WM8995_AIF2_LRCLK_INV_MASK 0x0080 /* AIF2_LRCLK_INV */
1893#define WM8995_AIF2_LRCLK_INV_SHIFT 7 /* AIF2_LRCLK_INV */
1894#define WM8995_AIF2_LRCLK_INV_WIDTH 1 /* AIF2_LRCLK_INV */
1895#define WM8995_AIF2_WL_MASK 0x0060 /* AIF2_WL - [6:5] */
1896#define WM8995_AIF2_WL_SHIFT 5 /* AIF2_WL - [6:5] */
1897#define WM8995_AIF2_WL_WIDTH 2 /* AIF2_WL - [6:5] */
1898#define WM8995_AIF2_FMT_MASK 0x0018 /* AIF2_FMT - [4:3] */
1899#define WM8995_AIF2_FMT_SHIFT 3 /* AIF2_FMT - [4:3] */
1900#define WM8995_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [4:3] */
1901
1902/*
1903 * R785 (0x311) - AIF2 Control (2)
1904 */
1905#define WM8995_AIF2DACL_SRC 0x8000 /* AIF2DACL_SRC */
1906#define WM8995_AIF2DACL_SRC_MASK 0x8000 /* AIF2DACL_SRC */
1907#define WM8995_AIF2DACL_SRC_SHIFT 15 /* AIF2DACL_SRC */
1908#define WM8995_AIF2DACL_SRC_WIDTH 1 /* AIF2DACL_SRC */
1909#define WM8995_AIF2DACR_SRC 0x4000 /* AIF2DACR_SRC */
1910#define WM8995_AIF2DACR_SRC_MASK 0x4000 /* AIF2DACR_SRC */
1911#define WM8995_AIF2DACR_SRC_SHIFT 14 /* AIF2DACR_SRC */
1912#define WM8995_AIF2DACR_SRC_WIDTH 1 /* AIF2DACR_SRC */
1913#define WM8995_AIF2DAC_TDM 0x2000 /* AIF2DAC_TDM */
1914#define WM8995_AIF2DAC_TDM_MASK 0x2000 /* AIF2DAC_TDM */
1915#define WM8995_AIF2DAC_TDM_SHIFT 13 /* AIF2DAC_TDM */
1916#define WM8995_AIF2DAC_TDM_WIDTH 1 /* AIF2DAC_TDM */
1917#define WM8995_AIF2DAC_TDM_CHAN 0x1000 /* AIF2DAC_TDM_CHAN */
1918#define WM8995_AIF2DAC_TDM_CHAN_MASK 0x1000 /* AIF2DAC_TDM_CHAN */
1919#define WM8995_AIF2DAC_TDM_CHAN_SHIFT 12 /* AIF2DAC_TDM_CHAN */
1920#define WM8995_AIF2DAC_TDM_CHAN_WIDTH 1 /* AIF2DAC_TDM_CHAN */
1921#define WM8995_AIF2DAC_BOOST_MASK 0x0C00 /* AIF2DAC_BOOST - [11:10] */
1922#define WM8995_AIF2DAC_BOOST_SHIFT 10 /* AIF2DAC_BOOST - [11:10] */
1923#define WM8995_AIF2DAC_BOOST_WIDTH 2 /* AIF2DAC_BOOST - [11:10] */
1924#define WM8995_AIF2DAC_COMP 0x0010 /* AIF2DAC_COMP */
1925#define WM8995_AIF2DAC_COMP_MASK 0x0010 /* AIF2DAC_COMP */
1926#define WM8995_AIF2DAC_COMP_SHIFT 4 /* AIF2DAC_COMP */
1927#define WM8995_AIF2DAC_COMP_WIDTH 1 /* AIF2DAC_COMP */
1928#define WM8995_AIF2DAC_COMPMODE 0x0008 /* AIF2DAC_COMPMODE */
1929#define WM8995_AIF2DAC_COMPMODE_MASK 0x0008 /* AIF2DAC_COMPMODE */
1930#define WM8995_AIF2DAC_COMPMODE_SHIFT 3 /* AIF2DAC_COMPMODE */
1931#define WM8995_AIF2DAC_COMPMODE_WIDTH 1 /* AIF2DAC_COMPMODE */
1932#define WM8995_AIF2ADC_COMP 0x0004 /* AIF2ADC_COMP */
1933#define WM8995_AIF2ADC_COMP_MASK 0x0004 /* AIF2ADC_COMP */
1934#define WM8995_AIF2ADC_COMP_SHIFT 2 /* AIF2ADC_COMP */
1935#define WM8995_AIF2ADC_COMP_WIDTH 1 /* AIF2ADC_COMP */
1936#define WM8995_AIF2ADC_COMPMODE 0x0002 /* AIF2ADC_COMPMODE */
1937#define WM8995_AIF2ADC_COMPMODE_MASK 0x0002 /* AIF2ADC_COMPMODE */
1938#define WM8995_AIF2ADC_COMPMODE_SHIFT 1 /* AIF2ADC_COMPMODE */
1939#define WM8995_AIF2ADC_COMPMODE_WIDTH 1 /* AIF2ADC_COMPMODE */
1940#define WM8995_AIF2_LOOPBACK 0x0001 /* AIF2_LOOPBACK */
1941#define WM8995_AIF2_LOOPBACK_MASK 0x0001 /* AIF2_LOOPBACK */
1942#define WM8995_AIF2_LOOPBACK_SHIFT 0 /* AIF2_LOOPBACK */
1943#define WM8995_AIF2_LOOPBACK_WIDTH 1 /* AIF2_LOOPBACK */
1944
1945/*
1946 * R786 (0x312) - AIF2 Master/Slave
1947 */
1948#define WM8995_AIF2_TRI 0x8000 /* AIF2_TRI */
1949#define WM8995_AIF2_TRI_MASK 0x8000 /* AIF2_TRI */
1950#define WM8995_AIF2_TRI_SHIFT 15 /* AIF2_TRI */
1951#define WM8995_AIF2_TRI_WIDTH 1 /* AIF2_TRI */
1952#define WM8995_AIF2_MSTR 0x4000 /* AIF2_MSTR */
1953#define WM8995_AIF2_MSTR_MASK 0x4000 /* AIF2_MSTR */
1954#define WM8995_AIF2_MSTR_SHIFT 14 /* AIF2_MSTR */
1955#define WM8995_AIF2_MSTR_WIDTH 1 /* AIF2_MSTR */
1956#define WM8995_AIF2_CLK_FRC 0x2000 /* AIF2_CLK_FRC */
1957#define WM8995_AIF2_CLK_FRC_MASK 0x2000 /* AIF2_CLK_FRC */
1958#define WM8995_AIF2_CLK_FRC_SHIFT 13 /* AIF2_CLK_FRC */
1959#define WM8995_AIF2_CLK_FRC_WIDTH 1 /* AIF2_CLK_FRC */
1960#define WM8995_AIF2_LRCLK_FRC 0x1000 /* AIF2_LRCLK_FRC */
1961#define WM8995_AIF2_LRCLK_FRC_MASK 0x1000 /* AIF2_LRCLK_FRC */
1962#define WM8995_AIF2_LRCLK_FRC_SHIFT 12 /* AIF2_LRCLK_FRC */
1963#define WM8995_AIF2_LRCLK_FRC_WIDTH 1 /* AIF2_LRCLK_FRC */
1964
1965/*
1966 * R787 (0x313) - AIF2 BCLK
1967 */
1968#define WM8995_AIF2_BCLK_DIV_MASK 0x00F0 /* AIF2_BCLK_DIV - [7:4] */
1969#define WM8995_AIF2_BCLK_DIV_SHIFT 4 /* AIF2_BCLK_DIV - [7:4] */
1970#define WM8995_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [7:4] */
1971
1972/*
1973 * R788 (0x314) - AIF2ADC LRCLK
1974 */
1975#define WM8995_AIF2ADC_LRCLK_DIR 0x0800 /* AIF2ADC_LRCLK_DIR */
1976#define WM8995_AIF2ADC_LRCLK_DIR_MASK 0x0800 /* AIF2ADC_LRCLK_DIR */
1977#define WM8995_AIF2ADC_LRCLK_DIR_SHIFT 11 /* AIF2ADC_LRCLK_DIR */
1978#define WM8995_AIF2ADC_LRCLK_DIR_WIDTH 1 /* AIF2ADC_LRCLK_DIR */
1979#define WM8995_AIF2ADC_RATE_MASK 0x07FF /* AIF2ADC_RATE - [10:0] */
1980#define WM8995_AIF2ADC_RATE_SHIFT 0 /* AIF2ADC_RATE - [10:0] */
1981#define WM8995_AIF2ADC_RATE_WIDTH 11 /* AIF2ADC_RATE - [10:0] */
1982
1983/*
1984 * R789 (0x315) - AIF2DAC LRCLK
1985 */
1986#define WM8995_AIF2DAC_LRCLK_DIR 0x0800 /* AIF2DAC_LRCLK_DIR */
1987#define WM8995_AIF2DAC_LRCLK_DIR_MASK 0x0800 /* AIF2DAC_LRCLK_DIR */
1988#define WM8995_AIF2DAC_LRCLK_DIR_SHIFT 11 /* AIF2DAC_LRCLK_DIR */
1989#define WM8995_AIF2DAC_LRCLK_DIR_WIDTH 1 /* AIF2DAC_LRCLK_DIR */
1990#define WM8995_AIF2DAC_RATE_MASK 0x07FF /* AIF2DAC_RATE - [10:0] */
1991#define WM8995_AIF2DAC_RATE_SHIFT 0 /* AIF2DAC_RATE - [10:0] */
1992#define WM8995_AIF2DAC_RATE_WIDTH 11 /* AIF2DAC_RATE - [10:0] */
1993
1994/*
1995 * R790 (0x316) - AIF2DAC Data
1996 */
1997#define WM8995_AIF2DACL_DAT_INV 0x0002 /* AIF2DACL_DAT_INV */
1998#define WM8995_AIF2DACL_DAT_INV_MASK 0x0002 /* AIF2DACL_DAT_INV */
1999#define WM8995_AIF2DACL_DAT_INV_SHIFT 1 /* AIF2DACL_DAT_INV */
2000#define WM8995_AIF2DACL_DAT_INV_WIDTH 1 /* AIF2DACL_DAT_INV */
2001#define WM8995_AIF2DACR_DAT_INV 0x0001 /* AIF2DACR_DAT_INV */
2002#define WM8995_AIF2DACR_DAT_INV_MASK 0x0001 /* AIF2DACR_DAT_INV */
2003#define WM8995_AIF2DACR_DAT_INV_SHIFT 0 /* AIF2DACR_DAT_INV */
2004#define WM8995_AIF2DACR_DAT_INV_WIDTH 1 /* AIF2DACR_DAT_INV */
2005
2006/*
2007 * R791 (0x317) - AIF2ADC Data
2008 */
2009#define WM8995_AIF2ADCL_DAT_INV 0x0002 /* AIF2ADCL_DAT_INV */
2010#define WM8995_AIF2ADCL_DAT_INV_MASK 0x0002 /* AIF2ADCL_DAT_INV */
2011#define WM8995_AIF2ADCL_DAT_INV_SHIFT 1 /* AIF2ADCL_DAT_INV */
2012#define WM8995_AIF2ADCL_DAT_INV_WIDTH 1 /* AIF2ADCL_DAT_INV */
2013#define WM8995_AIF2ADCR_DAT_INV 0x0001 /* AIF2ADCR_DAT_INV */
2014#define WM8995_AIF2ADCR_DAT_INV_MASK 0x0001 /* AIF2ADCR_DAT_INV */
2015#define WM8995_AIF2ADCR_DAT_INV_SHIFT 0 /* AIF2ADCR_DAT_INV */
2016#define WM8995_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */
2017
2018/*
2019 * R1024 (0x400) - AIF1 ADC1 Left Volume
2020 */
2021#define WM8995_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
2022#define WM8995_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
2023#define WM8995_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
2024#define WM8995_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
2025#define WM8995_AIF1ADC1L_VOL_MASK 0x00FF /* AIF1ADC1L_VOL - [7:0] */
2026#define WM8995_AIF1ADC1L_VOL_SHIFT 0 /* AIF1ADC1L_VOL - [7:0] */
2027#define WM8995_AIF1ADC1L_VOL_WIDTH 8 /* AIF1ADC1L_VOL - [7:0] */
2028
2029/*
2030 * R1025 (0x401) - AIF1 ADC1 Right Volume
2031 */
2032#define WM8995_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */
2033#define WM8995_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */
2034#define WM8995_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */
2035#define WM8995_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */
2036#define WM8995_AIF1ADC1R_VOL_MASK 0x00FF /* AIF1ADC1R_VOL - [7:0] */
2037#define WM8995_AIF1ADC1R_VOL_SHIFT 0 /* AIF1ADC1R_VOL - [7:0] */
2038#define WM8995_AIF1ADC1R_VOL_WIDTH 8 /* AIF1ADC1R_VOL - [7:0] */
2039
2040/*
2041 * R1026 (0x402) - AIF1 DAC1 Left Volume
2042 */
2043#define WM8995_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
2044#define WM8995_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
2045#define WM8995_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
2046#define WM8995_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
2047#define WM8995_AIF1DAC1L_VOL_MASK 0x00FF /* AIF1DAC1L_VOL - [7:0] */
2048#define WM8995_AIF1DAC1L_VOL_SHIFT 0 /* AIF1DAC1L_VOL - [7:0] */
2049#define WM8995_AIF1DAC1L_VOL_WIDTH 8 /* AIF1DAC1L_VOL - [7:0] */
2050
2051/*
2052 * R1027 (0x403) - AIF1 DAC1 Right Volume
2053 */
2054#define WM8995_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */
2055#define WM8995_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */
2056#define WM8995_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */
2057#define WM8995_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */
2058#define WM8995_AIF1DAC1R_VOL_MASK 0x00FF /* AIF1DAC1R_VOL - [7:0] */
2059#define WM8995_AIF1DAC1R_VOL_SHIFT 0 /* AIF1DAC1R_VOL - [7:0] */
2060#define WM8995_AIF1DAC1R_VOL_WIDTH 8 /* AIF1DAC1R_VOL - [7:0] */
2061
2062/*
2063 * R1028 (0x404) - AIF1 ADC2 Left Volume
2064 */
2065#define WM8995_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
2066#define WM8995_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
2067#define WM8995_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
2068#define WM8995_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
2069#define WM8995_AIF1ADC2L_VOL_MASK 0x00FF /* AIF1ADC2L_VOL - [7:0] */
2070#define WM8995_AIF1ADC2L_VOL_SHIFT 0 /* AIF1ADC2L_VOL - [7:0] */
2071#define WM8995_AIF1ADC2L_VOL_WIDTH 8 /* AIF1ADC2L_VOL - [7:0] */
2072
2073/*
2074 * R1029 (0x405) - AIF1 ADC2 Right Volume
2075 */
2076#define WM8995_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */
2077#define WM8995_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */
2078#define WM8995_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */
2079#define WM8995_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */
2080#define WM8995_AIF1ADC2R_VOL_MASK 0x00FF /* AIF1ADC2R_VOL - [7:0] */
2081#define WM8995_AIF1ADC2R_VOL_SHIFT 0 /* AIF1ADC2R_VOL - [7:0] */
2082#define WM8995_AIF1ADC2R_VOL_WIDTH 8 /* AIF1ADC2R_VOL - [7:0] */
2083
2084/*
2085 * R1030 (0x406) - AIF1 DAC2 Left Volume
2086 */
2087#define WM8995_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
2088#define WM8995_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
2089#define WM8995_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
2090#define WM8995_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
2091#define WM8995_AIF1DAC2L_VOL_MASK 0x00FF /* AIF1DAC2L_VOL - [7:0] */
2092#define WM8995_AIF1DAC2L_VOL_SHIFT 0 /* AIF1DAC2L_VOL - [7:0] */
2093#define WM8995_AIF1DAC2L_VOL_WIDTH 8 /* AIF1DAC2L_VOL - [7:0] */
2094
2095/*
2096 * R1031 (0x407) - AIF1 DAC2 Right Volume
2097 */
2098#define WM8995_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */
2099#define WM8995_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */
2100#define WM8995_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */
2101#define WM8995_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */
2102#define WM8995_AIF1DAC2R_VOL_MASK 0x00FF /* AIF1DAC2R_VOL - [7:0] */
2103#define WM8995_AIF1DAC2R_VOL_SHIFT 0 /* AIF1DAC2R_VOL - [7:0] */
2104#define WM8995_AIF1DAC2R_VOL_WIDTH 8 /* AIF1DAC2R_VOL - [7:0] */
2105
2106/*
2107 * R1040 (0x410) - AIF1 ADC1 Filters
2108 */
2109#define WM8995_AIF1ADC_4FS 0x8000 /* AIF1ADC_4FS */
2110#define WM8995_AIF1ADC_4FS_MASK 0x8000 /* AIF1ADC_4FS */
2111#define WM8995_AIF1ADC_4FS_SHIFT 15 /* AIF1ADC_4FS */
2112#define WM8995_AIF1ADC_4FS_WIDTH 1 /* AIF1ADC_4FS */
2113#define WM8995_AIF1ADC1L_HPF 0x1000 /* AIF1ADC1L_HPF */
2114#define WM8995_AIF1ADC1L_HPF_MASK 0x1000 /* AIF1ADC1L_HPF */
2115#define WM8995_AIF1ADC1L_HPF_SHIFT 12 /* AIF1ADC1L_HPF */
2116#define WM8995_AIF1ADC1L_HPF_WIDTH 1 /* AIF1ADC1L_HPF */
2117#define WM8995_AIF1ADC1R_HPF 0x0800 /* AIF1ADC1R_HPF */
2118#define WM8995_AIF1ADC1R_HPF_MASK 0x0800 /* AIF1ADC1R_HPF */
2119#define WM8995_AIF1ADC1R_HPF_SHIFT 11 /* AIF1ADC1R_HPF */
2120#define WM8995_AIF1ADC1R_HPF_WIDTH 1 /* AIF1ADC1R_HPF */
2121#define WM8995_AIF1ADC1_HPF_MODE 0x0008 /* AIF1ADC1_HPF_MODE */
2122#define WM8995_AIF1ADC1_HPF_MODE_MASK 0x0008 /* AIF1ADC1_HPF_MODE */
2123#define WM8995_AIF1ADC1_HPF_MODE_SHIFT 3 /* AIF1ADC1_HPF_MODE */
2124#define WM8995_AIF1ADC1_HPF_MODE_WIDTH 1 /* AIF1ADC1_HPF_MODE */
2125#define WM8995_AIF1ADC1_HPF_CUT_MASK 0x0007 /* AIF1ADC1_HPF_CUT - [2:0] */
2126#define WM8995_AIF1ADC1_HPF_CUT_SHIFT 0 /* AIF1ADC1_HPF_CUT - [2:0] */
2127#define WM8995_AIF1ADC1_HPF_CUT_WIDTH 3 /* AIF1ADC1_HPF_CUT - [2:0] */
2128
2129/*
2130 * R1041 (0x411) - AIF1 ADC2 Filters
2131 */
2132#define WM8995_AIF1ADC2L_HPF 0x1000 /* AIF1ADC2L_HPF */
2133#define WM8995_AIF1ADC2L_HPF_MASK 0x1000 /* AIF1ADC2L_HPF */
2134#define WM8995_AIF1ADC2L_HPF_SHIFT 12 /* AIF1ADC2L_HPF */
2135#define WM8995_AIF1ADC2L_HPF_WIDTH 1 /* AIF1ADC2L_HPF */
2136#define WM8995_AIF1ADC2R_HPF 0x0800 /* AIF1ADC2R_HPF */
2137#define WM8995_AIF1ADC2R_HPF_MASK 0x0800 /* AIF1ADC2R_HPF */
2138#define WM8995_AIF1ADC2R_HPF_SHIFT 11 /* AIF1ADC2R_HPF */
2139#define WM8995_AIF1ADC2R_HPF_WIDTH 1 /* AIF1ADC2R_HPF */
2140#define WM8995_AIF1ADC2_HPF_MODE 0x0008 /* AIF1ADC2_HPF_MODE */
2141#define WM8995_AIF1ADC2_HPF_MODE_MASK 0x0008 /* AIF1ADC2_HPF_MODE */
2142#define WM8995_AIF1ADC2_HPF_MODE_SHIFT 3 /* AIF1ADC2_HPF_MODE */
2143#define WM8995_AIF1ADC2_HPF_MODE_WIDTH 1 /* AIF1ADC2_HPF_MODE */
2144#define WM8995_AIF1ADC2_HPF_CUT_MASK 0x0007 /* AIF1ADC2_HPF_CUT - [2:0] */
2145#define WM8995_AIF1ADC2_HPF_CUT_SHIFT 0 /* AIF1ADC2_HPF_CUT - [2:0] */
2146#define WM8995_AIF1ADC2_HPF_CUT_WIDTH 3 /* AIF1ADC2_HPF_CUT - [2:0] */
2147
2148/*
2149 * R1056 (0x420) - AIF1 DAC1 Filters (1)
2150 */
2151#define WM8995_AIF1DAC1_MUTE 0x0200 /* AIF1DAC1_MUTE */
2152#define WM8995_AIF1DAC1_MUTE_MASK 0x0200 /* AIF1DAC1_MUTE */
2153#define WM8995_AIF1DAC1_MUTE_SHIFT 9 /* AIF1DAC1_MUTE */
2154#define WM8995_AIF1DAC1_MUTE_WIDTH 1 /* AIF1DAC1_MUTE */
2155#define WM8995_AIF1DAC1_MONO 0x0080 /* AIF1DAC1_MONO */
2156#define WM8995_AIF1DAC1_MONO_MASK 0x0080 /* AIF1DAC1_MONO */
2157#define WM8995_AIF1DAC1_MONO_SHIFT 7 /* AIF1DAC1_MONO */
2158#define WM8995_AIF1DAC1_MONO_WIDTH 1 /* AIF1DAC1_MONO */
2159#define WM8995_AIF1DAC1_MUTERATE 0x0020 /* AIF1DAC1_MUTERATE */
2160#define WM8995_AIF1DAC1_MUTERATE_MASK 0x0020 /* AIF1DAC1_MUTERATE */
2161#define WM8995_AIF1DAC1_MUTERATE_SHIFT 5 /* AIF1DAC1_MUTERATE */
2162#define WM8995_AIF1DAC1_MUTERATE_WIDTH 1 /* AIF1DAC1_MUTERATE */
2163#define WM8995_AIF1DAC1_UNMUTE_RAMP 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
2164#define WM8995_AIF1DAC1_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC1_UNMUTE_RAMP */
2165#define WM8995_AIF1DAC1_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC1_UNMUTE_RAMP */
2166#define WM8995_AIF1DAC1_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC1_UNMUTE_RAMP */
2167#define WM8995_AIF1DAC1_DEEMP_MASK 0x0006 /* AIF1DAC1_DEEMP - [2:1] */
2168#define WM8995_AIF1DAC1_DEEMP_SHIFT 1 /* AIF1DAC1_DEEMP - [2:1] */
2169#define WM8995_AIF1DAC1_DEEMP_WIDTH 2 /* AIF1DAC1_DEEMP - [2:1] */
2170
2171/*
2172 * R1057 (0x421) - AIF1 DAC1 Filters (2)
2173 */
2174#define WM8995_AIF1DAC1_3D_GAIN_MASK 0x3E00 /* AIF1DAC1_3D_GAIN - [13:9] */
2175#define WM8995_AIF1DAC1_3D_GAIN_SHIFT 9 /* AIF1DAC1_3D_GAIN - [13:9] */
2176#define WM8995_AIF1DAC1_3D_GAIN_WIDTH 5 /* AIF1DAC1_3D_GAIN - [13:9] */
2177#define WM8995_AIF1DAC1_3D_ENA 0x0100 /* AIF1DAC1_3D_ENA */
2178#define WM8995_AIF1DAC1_3D_ENA_MASK 0x0100 /* AIF1DAC1_3D_ENA */
2179#define WM8995_AIF1DAC1_3D_ENA_SHIFT 8 /* AIF1DAC1_3D_ENA */
2180#define WM8995_AIF1DAC1_3D_ENA_WIDTH 1 /* AIF1DAC1_3D_ENA */
2181
2182/*
2183 * R1058 (0x422) - AIF1 DAC2 Filters (1)
2184 */
2185#define WM8995_AIF1DAC2_MUTE 0x0200 /* AIF1DAC2_MUTE */
2186#define WM8995_AIF1DAC2_MUTE_MASK 0x0200 /* AIF1DAC2_MUTE */
2187#define WM8995_AIF1DAC2_MUTE_SHIFT 9 /* AIF1DAC2_MUTE */
2188#define WM8995_AIF1DAC2_MUTE_WIDTH 1 /* AIF1DAC2_MUTE */
2189#define WM8995_AIF1DAC2_MONO 0x0080 /* AIF1DAC2_MONO */
2190#define WM8995_AIF1DAC2_MONO_MASK 0x0080 /* AIF1DAC2_MONO */
2191#define WM8995_AIF1DAC2_MONO_SHIFT 7 /* AIF1DAC2_MONO */
2192#define WM8995_AIF1DAC2_MONO_WIDTH 1 /* AIF1DAC2_MONO */
2193#define WM8995_AIF1DAC2_MUTERATE 0x0020 /* AIF1DAC2_MUTERATE */
2194#define WM8995_AIF1DAC2_MUTERATE_MASK 0x0020 /* AIF1DAC2_MUTERATE */
2195#define WM8995_AIF1DAC2_MUTERATE_SHIFT 5 /* AIF1DAC2_MUTERATE */
2196#define WM8995_AIF1DAC2_MUTERATE_WIDTH 1 /* AIF1DAC2_MUTERATE */
2197#define WM8995_AIF1DAC2_UNMUTE_RAMP 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
2198#define WM8995_AIF1DAC2_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC2_UNMUTE_RAMP */
2199#define WM8995_AIF1DAC2_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC2_UNMUTE_RAMP */
2200#define WM8995_AIF1DAC2_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC2_UNMUTE_RAMP */
2201#define WM8995_AIF1DAC2_DEEMP_MASK 0x0006 /* AIF1DAC2_DEEMP - [2:1] */
2202#define WM8995_AIF1DAC2_DEEMP_SHIFT 1 /* AIF1DAC2_DEEMP - [2:1] */
2203#define WM8995_AIF1DAC2_DEEMP_WIDTH 2 /* AIF1DAC2_DEEMP - [2:1] */
2204
2205/*
2206 * R1059 (0x423) - AIF1 DAC2 Filters (2)
2207 */
2208#define WM8995_AIF1DAC2_3D_GAIN_MASK 0x3E00 /* AIF1DAC2_3D_GAIN - [13:9] */
2209#define WM8995_AIF1DAC2_3D_GAIN_SHIFT 9 /* AIF1DAC2_3D_GAIN - [13:9] */
2210#define WM8995_AIF1DAC2_3D_GAIN_WIDTH 5 /* AIF1DAC2_3D_GAIN - [13:9] */
2211#define WM8995_AIF1DAC2_3D_ENA 0x0100 /* AIF1DAC2_3D_ENA */
2212#define WM8995_AIF1DAC2_3D_ENA_MASK 0x0100 /* AIF1DAC2_3D_ENA */
2213#define WM8995_AIF1DAC2_3D_ENA_SHIFT 8 /* AIF1DAC2_3D_ENA */
2214#define WM8995_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */
2215
2216/*
2217 * R1088 (0x440) - AIF1 DRC1 (1)
2218 */
2219#define WM8995_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
2220#define WM8995_AIF1DRC1_SIG_DET_RMS_SHIFT 11 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
2221#define WM8995_AIF1DRC1_SIG_DET_RMS_WIDTH 5 /* AIF1DRC1_SIG_DET_RMS - [15:11] */
2222#define WM8995_AIF1DRC1_SIG_DET_PK_MASK 0x0600 /* AIF1DRC1_SIG_DET_PK - [10:9] */
2223#define WM8995_AIF1DRC1_SIG_DET_PK_SHIFT 9 /* AIF1DRC1_SIG_DET_PK - [10:9] */
2224#define WM8995_AIF1DRC1_SIG_DET_PK_WIDTH 2 /* AIF1DRC1_SIG_DET_PK - [10:9] */
2225#define WM8995_AIF1DRC1_NG_ENA 0x0100 /* AIF1DRC1_NG_ENA */
2226#define WM8995_AIF1DRC1_NG_ENA_MASK 0x0100 /* AIF1DRC1_NG_ENA */
2227#define WM8995_AIF1DRC1_NG_ENA_SHIFT 8 /* AIF1DRC1_NG_ENA */
2228#define WM8995_AIF1DRC1_NG_ENA_WIDTH 1 /* AIF1DRC1_NG_ENA */
2229#define WM8995_AIF1DRC1_SIG_DET_MODE 0x0080 /* AIF1DRC1_SIG_DET_MODE */
2230#define WM8995_AIF1DRC1_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC1_SIG_DET_MODE */
2231#define WM8995_AIF1DRC1_SIG_DET_MODE_SHIFT 7 /* AIF1DRC1_SIG_DET_MODE */
2232#define WM8995_AIF1DRC1_SIG_DET_MODE_WIDTH 1 /* AIF1DRC1_SIG_DET_MODE */
2233#define WM8995_AIF1DRC1_SIG_DET 0x0040 /* AIF1DRC1_SIG_DET */
2234#define WM8995_AIF1DRC1_SIG_DET_MASK 0x0040 /* AIF1DRC1_SIG_DET */
2235#define WM8995_AIF1DRC1_SIG_DET_SHIFT 6 /* AIF1DRC1_SIG_DET */
2236#define WM8995_AIF1DRC1_SIG_DET_WIDTH 1 /* AIF1DRC1_SIG_DET */
2237#define WM8995_AIF1DRC1_KNEE2_OP_ENA 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
2238#define WM8995_AIF1DRC1_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */
2239#define WM8995_AIF1DRC1_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC1_KNEE2_OP_ENA */
2240#define WM8995_AIF1DRC1_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC1_KNEE2_OP_ENA */
2241#define WM8995_AIF1DRC1_QR 0x0010 /* AIF1DRC1_QR */
2242#define WM8995_AIF1DRC1_QR_MASK 0x0010 /* AIF1DRC1_QR */
2243#define WM8995_AIF1DRC1_QR_SHIFT 4 /* AIF1DRC1_QR */
2244#define WM8995_AIF1DRC1_QR_WIDTH 1 /* AIF1DRC1_QR */
2245#define WM8995_AIF1DRC1_ANTICLIP 0x0008 /* AIF1DRC1_ANTICLIP */
2246#define WM8995_AIF1DRC1_ANTICLIP_MASK 0x0008 /* AIF1DRC1_ANTICLIP */
2247#define WM8995_AIF1DRC1_ANTICLIP_SHIFT 3 /* AIF1DRC1_ANTICLIP */
2248#define WM8995_AIF1DRC1_ANTICLIP_WIDTH 1 /* AIF1DRC1_ANTICLIP */
2249#define WM8995_AIF1DAC1_DRC_ENA 0x0004 /* AIF1DAC1_DRC_ENA */
2250#define WM8995_AIF1DAC1_DRC_ENA_MASK 0x0004 /* AIF1DAC1_DRC_ENA */
2251#define WM8995_AIF1DAC1_DRC_ENA_SHIFT 2 /* AIF1DAC1_DRC_ENA */
2252#define WM8995_AIF1DAC1_DRC_ENA_WIDTH 1 /* AIF1DAC1_DRC_ENA */
2253#define WM8995_AIF1ADC1L_DRC_ENA 0x0002 /* AIF1ADC1L_DRC_ENA */
2254#define WM8995_AIF1ADC1L_DRC_ENA_MASK 0x0002 /* AIF1ADC1L_DRC_ENA */
2255#define WM8995_AIF1ADC1L_DRC_ENA_SHIFT 1 /* AIF1ADC1L_DRC_ENA */
2256#define WM8995_AIF1ADC1L_DRC_ENA_WIDTH 1 /* AIF1ADC1L_DRC_ENA */
2257#define WM8995_AIF1ADC1R_DRC_ENA 0x0001 /* AIF1ADC1R_DRC_ENA */
2258#define WM8995_AIF1ADC1R_DRC_ENA_MASK 0x0001 /* AIF1ADC1R_DRC_ENA */
2259#define WM8995_AIF1ADC1R_DRC_ENA_SHIFT 0 /* AIF1ADC1R_DRC_ENA */
2260#define WM8995_AIF1ADC1R_DRC_ENA_WIDTH 1 /* AIF1ADC1R_DRC_ENA */
2261
2262/*
2263 * R1089 (0x441) - AIF1 DRC1 (2)
2264 */
2265#define WM8995_AIF1DRC1_ATK_MASK 0x1E00 /* AIF1DRC1_ATK - [12:9] */
2266#define WM8995_AIF1DRC1_ATK_SHIFT 9 /* AIF1DRC1_ATK - [12:9] */
2267#define WM8995_AIF1DRC1_ATK_WIDTH 4 /* AIF1DRC1_ATK - [12:9] */
2268#define WM8995_AIF1DRC1_DCY_MASK 0x01E0 /* AIF1DRC1_DCY - [8:5] */
2269#define WM8995_AIF1DRC1_DCY_SHIFT 5 /* AIF1DRC1_DCY - [8:5] */
2270#define WM8995_AIF1DRC1_DCY_WIDTH 4 /* AIF1DRC1_DCY - [8:5] */
2271#define WM8995_AIF1DRC1_MINGAIN_MASK 0x001C /* AIF1DRC1_MINGAIN - [4:2] */
2272#define WM8995_AIF1DRC1_MINGAIN_SHIFT 2 /* AIF1DRC1_MINGAIN - [4:2] */
2273#define WM8995_AIF1DRC1_MINGAIN_WIDTH 3 /* AIF1DRC1_MINGAIN - [4:2] */
2274#define WM8995_AIF1DRC1_MAXGAIN_MASK 0x0003 /* AIF1DRC1_MAXGAIN - [1:0] */
2275#define WM8995_AIF1DRC1_MAXGAIN_SHIFT 0 /* AIF1DRC1_MAXGAIN - [1:0] */
2276#define WM8995_AIF1DRC1_MAXGAIN_WIDTH 2 /* AIF1DRC1_MAXGAIN - [1:0] */
2277
2278/*
2279 * R1090 (0x442) - AIF1 DRC1 (3)
2280 */
2281#define WM8995_AIF1DRC1_NG_MINGAIN_MASK 0xF000 /* AIF1DRC1_NG_MINGAIN - [15:12] */
2282#define WM8995_AIF1DRC1_NG_MINGAIN_SHIFT 12 /* AIF1DRC1_NG_MINGAIN - [15:12] */
2283#define WM8995_AIF1DRC1_NG_MINGAIN_WIDTH 4 /* AIF1DRC1_NG_MINGAIN - [15:12] */
2284#define WM8995_AIF1DRC1_NG_EXP_MASK 0x0C00 /* AIF1DRC1_NG_EXP - [11:10] */
2285#define WM8995_AIF1DRC1_NG_EXP_SHIFT 10 /* AIF1DRC1_NG_EXP - [11:10] */
2286#define WM8995_AIF1DRC1_NG_EXP_WIDTH 2 /* AIF1DRC1_NG_EXP - [11:10] */
2287#define WM8995_AIF1DRC1_QR_THR_MASK 0x0300 /* AIF1DRC1_QR_THR - [9:8] */
2288#define WM8995_AIF1DRC1_QR_THR_SHIFT 8 /* AIF1DRC1_QR_THR - [9:8] */
2289#define WM8995_AIF1DRC1_QR_THR_WIDTH 2 /* AIF1DRC1_QR_THR - [9:8] */
2290#define WM8995_AIF1DRC1_QR_DCY_MASK 0x00C0 /* AIF1DRC1_QR_DCY - [7:6] */
2291#define WM8995_AIF1DRC1_QR_DCY_SHIFT 6 /* AIF1DRC1_QR_DCY - [7:6] */
2292#define WM8995_AIF1DRC1_QR_DCY_WIDTH 2 /* AIF1DRC1_QR_DCY - [7:6] */
2293#define WM8995_AIF1DRC1_HI_COMP_MASK 0x0038 /* AIF1DRC1_HI_COMP - [5:3] */
2294#define WM8995_AIF1DRC1_HI_COMP_SHIFT 3 /* AIF1DRC1_HI_COMP - [5:3] */
2295#define WM8995_AIF1DRC1_HI_COMP_WIDTH 3 /* AIF1DRC1_HI_COMP - [5:3] */
2296#define WM8995_AIF1DRC1_LO_COMP_MASK 0x0007 /* AIF1DRC1_LO_COMP - [2:0] */
2297#define WM8995_AIF1DRC1_LO_COMP_SHIFT 0 /* AIF1DRC1_LO_COMP - [2:0] */
2298#define WM8995_AIF1DRC1_LO_COMP_WIDTH 3 /* AIF1DRC1_LO_COMP - [2:0] */
2299
2300/*
2301 * R1091 (0x443) - AIF1 DRC1 (4)
2302 */
2303#define WM8995_AIF1DRC1_KNEE_IP_MASK 0x07E0 /* AIF1DRC1_KNEE_IP - [10:5] */
2304#define WM8995_AIF1DRC1_KNEE_IP_SHIFT 5 /* AIF1DRC1_KNEE_IP - [10:5] */
2305#define WM8995_AIF1DRC1_KNEE_IP_WIDTH 6 /* AIF1DRC1_KNEE_IP - [10:5] */
2306#define WM8995_AIF1DRC1_KNEE_OP_MASK 0x001F /* AIF1DRC1_KNEE_OP - [4:0] */
2307#define WM8995_AIF1DRC1_KNEE_OP_SHIFT 0 /* AIF1DRC1_KNEE_OP - [4:0] */
2308#define WM8995_AIF1DRC1_KNEE_OP_WIDTH 5 /* AIF1DRC1_KNEE_OP - [4:0] */
2309
2310/*
2311 * R1092 (0x444) - AIF1 DRC1 (5)
2312 */
2313#define WM8995_AIF1DRC1_KNEE2_IP_MASK 0x03E0 /* AIF1DRC1_KNEE2_IP - [9:5] */
2314#define WM8995_AIF1DRC1_KNEE2_IP_SHIFT 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
2315#define WM8995_AIF1DRC1_KNEE2_IP_WIDTH 5 /* AIF1DRC1_KNEE2_IP - [9:5] */
2316#define WM8995_AIF1DRC1_KNEE2_OP_MASK 0x001F /* AIF1DRC1_KNEE2_OP - [4:0] */
2317#define WM8995_AIF1DRC1_KNEE2_OP_SHIFT 0 /* AIF1DRC1_KNEE2_OP - [4:0] */
2318#define WM8995_AIF1DRC1_KNEE2_OP_WIDTH 5 /* AIF1DRC1_KNEE2_OP - [4:0] */
2319
2320/*
2321 * R1104 (0x450) - AIF1 DRC2 (1)
2322 */
2323#define WM8995_AIF1DRC2_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
2324#define WM8995_AIF1DRC2_SIG_DET_RMS_SHIFT 11 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
2325#define WM8995_AIF1DRC2_SIG_DET_RMS_WIDTH 5 /* AIF1DRC2_SIG_DET_RMS - [15:11] */
2326#define WM8995_AIF1DRC2_SIG_DET_PK_MASK 0x0600 /* AIF1DRC2_SIG_DET_PK - [10:9] */
2327#define WM8995_AIF1DRC2_SIG_DET_PK_SHIFT 9 /* AIF1DRC2_SIG_DET_PK - [10:9] */
2328#define WM8995_AIF1DRC2_SIG_DET_PK_WIDTH 2 /* AIF1DRC2_SIG_DET_PK - [10:9] */
2329#define WM8995_AIF1DRC2_NG_ENA 0x0100 /* AIF1DRC2_NG_ENA */
2330#define WM8995_AIF1DRC2_NG_ENA_MASK 0x0100 /* AIF1DRC2_NG_ENA */
2331#define WM8995_AIF1DRC2_NG_ENA_SHIFT 8 /* AIF1DRC2_NG_ENA */
2332#define WM8995_AIF1DRC2_NG_ENA_WIDTH 1 /* AIF1DRC2_NG_ENA */
2333#define WM8995_AIF1DRC2_SIG_DET_MODE 0x0080 /* AIF1DRC2_SIG_DET_MODE */
2334#define WM8995_AIF1DRC2_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC2_SIG_DET_MODE */
2335#define WM8995_AIF1DRC2_SIG_DET_MODE_SHIFT 7 /* AIF1DRC2_SIG_DET_MODE */
2336#define WM8995_AIF1DRC2_SIG_DET_MODE_WIDTH 1 /* AIF1DRC2_SIG_DET_MODE */
2337#define WM8995_AIF1DRC2_SIG_DET 0x0040 /* AIF1DRC2_SIG_DET */
2338#define WM8995_AIF1DRC2_SIG_DET_MASK 0x0040 /* AIF1DRC2_SIG_DET */
2339#define WM8995_AIF1DRC2_SIG_DET_SHIFT 6 /* AIF1DRC2_SIG_DET */
2340#define WM8995_AIF1DRC2_SIG_DET_WIDTH 1 /* AIF1DRC2_SIG_DET */
2341#define WM8995_AIF1DRC2_KNEE2_OP_ENA 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
2342#define WM8995_AIF1DRC2_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */
2343#define WM8995_AIF1DRC2_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC2_KNEE2_OP_ENA */
2344#define WM8995_AIF1DRC2_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC2_KNEE2_OP_ENA */
2345#define WM8995_AIF1DRC2_QR 0x0010 /* AIF1DRC2_QR */
2346#define WM8995_AIF1DRC2_QR_MASK 0x0010 /* AIF1DRC2_QR */
2347#define WM8995_AIF1DRC2_QR_SHIFT 4 /* AIF1DRC2_QR */
2348#define WM8995_AIF1DRC2_QR_WIDTH 1 /* AIF1DRC2_QR */
2349#define WM8995_AIF1DRC2_ANTICLIP 0x0008 /* AIF1DRC2_ANTICLIP */
2350#define WM8995_AIF1DRC2_ANTICLIP_MASK 0x0008 /* AIF1DRC2_ANTICLIP */
2351#define WM8995_AIF1DRC2_ANTICLIP_SHIFT 3 /* AIF1DRC2_ANTICLIP */
2352#define WM8995_AIF1DRC2_ANTICLIP_WIDTH 1 /* AIF1DRC2_ANTICLIP */
2353#define WM8995_AIF1DAC2_DRC_ENA 0x0004 /* AIF1DAC2_DRC_ENA */
2354#define WM8995_AIF1DAC2_DRC_ENA_MASK 0x0004 /* AIF1DAC2_DRC_ENA */
2355#define WM8995_AIF1DAC2_DRC_ENA_SHIFT 2 /* AIF1DAC2_DRC_ENA */
2356#define WM8995_AIF1DAC2_DRC_ENA_WIDTH 1 /* AIF1DAC2_DRC_ENA */
2357#define WM8995_AIF1ADC2L_DRC_ENA 0x0002 /* AIF1ADC2L_DRC_ENA */
2358#define WM8995_AIF1ADC2L_DRC_ENA_MASK 0x0002 /* AIF1ADC2L_DRC_ENA */
2359#define WM8995_AIF1ADC2L_DRC_ENA_SHIFT 1 /* AIF1ADC2L_DRC_ENA */
2360#define WM8995_AIF1ADC2L_DRC_ENA_WIDTH 1 /* AIF1ADC2L_DRC_ENA */
2361#define WM8995_AIF1ADC2R_DRC_ENA 0x0001 /* AIF1ADC2R_DRC_ENA */
2362#define WM8995_AIF1ADC2R_DRC_ENA_MASK 0x0001 /* AIF1ADC2R_DRC_ENA */
2363#define WM8995_AIF1ADC2R_DRC_ENA_SHIFT 0 /* AIF1ADC2R_DRC_ENA */
2364#define WM8995_AIF1ADC2R_DRC_ENA_WIDTH 1 /* AIF1ADC2R_DRC_ENA */
2365
2366/*
2367 * R1105 (0x451) - AIF1 DRC2 (2)
2368 */
2369#define WM8995_AIF1DRC2_ATK_MASK 0x1E00 /* AIF1DRC2_ATK - [12:9] */
2370#define WM8995_AIF1DRC2_ATK_SHIFT 9 /* AIF1DRC2_ATK - [12:9] */
2371#define WM8995_AIF1DRC2_ATK_WIDTH 4 /* AIF1DRC2_ATK - [12:9] */
2372#define WM8995_AIF1DRC2_DCY_MASK 0x01E0 /* AIF1DRC2_DCY - [8:5] */
2373#define WM8995_AIF1DRC2_DCY_SHIFT 5 /* AIF1DRC2_DCY - [8:5] */
2374#define WM8995_AIF1DRC2_DCY_WIDTH 4 /* AIF1DRC2_DCY - [8:5] */
2375#define WM8995_AIF1DRC2_MINGAIN_MASK 0x001C /* AIF1DRC2_MINGAIN - [4:2] */
2376#define WM8995_AIF1DRC2_MINGAIN_SHIFT 2 /* AIF1DRC2_MINGAIN - [4:2] */
2377#define WM8995_AIF1DRC2_MINGAIN_WIDTH 3 /* AIF1DRC2_MINGAIN - [4:2] */
2378#define WM8995_AIF1DRC2_MAXGAIN_MASK 0x0003 /* AIF1DRC2_MAXGAIN - [1:0] */
2379#define WM8995_AIF1DRC2_MAXGAIN_SHIFT 0 /* AIF1DRC2_MAXGAIN - [1:0] */
2380#define WM8995_AIF1DRC2_MAXGAIN_WIDTH 2 /* AIF1DRC2_MAXGAIN - [1:0] */
2381
2382/*
2383 * R1106 (0x452) - AIF1 DRC2 (3)
2384 */
2385#define WM8995_AIF1DRC2_NG_MINGAIN_MASK 0xF000 /* AIF1DRC2_NG_MINGAIN - [15:12] */
2386#define WM8995_AIF1DRC2_NG_MINGAIN_SHIFT 12 /* AIF1DRC2_NG_MINGAIN - [15:12] */
2387#define WM8995_AIF1DRC2_NG_MINGAIN_WIDTH 4 /* AIF1DRC2_NG_MINGAIN - [15:12] */
2388#define WM8995_AIF1DRC2_NG_EXP_MASK 0x0C00 /* AIF1DRC2_NG_EXP - [11:10] */
2389#define WM8995_AIF1DRC2_NG_EXP_SHIFT 10 /* AIF1DRC2_NG_EXP - [11:10] */
2390#define WM8995_AIF1DRC2_NG_EXP_WIDTH 2 /* AIF1DRC2_NG_EXP - [11:10] */
2391#define WM8995_AIF1DRC2_QR_THR_MASK 0x0300 /* AIF1DRC2_QR_THR - [9:8] */
2392#define WM8995_AIF1DRC2_QR_THR_SHIFT 8 /* AIF1DRC2_QR_THR - [9:8] */
2393#define WM8995_AIF1DRC2_QR_THR_WIDTH 2 /* AIF1DRC2_QR_THR - [9:8] */
2394#define WM8995_AIF1DRC2_QR_DCY_MASK 0x00C0 /* AIF1DRC2_QR_DCY - [7:6] */
2395#define WM8995_AIF1DRC2_QR_DCY_SHIFT 6 /* AIF1DRC2_QR_DCY - [7:6] */
2396#define WM8995_AIF1DRC2_QR_DCY_WIDTH 2 /* AIF1DRC2_QR_DCY - [7:6] */
2397#define WM8995_AIF1DRC2_HI_COMP_MASK 0x0038 /* AIF1DRC2_HI_COMP - [5:3] */
2398#define WM8995_AIF1DRC2_HI_COMP_SHIFT 3 /* AIF1DRC2_HI_COMP - [5:3] */
2399#define WM8995_AIF1DRC2_HI_COMP_WIDTH 3 /* AIF1DRC2_HI_COMP - [5:3] */
2400#define WM8995_AIF1DRC2_LO_COMP_MASK 0x0007 /* AIF1DRC2_LO_COMP - [2:0] */
2401#define WM8995_AIF1DRC2_LO_COMP_SHIFT 0 /* AIF1DRC2_LO_COMP - [2:0] */
2402#define WM8995_AIF1DRC2_LO_COMP_WIDTH 3 /* AIF1DRC2_LO_COMP - [2:0] */
2403
2404/*
2405 * R1107 (0x453) - AIF1 DRC2 (4)
2406 */
2407#define WM8995_AIF1DRC2_KNEE_IP_MASK 0x07E0 /* AIF1DRC2_KNEE_IP - [10:5] */
2408#define WM8995_AIF1DRC2_KNEE_IP_SHIFT 5 /* AIF1DRC2_KNEE_IP - [10:5] */
2409#define WM8995_AIF1DRC2_KNEE_IP_WIDTH 6 /* AIF1DRC2_KNEE_IP - [10:5] */
2410#define WM8995_AIF1DRC2_KNEE_OP_MASK 0x001F /* AIF1DRC2_KNEE_OP - [4:0] */
2411#define WM8995_AIF1DRC2_KNEE_OP_SHIFT 0 /* AIF1DRC2_KNEE_OP - [4:0] */
2412#define WM8995_AIF1DRC2_KNEE_OP_WIDTH 5 /* AIF1DRC2_KNEE_OP - [4:0] */
2413
2414/*
2415 * R1108 (0x454) - AIF1 DRC2 (5)
2416 */
2417#define WM8995_AIF1DRC2_KNEE2_IP_MASK 0x03E0 /* AIF1DRC2_KNEE2_IP - [9:5] */
2418#define WM8995_AIF1DRC2_KNEE2_IP_SHIFT 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
2419#define WM8995_AIF1DRC2_KNEE2_IP_WIDTH 5 /* AIF1DRC2_KNEE2_IP - [9:5] */
2420#define WM8995_AIF1DRC2_KNEE2_OP_MASK 0x001F /* AIF1DRC2_KNEE2_OP - [4:0] */
2421#define WM8995_AIF1DRC2_KNEE2_OP_SHIFT 0 /* AIF1DRC2_KNEE2_OP - [4:0] */
2422#define WM8995_AIF1DRC2_KNEE2_OP_WIDTH 5 /* AIF1DRC2_KNEE2_OP - [4:0] */
2423
2424/*
2425 * R1152 (0x480) - AIF1 DAC1 EQ Gains (1)
2426 */
2427#define WM8995_AIF1DAC1_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
2428#define WM8995_AIF1DAC1_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
2429#define WM8995_AIF1DAC1_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */
2430#define WM8995_AIF1DAC1_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
2431#define WM8995_AIF1DAC1_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
2432#define WM8995_AIF1DAC1_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */
2433#define WM8995_AIF1DAC1_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
2434#define WM8995_AIF1DAC1_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
2435#define WM8995_AIF1DAC1_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */
2436#define WM8995_AIF1DAC1_EQ_ENA 0x0001 /* AIF1DAC1_EQ_ENA */
2437#define WM8995_AIF1DAC1_EQ_ENA_MASK 0x0001 /* AIF1DAC1_EQ_ENA */
2438#define WM8995_AIF1DAC1_EQ_ENA_SHIFT 0 /* AIF1DAC1_EQ_ENA */
2439#define WM8995_AIF1DAC1_EQ_ENA_WIDTH 1 /* AIF1DAC1_EQ_ENA */
2440
2441/*
2442 * R1153 (0x481) - AIF1 DAC1 EQ Gains (2)
2443 */
2444#define WM8995_AIF1DAC1_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
2445#define WM8995_AIF1DAC1_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
2446#define WM8995_AIF1DAC1_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */
2447#define WM8995_AIF1DAC1_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
2448#define WM8995_AIF1DAC1_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
2449#define WM8995_AIF1DAC1_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */
2450
2451/*
2452 * R1154 (0x482) - AIF1 DAC1 EQ Band 1 A
2453 */
2454#define WM8995_AIF1DAC1_EQ_B1_A_MASK 0xFFFF /* AIF1DAC1_EQ_B1_A - [15:0] */
2455#define WM8995_AIF1DAC1_EQ_B1_A_SHIFT 0 /* AIF1DAC1_EQ_B1_A - [15:0] */
2456#define WM8995_AIF1DAC1_EQ_B1_A_WIDTH 16 /* AIF1DAC1_EQ_B1_A - [15:0] */
2457
2458/*
2459 * R1155 (0x483) - AIF1 DAC1 EQ Band 1 B
2460 */
2461#define WM8995_AIF1DAC1_EQ_B1_B_MASK 0xFFFF /* AIF1DAC1_EQ_B1_B - [15:0] */
2462#define WM8995_AIF1DAC1_EQ_B1_B_SHIFT 0 /* AIF1DAC1_EQ_B1_B - [15:0] */
2463#define WM8995_AIF1DAC1_EQ_B1_B_WIDTH 16 /* AIF1DAC1_EQ_B1_B - [15:0] */
2464
2465/*
2466 * R1156 (0x484) - AIF1 DAC1 EQ Band 1 PG
2467 */
2468#define WM8995_AIF1DAC1_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B1_PG - [15:0] */
2469#define WM8995_AIF1DAC1_EQ_B1_PG_SHIFT 0 /* AIF1DAC1_EQ_B1_PG - [15:0] */
2470#define WM8995_AIF1DAC1_EQ_B1_PG_WIDTH 16 /* AIF1DAC1_EQ_B1_PG - [15:0] */
2471
2472/*
2473 * R1157 (0x485) - AIF1 DAC1 EQ Band 2 A
2474 */
2475#define WM8995_AIF1DAC1_EQ_B2_A_MASK 0xFFFF /* AIF1DAC1_EQ_B2_A - [15:0] */
2476#define WM8995_AIF1DAC1_EQ_B2_A_SHIFT 0 /* AIF1DAC1_EQ_B2_A - [15:0] */
2477#define WM8995_AIF1DAC1_EQ_B2_A_WIDTH 16 /* AIF1DAC1_EQ_B2_A - [15:0] */
2478
2479/*
2480 * R1158 (0x486) - AIF1 DAC1 EQ Band 2 B
2481 */
2482#define WM8995_AIF1DAC1_EQ_B2_B_MASK 0xFFFF /* AIF1DAC1_EQ_B2_B - [15:0] */
2483#define WM8995_AIF1DAC1_EQ_B2_B_SHIFT 0 /* AIF1DAC1_EQ_B2_B - [15:0] */
2484#define WM8995_AIF1DAC1_EQ_B2_B_WIDTH 16 /* AIF1DAC1_EQ_B2_B - [15:0] */
2485
2486/*
2487 * R1159 (0x487) - AIF1 DAC1 EQ Band 2 C
2488 */
2489#define WM8995_AIF1DAC1_EQ_B2_C_MASK 0xFFFF /* AIF1DAC1_EQ_B2_C - [15:0] */
2490#define WM8995_AIF1DAC1_EQ_B2_C_SHIFT 0 /* AIF1DAC1_EQ_B2_C - [15:0] */
2491#define WM8995_AIF1DAC1_EQ_B2_C_WIDTH 16 /* AIF1DAC1_EQ_B2_C - [15:0] */
2492
2493/*
2494 * R1160 (0x488) - AIF1 DAC1 EQ Band 2 PG
2495 */
2496#define WM8995_AIF1DAC1_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B2_PG - [15:0] */
2497#define WM8995_AIF1DAC1_EQ_B2_PG_SHIFT 0 /* AIF1DAC1_EQ_B2_PG - [15:0] */
2498#define WM8995_AIF1DAC1_EQ_B2_PG_WIDTH 16 /* AIF1DAC1_EQ_B2_PG - [15:0] */
2499
2500/*
2501 * R1161 (0x489) - AIF1 DAC1 EQ Band 3 A
2502 */
2503#define WM8995_AIF1DAC1_EQ_B3_A_MASK 0xFFFF /* AIF1DAC1_EQ_B3_A - [15:0] */
2504#define WM8995_AIF1DAC1_EQ_B3_A_SHIFT 0 /* AIF1DAC1_EQ_B3_A - [15:0] */
2505#define WM8995_AIF1DAC1_EQ_B3_A_WIDTH 16 /* AIF1DAC1_EQ_B3_A - [15:0] */
2506
2507/*
2508 * R1162 (0x48A) - AIF1 DAC1 EQ Band 3 B
2509 */
2510#define WM8995_AIF1DAC1_EQ_B3_B_MASK 0xFFFF /* AIF1DAC1_EQ_B3_B - [15:0] */
2511#define WM8995_AIF1DAC1_EQ_B3_B_SHIFT 0 /* AIF1DAC1_EQ_B3_B - [15:0] */
2512#define WM8995_AIF1DAC1_EQ_B3_B_WIDTH 16 /* AIF1DAC1_EQ_B3_B - [15:0] */
2513
2514/*
2515 * R1163 (0x48B) - AIF1 DAC1 EQ Band 3 C
2516 */
2517#define WM8995_AIF1DAC1_EQ_B3_C_MASK 0xFFFF /* AIF1DAC1_EQ_B3_C - [15:0] */
2518#define WM8995_AIF1DAC1_EQ_B3_C_SHIFT 0 /* AIF1DAC1_EQ_B3_C - [15:0] */
2519#define WM8995_AIF1DAC1_EQ_B3_C_WIDTH 16 /* AIF1DAC1_EQ_B3_C - [15:0] */
2520
2521/*
2522 * R1164 (0x48C) - AIF1 DAC1 EQ Band 3 PG
2523 */
2524#define WM8995_AIF1DAC1_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B3_PG - [15:0] */
2525#define WM8995_AIF1DAC1_EQ_B3_PG_SHIFT 0 /* AIF1DAC1_EQ_B3_PG - [15:0] */
2526#define WM8995_AIF1DAC1_EQ_B3_PG_WIDTH 16 /* AIF1DAC1_EQ_B3_PG - [15:0] */
2527
2528/*
2529 * R1165 (0x48D) - AIF1 DAC1 EQ Band 4 A
2530 */
2531#define WM8995_AIF1DAC1_EQ_B4_A_MASK 0xFFFF /* AIF1DAC1_EQ_B4_A - [15:0] */
2532#define WM8995_AIF1DAC1_EQ_B4_A_SHIFT 0 /* AIF1DAC1_EQ_B4_A - [15:0] */
2533#define WM8995_AIF1DAC1_EQ_B4_A_WIDTH 16 /* AIF1DAC1_EQ_B4_A - [15:0] */
2534
2535/*
2536 * R1166 (0x48E) - AIF1 DAC1 EQ Band 4 B
2537 */
2538#define WM8995_AIF1DAC1_EQ_B4_B_MASK 0xFFFF /* AIF1DAC1_EQ_B4_B - [15:0] */
2539#define WM8995_AIF1DAC1_EQ_B4_B_SHIFT 0 /* AIF1DAC1_EQ_B4_B - [15:0] */
2540#define WM8995_AIF1DAC1_EQ_B4_B_WIDTH 16 /* AIF1DAC1_EQ_B4_B - [15:0] */
2541
2542/*
2543 * R1167 (0x48F) - AIF1 DAC1 EQ Band 4 C
2544 */
2545#define WM8995_AIF1DAC1_EQ_B4_C_MASK 0xFFFF /* AIF1DAC1_EQ_B4_C - [15:0] */
2546#define WM8995_AIF1DAC1_EQ_B4_C_SHIFT 0 /* AIF1DAC1_EQ_B4_C - [15:0] */
2547#define WM8995_AIF1DAC1_EQ_B4_C_WIDTH 16 /* AIF1DAC1_EQ_B4_C - [15:0] */
2548
2549/*
2550 * R1168 (0x490) - AIF1 DAC1 EQ Band 4 PG
2551 */
2552#define WM8995_AIF1DAC1_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B4_PG - [15:0] */
2553#define WM8995_AIF1DAC1_EQ_B4_PG_SHIFT 0 /* AIF1DAC1_EQ_B4_PG - [15:0] */
2554#define WM8995_AIF1DAC1_EQ_B4_PG_WIDTH 16 /* AIF1DAC1_EQ_B4_PG - [15:0] */
2555
2556/*
2557 * R1169 (0x491) - AIF1 DAC1 EQ Band 5 A
2558 */
2559#define WM8995_AIF1DAC1_EQ_B5_A_MASK 0xFFFF /* AIF1DAC1_EQ_B5_A - [15:0] */
2560#define WM8995_AIF1DAC1_EQ_B5_A_SHIFT 0 /* AIF1DAC1_EQ_B5_A - [15:0] */
2561#define WM8995_AIF1DAC1_EQ_B5_A_WIDTH 16 /* AIF1DAC1_EQ_B5_A - [15:0] */
2562
2563/*
2564 * R1170 (0x492) - AIF1 DAC1 EQ Band 5 B
2565 */
2566#define WM8995_AIF1DAC1_EQ_B5_B_MASK 0xFFFF /* AIF1DAC1_EQ_B5_B - [15:0] */
2567#define WM8995_AIF1DAC1_EQ_B5_B_SHIFT 0 /* AIF1DAC1_EQ_B5_B - [15:0] */
2568#define WM8995_AIF1DAC1_EQ_B5_B_WIDTH 16 /* AIF1DAC1_EQ_B5_B - [15:0] */
2569
2570/*
2571 * R1171 (0x493) - AIF1 DAC1 EQ Band 5 PG
2572 */
2573#define WM8995_AIF1DAC1_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B5_PG - [15:0] */
2574#define WM8995_AIF1DAC1_EQ_B5_PG_SHIFT 0 /* AIF1DAC1_EQ_B5_PG - [15:0] */
2575#define WM8995_AIF1DAC1_EQ_B5_PG_WIDTH 16 /* AIF1DAC1_EQ_B5_PG - [15:0] */
2576
2577/*
2578 * R1184 (0x4A0) - AIF1 DAC2 EQ Gains (1)
2579 */
2580#define WM8995_AIF1DAC2_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
2581#define WM8995_AIF1DAC2_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
2582#define WM8995_AIF1DAC2_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */
2583#define WM8995_AIF1DAC2_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
2584#define WM8995_AIF1DAC2_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
2585#define WM8995_AIF1DAC2_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */
2586#define WM8995_AIF1DAC2_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
2587#define WM8995_AIF1DAC2_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
2588#define WM8995_AIF1DAC2_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */
2589#define WM8995_AIF1DAC2_EQ_ENA 0x0001 /* AIF1DAC2_EQ_ENA */
2590#define WM8995_AIF1DAC2_EQ_ENA_MASK 0x0001 /* AIF1DAC2_EQ_ENA */
2591#define WM8995_AIF1DAC2_EQ_ENA_SHIFT 0 /* AIF1DAC2_EQ_ENA */
2592#define WM8995_AIF1DAC2_EQ_ENA_WIDTH 1 /* AIF1DAC2_EQ_ENA */
2593
2594/*
2595 * R1185 (0x4A1) - AIF1 DAC2 EQ Gains (2)
2596 */
2597#define WM8995_AIF1DAC2_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
2598#define WM8995_AIF1DAC2_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
2599#define WM8995_AIF1DAC2_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */
2600#define WM8995_AIF1DAC2_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
2601#define WM8995_AIF1DAC2_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
2602#define WM8995_AIF1DAC2_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */
2603
2604/*
2605 * R1186 (0x4A2) - AIF1 DAC2 EQ Band 1 A
2606 */
2607#define WM8995_AIF1DAC2_EQ_B1_A_MASK 0xFFFF /* AIF1DAC2_EQ_B1_A - [15:0] */
2608#define WM8995_AIF1DAC2_EQ_B1_A_SHIFT 0 /* AIF1DAC2_EQ_B1_A - [15:0] */
2609#define WM8995_AIF1DAC2_EQ_B1_A_WIDTH 16 /* AIF1DAC2_EQ_B1_A - [15:0] */
2610
2611/*
2612 * R1187 (0x4A3) - AIF1 DAC2 EQ Band 1 B
2613 */
2614#define WM8995_AIF1DAC2_EQ_B1_B_MASK 0xFFFF /* AIF1DAC2_EQ_B1_B - [15:0] */
2615#define WM8995_AIF1DAC2_EQ_B1_B_SHIFT 0 /* AIF1DAC2_EQ_B1_B - [15:0] */
2616#define WM8995_AIF1DAC2_EQ_B1_B_WIDTH 16 /* AIF1DAC2_EQ_B1_B - [15:0] */
2617
2618/*
2619 * R1188 (0x4A4) - AIF1 DAC2 EQ Band 1 PG
2620 */
2621#define WM8995_AIF1DAC2_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B1_PG - [15:0] */
2622#define WM8995_AIF1DAC2_EQ_B1_PG_SHIFT 0 /* AIF1DAC2_EQ_B1_PG - [15:0] */
2623#define WM8995_AIF1DAC2_EQ_B1_PG_WIDTH 16 /* AIF1DAC2_EQ_B1_PG - [15:0] */
2624
2625/*
2626 * R1189 (0x4A5) - AIF1 DAC2 EQ Band 2 A
2627 */
2628#define WM8995_AIF1DAC2_EQ_B2_A_MASK 0xFFFF /* AIF1DAC2_EQ_B2_A - [15:0] */
2629#define WM8995_AIF1DAC2_EQ_B2_A_SHIFT 0 /* AIF1DAC2_EQ_B2_A - [15:0] */
2630#define WM8995_AIF1DAC2_EQ_B2_A_WIDTH 16 /* AIF1DAC2_EQ_B2_A - [15:0] */
2631
2632/*
2633 * R1190 (0x4A6) - AIF1 DAC2 EQ Band 2 B
2634 */
2635#define WM8995_AIF1DAC2_EQ_B2_B_MASK 0xFFFF /* AIF1DAC2_EQ_B2_B - [15:0] */
2636#define WM8995_AIF1DAC2_EQ_B2_B_SHIFT 0 /* AIF1DAC2_EQ_B2_B - [15:0] */
2637#define WM8995_AIF1DAC2_EQ_B2_B_WIDTH 16 /* AIF1DAC2_EQ_B2_B - [15:0] */
2638
2639/*
2640 * R1191 (0x4A7) - AIF1 DAC2 EQ Band 2 C
2641 */
2642#define WM8995_AIF1DAC2_EQ_B2_C_MASK 0xFFFF /* AIF1DAC2_EQ_B2_C - [15:0] */
2643#define WM8995_AIF1DAC2_EQ_B2_C_SHIFT 0 /* AIF1DAC2_EQ_B2_C - [15:0] */
2644#define WM8995_AIF1DAC2_EQ_B2_C_WIDTH 16 /* AIF1DAC2_EQ_B2_C - [15:0] */
2645
2646/*
2647 * R1192 (0x4A8) - AIF1 DAC2 EQ Band 2 PG
2648 */
2649#define WM8995_AIF1DAC2_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B2_PG - [15:0] */
2650#define WM8995_AIF1DAC2_EQ_B2_PG_SHIFT 0 /* AIF1DAC2_EQ_B2_PG - [15:0] */
2651#define WM8995_AIF1DAC2_EQ_B2_PG_WIDTH 16 /* AIF1DAC2_EQ_B2_PG - [15:0] */
2652
2653/*
2654 * R1193 (0x4A9) - AIF1 DAC2 EQ Band 3 A
2655 */
2656#define WM8995_AIF1DAC2_EQ_B3_A_MASK 0xFFFF /* AIF1DAC2_EQ_B3_A - [15:0] */
2657#define WM8995_AIF1DAC2_EQ_B3_A_SHIFT 0 /* AIF1DAC2_EQ_B3_A - [15:0] */
2658#define WM8995_AIF1DAC2_EQ_B3_A_WIDTH 16 /* AIF1DAC2_EQ_B3_A - [15:0] */
2659
2660/*
2661 * R1194 (0x4AA) - AIF1 DAC2 EQ Band 3 B
2662 */
2663#define WM8995_AIF1DAC2_EQ_B3_B_MASK 0xFFFF /* AIF1DAC2_EQ_B3_B - [15:0] */
2664#define WM8995_AIF1DAC2_EQ_B3_B_SHIFT 0 /* AIF1DAC2_EQ_B3_B - [15:0] */
2665#define WM8995_AIF1DAC2_EQ_B3_B_WIDTH 16 /* AIF1DAC2_EQ_B3_B - [15:0] */
2666
2667/*
2668 * R1195 (0x4AB) - AIF1 DAC2 EQ Band 3 C
2669 */
2670#define WM8995_AIF1DAC2_EQ_B3_C_MASK 0xFFFF /* AIF1DAC2_EQ_B3_C - [15:0] */
2671#define WM8995_AIF1DAC2_EQ_B3_C_SHIFT 0 /* AIF1DAC2_EQ_B3_C - [15:0] */
2672#define WM8995_AIF1DAC2_EQ_B3_C_WIDTH 16 /* AIF1DAC2_EQ_B3_C - [15:0] */
2673
2674/*
2675 * R1196 (0x4AC) - AIF1 DAC2 EQ Band 3 PG
2676 */
2677#define WM8995_AIF1DAC2_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B3_PG - [15:0] */
2678#define WM8995_AIF1DAC2_EQ_B3_PG_SHIFT 0 /* AIF1DAC2_EQ_B3_PG - [15:0] */
2679#define WM8995_AIF1DAC2_EQ_B3_PG_WIDTH 16 /* AIF1DAC2_EQ_B3_PG - [15:0] */
2680
2681/*
2682 * R1197 (0x4AD) - AIF1 DAC2 EQ Band 4 A
2683 */
2684#define WM8995_AIF1DAC2_EQ_B4_A_MASK 0xFFFF /* AIF1DAC2_EQ_B4_A - [15:0] */
2685#define WM8995_AIF1DAC2_EQ_B4_A_SHIFT 0 /* AIF1DAC2_EQ_B4_A - [15:0] */
2686#define WM8995_AIF1DAC2_EQ_B4_A_WIDTH 16 /* AIF1DAC2_EQ_B4_A - [15:0] */
2687
2688/*
2689 * R1198 (0x4AE) - AIF1 DAC2 EQ Band 4 B
2690 */
2691#define WM8995_AIF1DAC2_EQ_B4_B_MASK 0xFFFF /* AIF1DAC2_EQ_B4_B - [15:0] */
2692#define WM8995_AIF1DAC2_EQ_B4_B_SHIFT 0 /* AIF1DAC2_EQ_B4_B - [15:0] */
2693#define WM8995_AIF1DAC2_EQ_B4_B_WIDTH 16 /* AIF1DAC2_EQ_B4_B - [15:0] */
2694
2695/*
2696 * R1199 (0x4AF) - AIF1 DAC2 EQ Band 4 C
2697 */
2698#define WM8995_AIF1DAC2_EQ_B4_C_MASK 0xFFFF /* AIF1DAC2_EQ_B4_C - [15:0] */
2699#define WM8995_AIF1DAC2_EQ_B4_C_SHIFT 0 /* AIF1DAC2_EQ_B4_C - [15:0] */
2700#define WM8995_AIF1DAC2_EQ_B4_C_WIDTH 16 /* AIF1DAC2_EQ_B4_C - [15:0] */
2701
2702/*
2703 * R1200 (0x4B0) - AIF1 DAC2 EQ Band 4 PG
2704 */
2705#define WM8995_AIF1DAC2_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B4_PG - [15:0] */
2706#define WM8995_AIF1DAC2_EQ_B4_PG_SHIFT 0 /* AIF1DAC2_EQ_B4_PG - [15:0] */
2707#define WM8995_AIF1DAC2_EQ_B4_PG_WIDTH 16 /* AIF1DAC2_EQ_B4_PG - [15:0] */
2708
2709/*
2710 * R1201 (0x4B1) - AIF1 DAC2 EQ Band 5 A
2711 */
2712#define WM8995_AIF1DAC2_EQ_B5_A_MASK 0xFFFF /* AIF1DAC2_EQ_B5_A - [15:0] */
2713#define WM8995_AIF1DAC2_EQ_B5_A_SHIFT 0 /* AIF1DAC2_EQ_B5_A - [15:0] */
2714#define WM8995_AIF1DAC2_EQ_B5_A_WIDTH 16 /* AIF1DAC2_EQ_B5_A - [15:0] */
2715
2716/*
2717 * R1202 (0x4B2) - AIF1 DAC2 EQ Band 5 B
2718 */
2719#define WM8995_AIF1DAC2_EQ_B5_B_MASK 0xFFFF /* AIF1DAC2_EQ_B5_B - [15:0] */
2720#define WM8995_AIF1DAC2_EQ_B5_B_SHIFT 0 /* AIF1DAC2_EQ_B5_B - [15:0] */
2721#define WM8995_AIF1DAC2_EQ_B5_B_WIDTH 16 /* AIF1DAC2_EQ_B5_B - [15:0] */
2722
2723/*
2724 * R1203 (0x4B3) - AIF1 DAC2 EQ Band 5 PG
2725 */
2726#define WM8995_AIF1DAC2_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B5_PG - [15:0] */
2727#define WM8995_AIF1DAC2_EQ_B5_PG_SHIFT 0 /* AIF1DAC2_EQ_B5_PG - [15:0] */
2728#define WM8995_AIF1DAC2_EQ_B5_PG_WIDTH 16 /* AIF1DAC2_EQ_B5_PG - [15:0] */
2729
2730/*
2731 * R1280 (0x500) - AIF2 ADC Left Volume
2732 */
2733#define WM8995_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
2734#define WM8995_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
2735#define WM8995_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
2736#define WM8995_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
2737#define WM8995_AIF2ADCL_VOL_MASK 0x00FF /* AIF2ADCL_VOL - [7:0] */
2738#define WM8995_AIF2ADCL_VOL_SHIFT 0 /* AIF2ADCL_VOL - [7:0] */
2739#define WM8995_AIF2ADCL_VOL_WIDTH 8 /* AIF2ADCL_VOL - [7:0] */
2740
2741/*
2742 * R1281 (0x501) - AIF2 ADC Right Volume
2743 */
2744#define WM8995_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */
2745#define WM8995_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */
2746#define WM8995_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */
2747#define WM8995_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */
2748#define WM8995_AIF2ADCR_VOL_MASK 0x00FF /* AIF2ADCR_VOL - [7:0] */
2749#define WM8995_AIF2ADCR_VOL_SHIFT 0 /* AIF2ADCR_VOL - [7:0] */
2750#define WM8995_AIF2ADCR_VOL_WIDTH 8 /* AIF2ADCR_VOL - [7:0] */
2751
2752/*
2753 * R1282 (0x502) - AIF2 DAC Left Volume
2754 */
2755#define WM8995_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
2756#define WM8995_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
2757#define WM8995_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
2758#define WM8995_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
2759#define WM8995_AIF2DACL_VOL_MASK 0x00FF /* AIF2DACL_VOL - [7:0] */
2760#define WM8995_AIF2DACL_VOL_SHIFT 0 /* AIF2DACL_VOL - [7:0] */
2761#define WM8995_AIF2DACL_VOL_WIDTH 8 /* AIF2DACL_VOL - [7:0] */
2762
2763/*
2764 * R1283 (0x503) - AIF2 DAC Right Volume
2765 */
2766#define WM8995_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */
2767#define WM8995_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */
2768#define WM8995_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */
2769#define WM8995_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */
2770#define WM8995_AIF2DACR_VOL_MASK 0x00FF /* AIF2DACR_VOL - [7:0] */
2771#define WM8995_AIF2DACR_VOL_SHIFT 0 /* AIF2DACR_VOL - [7:0] */
2772#define WM8995_AIF2DACR_VOL_WIDTH 8 /* AIF2DACR_VOL - [7:0] */
2773
2774/*
2775 * R1296 (0x510) - AIF2 ADC Filters
2776 */
2777#define WM8995_AIF2ADC_4FS 0x8000 /* AIF2ADC_4FS */
2778#define WM8995_AIF2ADC_4FS_MASK 0x8000 /* AIF2ADC_4FS */
2779#define WM8995_AIF2ADC_4FS_SHIFT 15 /* AIF2ADC_4FS */
2780#define WM8995_AIF2ADC_4FS_WIDTH 1 /* AIF2ADC_4FS */
2781#define WM8995_AIF2ADCL_HPF 0x1000 /* AIF2ADCL_HPF */
2782#define WM8995_AIF2ADCL_HPF_MASK 0x1000 /* AIF2ADCL_HPF */
2783#define WM8995_AIF2ADCL_HPF_SHIFT 12 /* AIF2ADCL_HPF */
2784#define WM8995_AIF2ADCL_HPF_WIDTH 1 /* AIF2ADCL_HPF */
2785#define WM8995_AIF2ADCR_HPF 0x0800 /* AIF2ADCR_HPF */
2786#define WM8995_AIF2ADCR_HPF_MASK 0x0800 /* AIF2ADCR_HPF */
2787#define WM8995_AIF2ADCR_HPF_SHIFT 11 /* AIF2ADCR_HPF */
2788#define WM8995_AIF2ADCR_HPF_WIDTH 1 /* AIF2ADCR_HPF */
2789#define WM8995_AIF2ADC_HPF_MODE 0x0008 /* AIF2ADC_HPF_MODE */
2790#define WM8995_AIF2ADC_HPF_MODE_MASK 0x0008 /* AIF2ADC_HPF_MODE */
2791#define WM8995_AIF2ADC_HPF_MODE_SHIFT 3 /* AIF2ADC_HPF_MODE */
2792#define WM8995_AIF2ADC_HPF_MODE_WIDTH 1 /* AIF2ADC_HPF_MODE */
2793#define WM8995_AIF2ADC_HPF_CUT_MASK 0x0007 /* AIF2ADC_HPF_CUT - [2:0] */
2794#define WM8995_AIF2ADC_HPF_CUT_SHIFT 0 /* AIF2ADC_HPF_CUT - [2:0] */
2795#define WM8995_AIF2ADC_HPF_CUT_WIDTH 3 /* AIF2ADC_HPF_CUT - [2:0] */
2796
2797/*
2798 * R1312 (0x520) - AIF2 DAC Filters (1)
2799 */
2800#define WM8995_AIF2DAC_MUTE 0x0200 /* AIF2DAC_MUTE */
2801#define WM8995_AIF2DAC_MUTE_MASK 0x0200 /* AIF2DAC_MUTE */
2802#define WM8995_AIF2DAC_MUTE_SHIFT 9 /* AIF2DAC_MUTE */
2803#define WM8995_AIF2DAC_MUTE_WIDTH 1 /* AIF2DAC_MUTE */
2804#define WM8995_AIF2DAC_MONO 0x0080 /* AIF2DAC_MONO */
2805#define WM8995_AIF2DAC_MONO_MASK 0x0080 /* AIF2DAC_MONO */
2806#define WM8995_AIF2DAC_MONO_SHIFT 7 /* AIF2DAC_MONO */
2807#define WM8995_AIF2DAC_MONO_WIDTH 1 /* AIF2DAC_MONO */
2808#define WM8995_AIF2DAC_MUTERATE 0x0020 /* AIF2DAC_MUTERATE */
2809#define WM8995_AIF2DAC_MUTERATE_MASK 0x0020 /* AIF2DAC_MUTERATE */
2810#define WM8995_AIF2DAC_MUTERATE_SHIFT 5 /* AIF2DAC_MUTERATE */
2811#define WM8995_AIF2DAC_MUTERATE_WIDTH 1 /* AIF2DAC_MUTERATE */
2812#define WM8995_AIF2DAC_UNMUTE_RAMP 0x0010 /* AIF2DAC_UNMUTE_RAMP */
2813#define WM8995_AIF2DAC_UNMUTE_RAMP_MASK 0x0010 /* AIF2DAC_UNMUTE_RAMP */
2814#define WM8995_AIF2DAC_UNMUTE_RAMP_SHIFT 4 /* AIF2DAC_UNMUTE_RAMP */
2815#define WM8995_AIF2DAC_UNMUTE_RAMP_WIDTH 1 /* AIF2DAC_UNMUTE_RAMP */
2816#define WM8995_AIF2DAC_DEEMP_MASK 0x0006 /* AIF2DAC_DEEMP - [2:1] */
2817#define WM8995_AIF2DAC_DEEMP_SHIFT 1 /* AIF2DAC_DEEMP - [2:1] */
2818#define WM8995_AIF2DAC_DEEMP_WIDTH 2 /* AIF2DAC_DEEMP - [2:1] */
2819
2820/*
2821 * R1313 (0x521) - AIF2 DAC Filters (2)
2822 */
2823#define WM8995_AIF2DAC_3D_GAIN_MASK 0x3E00 /* AIF2DAC_3D_GAIN - [13:9] */
2824#define WM8995_AIF2DAC_3D_GAIN_SHIFT 9 /* AIF2DAC_3D_GAIN - [13:9] */
2825#define WM8995_AIF2DAC_3D_GAIN_WIDTH 5 /* AIF2DAC_3D_GAIN - [13:9] */
2826#define WM8995_AIF2DAC_3D_ENA 0x0100 /* AIF2DAC_3D_ENA */
2827#define WM8995_AIF2DAC_3D_ENA_MASK 0x0100 /* AIF2DAC_3D_ENA */
2828#define WM8995_AIF2DAC_3D_ENA_SHIFT 8 /* AIF2DAC_3D_ENA */
2829#define WM8995_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */
2830
2831/*
2832 * R1344 (0x540) - AIF2 DRC (1)
2833 */
2834#define WM8995_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */
2835#define WM8995_AIF2DRC_SIG_DET_RMS_SHIFT 11 /* AIF2DRC_SIG_DET_RMS - [15:11] */
2836#define WM8995_AIF2DRC_SIG_DET_RMS_WIDTH 5 /* AIF2DRC_SIG_DET_RMS - [15:11] */
2837#define WM8995_AIF2DRC_SIG_DET_PK_MASK 0x0600 /* AIF2DRC_SIG_DET_PK - [10:9] */
2838#define WM8995_AIF2DRC_SIG_DET_PK_SHIFT 9 /* AIF2DRC_SIG_DET_PK - [10:9] */
2839#define WM8995_AIF2DRC_SIG_DET_PK_WIDTH 2 /* AIF2DRC_SIG_DET_PK - [10:9] */
2840#define WM8995_AIF2DRC_NG_ENA 0x0100 /* AIF2DRC_NG_ENA */
2841#define WM8995_AIF2DRC_NG_ENA_MASK 0x0100 /* AIF2DRC_NG_ENA */
2842#define WM8995_AIF2DRC_NG_ENA_SHIFT 8 /* AIF2DRC_NG_ENA */
2843#define WM8995_AIF2DRC_NG_ENA_WIDTH 1 /* AIF2DRC_NG_ENA */
2844#define WM8995_AIF2DRC_SIG_DET_MODE 0x0080 /* AIF2DRC_SIG_DET_MODE */
2845#define WM8995_AIF2DRC_SIG_DET_MODE_MASK 0x0080 /* AIF2DRC_SIG_DET_MODE */
2846#define WM8995_AIF2DRC_SIG_DET_MODE_SHIFT 7 /* AIF2DRC_SIG_DET_MODE */
2847#define WM8995_AIF2DRC_SIG_DET_MODE_WIDTH 1 /* AIF2DRC_SIG_DET_MODE */
2848#define WM8995_AIF2DRC_SIG_DET 0x0040 /* AIF2DRC_SIG_DET */
2849#define WM8995_AIF2DRC_SIG_DET_MASK 0x0040 /* AIF2DRC_SIG_DET */
2850#define WM8995_AIF2DRC_SIG_DET_SHIFT 6 /* AIF2DRC_SIG_DET */
2851#define WM8995_AIF2DRC_SIG_DET_WIDTH 1 /* AIF2DRC_SIG_DET */
2852#define WM8995_AIF2DRC_KNEE2_OP_ENA 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
2853#define WM8995_AIF2DRC_KNEE2_OP_ENA_MASK 0x0020 /* AIF2DRC_KNEE2_OP_ENA */
2854#define WM8995_AIF2DRC_KNEE2_OP_ENA_SHIFT 5 /* AIF2DRC_KNEE2_OP_ENA */
2855#define WM8995_AIF2DRC_KNEE2_OP_ENA_WIDTH 1 /* AIF2DRC_KNEE2_OP_ENA */
2856#define WM8995_AIF2DRC_QR 0x0010 /* AIF2DRC_QR */
2857#define WM8995_AIF2DRC_QR_MASK 0x0010 /* AIF2DRC_QR */
2858#define WM8995_AIF2DRC_QR_SHIFT 4 /* AIF2DRC_QR */
2859#define WM8995_AIF2DRC_QR_WIDTH 1 /* AIF2DRC_QR */
2860#define WM8995_AIF2DRC_ANTICLIP 0x0008 /* AIF2DRC_ANTICLIP */
2861#define WM8995_AIF2DRC_ANTICLIP_MASK 0x0008 /* AIF2DRC_ANTICLIP */
2862#define WM8995_AIF2DRC_ANTICLIP_SHIFT 3 /* AIF2DRC_ANTICLIP */
2863#define WM8995_AIF2DRC_ANTICLIP_WIDTH 1 /* AIF2DRC_ANTICLIP */
2864#define WM8995_AIF2DAC_DRC_ENA 0x0004 /* AIF2DAC_DRC_ENA */
2865#define WM8995_AIF2DAC_DRC_ENA_MASK 0x0004 /* AIF2DAC_DRC_ENA */
2866#define WM8995_AIF2DAC_DRC_ENA_SHIFT 2 /* AIF2DAC_DRC_ENA */
2867#define WM8995_AIF2DAC_DRC_ENA_WIDTH 1 /* AIF2DAC_DRC_ENA */
2868#define WM8995_AIF2ADCL_DRC_ENA 0x0002 /* AIF2ADCL_DRC_ENA */
2869#define WM8995_AIF2ADCL_DRC_ENA_MASK 0x0002 /* AIF2ADCL_DRC_ENA */
2870#define WM8995_AIF2ADCL_DRC_ENA_SHIFT 1 /* AIF2ADCL_DRC_ENA */
2871#define WM8995_AIF2ADCL_DRC_ENA_WIDTH 1 /* AIF2ADCL_DRC_ENA */
2872#define WM8995_AIF2ADCR_DRC_ENA 0x0001 /* AIF2ADCR_DRC_ENA */
2873#define WM8995_AIF2ADCR_DRC_ENA_MASK 0x0001 /* AIF2ADCR_DRC_ENA */
2874#define WM8995_AIF2ADCR_DRC_ENA_SHIFT 0 /* AIF2ADCR_DRC_ENA */
2875#define WM8995_AIF2ADCR_DRC_ENA_WIDTH 1 /* AIF2ADCR_DRC_ENA */
2876
2877/*
2878 * R1345 (0x541) - AIF2 DRC (2)
2879 */
2880#define WM8995_AIF2DRC_ATK_MASK 0x1E00 /* AIF2DRC_ATK - [12:9] */
2881#define WM8995_AIF2DRC_ATK_SHIFT 9 /* AIF2DRC_ATK - [12:9] */
2882#define WM8995_AIF2DRC_ATK_WIDTH 4 /* AIF2DRC_ATK - [12:9] */
2883#define WM8995_AIF2DRC_DCY_MASK 0x01E0 /* AIF2DRC_DCY - [8:5] */
2884#define WM8995_AIF2DRC_DCY_SHIFT 5 /* AIF2DRC_DCY - [8:5] */
2885#define WM8995_AIF2DRC_DCY_WIDTH 4 /* AIF2DRC_DCY - [8:5] */
2886#define WM8995_AIF2DRC_MINGAIN_MASK 0x001C /* AIF2DRC_MINGAIN - [4:2] */
2887#define WM8995_AIF2DRC_MINGAIN_SHIFT 2 /* AIF2DRC_MINGAIN - [4:2] */
2888#define WM8995_AIF2DRC_MINGAIN_WIDTH 3 /* AIF2DRC_MINGAIN - [4:2] */
2889#define WM8995_AIF2DRC_MAXGAIN_MASK 0x0003 /* AIF2DRC_MAXGAIN - [1:0] */
2890#define WM8995_AIF2DRC_MAXGAIN_SHIFT 0 /* AIF2DRC_MAXGAIN - [1:0] */
2891#define WM8995_AIF2DRC_MAXGAIN_WIDTH 2 /* AIF2DRC_MAXGAIN - [1:0] */
2892
2893/*
2894 * R1346 (0x542) - AIF2 DRC (3)
2895 */
2896#define WM8995_AIF2DRC_NG_MINGAIN_MASK 0xF000 /* AIF2DRC_NG_MINGAIN - [15:12] */
2897#define WM8995_AIF2DRC_NG_MINGAIN_SHIFT 12 /* AIF2DRC_NG_MINGAIN - [15:12] */
2898#define WM8995_AIF2DRC_NG_MINGAIN_WIDTH 4 /* AIF2DRC_NG_MINGAIN - [15:12] */
2899#define WM8995_AIF2DRC_NG_EXP_MASK 0x0C00 /* AIF2DRC_NG_EXP - [11:10] */
2900#define WM8995_AIF2DRC_NG_EXP_SHIFT 10 /* AIF2DRC_NG_EXP - [11:10] */
2901#define WM8995_AIF2DRC_NG_EXP_WIDTH 2 /* AIF2DRC_NG_EXP - [11:10] */
2902#define WM8995_AIF2DRC_QR_THR_MASK 0x0300 /* AIF2DRC_QR_THR - [9:8] */
2903#define WM8995_AIF2DRC_QR_THR_SHIFT 8 /* AIF2DRC_QR_THR - [9:8] */
2904#define WM8995_AIF2DRC_QR_THR_WIDTH 2 /* AIF2DRC_QR_THR - [9:8] */
2905#define WM8995_AIF2DRC_QR_DCY_MASK 0x00C0 /* AIF2DRC_QR_DCY - [7:6] */
2906#define WM8995_AIF2DRC_QR_DCY_SHIFT 6 /* AIF2DRC_QR_DCY - [7:6] */
2907#define WM8995_AIF2DRC_QR_DCY_WIDTH 2 /* AIF2DRC_QR_DCY - [7:6] */
2908#define WM8995_AIF2DRC_HI_COMP_MASK 0x0038 /* AIF2DRC_HI_COMP - [5:3] */
2909#define WM8995_AIF2DRC_HI_COMP_SHIFT 3 /* AIF2DRC_HI_COMP - [5:3] */
2910#define WM8995_AIF2DRC_HI_COMP_WIDTH 3 /* AIF2DRC_HI_COMP - [5:3] */
2911#define WM8995_AIF2DRC_LO_COMP_MASK 0x0007 /* AIF2DRC_LO_COMP - [2:0] */
2912#define WM8995_AIF2DRC_LO_COMP_SHIFT 0 /* AIF2DRC_LO_COMP - [2:0] */
2913#define WM8995_AIF2DRC_LO_COMP_WIDTH 3 /* AIF2DRC_LO_COMP - [2:0] */
2914
2915/*
2916 * R1347 (0x543) - AIF2 DRC (4)
2917 */
2918#define WM8995_AIF2DRC_KNEE_IP_MASK 0x07E0 /* AIF2DRC_KNEE_IP - [10:5] */
2919#define WM8995_AIF2DRC_KNEE_IP_SHIFT 5 /* AIF2DRC_KNEE_IP - [10:5] */
2920#define WM8995_AIF2DRC_KNEE_IP_WIDTH 6 /* AIF2DRC_KNEE_IP - [10:5] */
2921#define WM8995_AIF2DRC_KNEE_OP_MASK 0x001F /* AIF2DRC_KNEE_OP - [4:0] */
2922#define WM8995_AIF2DRC_KNEE_OP_SHIFT 0 /* AIF2DRC_KNEE_OP - [4:0] */
2923#define WM8995_AIF2DRC_KNEE_OP_WIDTH 5 /* AIF2DRC_KNEE_OP - [4:0] */
2924
2925/*
2926 * R1348 (0x544) - AIF2 DRC (5)
2927 */
2928#define WM8995_AIF2DRC_KNEE2_IP_MASK 0x03E0 /* AIF2DRC_KNEE2_IP - [9:5] */
2929#define WM8995_AIF2DRC_KNEE2_IP_SHIFT 5 /* AIF2DRC_KNEE2_IP - [9:5] */
2930#define WM8995_AIF2DRC_KNEE2_IP_WIDTH 5 /* AIF2DRC_KNEE2_IP - [9:5] */
2931#define WM8995_AIF2DRC_KNEE2_OP_MASK 0x001F /* AIF2DRC_KNEE2_OP - [4:0] */
2932#define WM8995_AIF2DRC_KNEE2_OP_SHIFT 0 /* AIF2DRC_KNEE2_OP - [4:0] */
2933#define WM8995_AIF2DRC_KNEE2_OP_WIDTH 5 /* AIF2DRC_KNEE2_OP - [4:0] */
2934
2935/*
2936 * R1408 (0x580) - AIF2 EQ Gains (1)
2937 */
2938#define WM8995_AIF2DAC_EQ_B1_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
2939#define WM8995_AIF2DAC_EQ_B1_GAIN_SHIFT 11 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
2940#define WM8995_AIF2DAC_EQ_B1_GAIN_WIDTH 5 /* AIF2DAC_EQ_B1_GAIN - [15:11] */
2941#define WM8995_AIF2DAC_EQ_B2_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
2942#define WM8995_AIF2DAC_EQ_B2_GAIN_SHIFT 6 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
2943#define WM8995_AIF2DAC_EQ_B2_GAIN_WIDTH 5 /* AIF2DAC_EQ_B2_GAIN - [10:6] */
2944#define WM8995_AIF2DAC_EQ_B3_GAIN_MASK 0x003E /* AIF2DAC_EQ_B3_GAIN - [5:1] */
2945#define WM8995_AIF2DAC_EQ_B3_GAIN_SHIFT 1 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
2946#define WM8995_AIF2DAC_EQ_B3_GAIN_WIDTH 5 /* AIF2DAC_EQ_B3_GAIN - [5:1] */
2947#define WM8995_AIF2DAC_EQ_ENA 0x0001 /* AIF2DAC_EQ_ENA */
2948#define WM8995_AIF2DAC_EQ_ENA_MASK 0x0001 /* AIF2DAC_EQ_ENA */
2949#define WM8995_AIF2DAC_EQ_ENA_SHIFT 0 /* AIF2DAC_EQ_ENA */
2950#define WM8995_AIF2DAC_EQ_ENA_WIDTH 1 /* AIF2DAC_EQ_ENA */
2951
2952/*
2953 * R1409 (0x581) - AIF2 EQ Gains (2)
2954 */
2955#define WM8995_AIF2DAC_EQ_B4_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
2956#define WM8995_AIF2DAC_EQ_B4_GAIN_SHIFT 11 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
2957#define WM8995_AIF2DAC_EQ_B4_GAIN_WIDTH 5 /* AIF2DAC_EQ_B4_GAIN - [15:11] */
2958#define WM8995_AIF2DAC_EQ_B5_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
2959#define WM8995_AIF2DAC_EQ_B5_GAIN_SHIFT 6 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
2960#define WM8995_AIF2DAC_EQ_B5_GAIN_WIDTH 5 /* AIF2DAC_EQ_B5_GAIN - [10:6] */
2961
2962/*
2963 * R1410 (0x582) - AIF2 EQ Band 1 A
2964 */
2965#define WM8995_AIF2DAC_EQ_B1_A_MASK 0xFFFF /* AIF2DAC_EQ_B1_A - [15:0] */
2966#define WM8995_AIF2DAC_EQ_B1_A_SHIFT 0 /* AIF2DAC_EQ_B1_A - [15:0] */
2967#define WM8995_AIF2DAC_EQ_B1_A_WIDTH 16 /* AIF2DAC_EQ_B1_A - [15:0] */
2968
2969/*
2970 * R1411 (0x583) - AIF2 EQ Band 1 B
2971 */
2972#define WM8995_AIF2DAC_EQ_B1_B_MASK 0xFFFF /* AIF2DAC_EQ_B1_B - [15:0] */
2973#define WM8995_AIF2DAC_EQ_B1_B_SHIFT 0 /* AIF2DAC_EQ_B1_B - [15:0] */
2974#define WM8995_AIF2DAC_EQ_B1_B_WIDTH 16 /* AIF2DAC_EQ_B1_B - [15:0] */
2975
2976/*
2977 * R1412 (0x584) - AIF2 EQ Band 1 PG
2978 */
2979#define WM8995_AIF2DAC_EQ_B1_PG_MASK 0xFFFF /* AIF2DAC_EQ_B1_PG - [15:0] */
2980#define WM8995_AIF2DAC_EQ_B1_PG_SHIFT 0 /* AIF2DAC_EQ_B1_PG - [15:0] */
2981#define WM8995_AIF2DAC_EQ_B1_PG_WIDTH 16 /* AIF2DAC_EQ_B1_PG - [15:0] */
2982
2983/*
2984 * R1413 (0x585) - AIF2 EQ Band 2 A
2985 */
2986#define WM8995_AIF2DAC_EQ_B2_A_MASK 0xFFFF /* AIF2DAC_EQ_B2_A - [15:0] */
2987#define WM8995_AIF2DAC_EQ_B2_A_SHIFT 0 /* AIF2DAC_EQ_B2_A - [15:0] */
2988#define WM8995_AIF2DAC_EQ_B2_A_WIDTH 16 /* AIF2DAC_EQ_B2_A - [15:0] */
2989
2990/*
2991 * R1414 (0x586) - AIF2 EQ Band 2 B
2992 */
2993#define WM8995_AIF2DAC_EQ_B2_B_MASK 0xFFFF /* AIF2DAC_EQ_B2_B - [15:0] */
2994#define WM8995_AIF2DAC_EQ_B2_B_SHIFT 0 /* AIF2DAC_EQ_B2_B - [15:0] */
2995#define WM8995_AIF2DAC_EQ_B2_B_WIDTH 16 /* AIF2DAC_EQ_B2_B - [15:0] */
2996
2997/*
2998 * R1415 (0x587) - AIF2 EQ Band 2 C
2999 */
3000#define WM8995_AIF2DAC_EQ_B2_C_MASK 0xFFFF /* AIF2DAC_EQ_B2_C - [15:0] */
3001#define WM8995_AIF2DAC_EQ_B2_C_SHIFT 0 /* AIF2DAC_EQ_B2_C - [15:0] */
3002#define WM8995_AIF2DAC_EQ_B2_C_WIDTH 16 /* AIF2DAC_EQ_B2_C - [15:0] */
3003
3004/*
3005 * R1416 (0x588) - AIF2 EQ Band 2 PG
3006 */
3007#define WM8995_AIF2DAC_EQ_B2_PG_MASK 0xFFFF /* AIF2DAC_EQ_B2_PG - [15:0] */
3008#define WM8995_AIF2DAC_EQ_B2_PG_SHIFT 0 /* AIF2DAC_EQ_B2_PG - [15:0] */
3009#define WM8995_AIF2DAC_EQ_B2_PG_WIDTH 16 /* AIF2DAC_EQ_B2_PG - [15:0] */
3010
3011/*
3012 * R1417 (0x589) - AIF2 EQ Band 3 A
3013 */
3014#define WM8995_AIF2DAC_EQ_B3_A_MASK 0xFFFF /* AIF2DAC_EQ_B3_A - [15:0] */
3015#define WM8995_AIF2DAC_EQ_B3_A_SHIFT 0 /* AIF2DAC_EQ_B3_A - [15:0] */
3016#define WM8995_AIF2DAC_EQ_B3_A_WIDTH 16 /* AIF2DAC_EQ_B3_A - [15:0] */
3017
3018/*
3019 * R1418 (0x58A) - AIF2 EQ Band 3 B
3020 */
3021#define WM8995_AIF2DAC_EQ_B3_B_MASK 0xFFFF /* AIF2DAC_EQ_B3_B - [15:0] */
3022#define WM8995_AIF2DAC_EQ_B3_B_SHIFT 0 /* AIF2DAC_EQ_B3_B - [15:0] */
3023#define WM8995_AIF2DAC_EQ_B3_B_WIDTH 16 /* AIF2DAC_EQ_B3_B - [15:0] */
3024
3025/*
3026 * R1419 (0x58B) - AIF2 EQ Band 3 C
3027 */
3028#define WM8995_AIF2DAC_EQ_B3_C_MASK 0xFFFF /* AIF2DAC_EQ_B3_C - [15:0] */
3029#define WM8995_AIF2DAC_EQ_B3_C_SHIFT 0 /* AIF2DAC_EQ_B3_C - [15:0] */
3030#define WM8995_AIF2DAC_EQ_B3_C_WIDTH 16 /* AIF2DAC_EQ_B3_C - [15:0] */
3031
3032/*
3033 * R1420 (0x58C) - AIF2 EQ Band 3 PG
3034 */
3035#define WM8995_AIF2DAC_EQ_B3_PG_MASK 0xFFFF /* AIF2DAC_EQ_B3_PG - [15:0] */
3036#define WM8995_AIF2DAC_EQ_B3_PG_SHIFT 0 /* AIF2DAC_EQ_B3_PG - [15:0] */
3037#define WM8995_AIF2DAC_EQ_B3_PG_WIDTH 16 /* AIF2DAC_EQ_B3_PG - [15:0] */
3038
3039/*
3040 * R1421 (0x58D) - AIF2 EQ Band 4 A
3041 */
3042#define WM8995_AIF2DAC_EQ_B4_A_MASK 0xFFFF /* AIF2DAC_EQ_B4_A - [15:0] */
3043#define WM8995_AIF2DAC_EQ_B4_A_SHIFT 0 /* AIF2DAC_EQ_B4_A - [15:0] */
3044#define WM8995_AIF2DAC_EQ_B4_A_WIDTH 16 /* AIF2DAC_EQ_B4_A - [15:0] */
3045
3046/*
3047 * R1422 (0x58E) - AIF2 EQ Band 4 B
3048 */
3049#define WM8995_AIF2DAC_EQ_B4_B_MASK 0xFFFF /* AIF2DAC_EQ_B4_B - [15:0] */
3050#define WM8995_AIF2DAC_EQ_B4_B_SHIFT 0 /* AIF2DAC_EQ_B4_B - [15:0] */
3051#define WM8995_AIF2DAC_EQ_B4_B_WIDTH 16 /* AIF2DAC_EQ_B4_B - [15:0] */
3052
3053/*
3054 * R1423 (0x58F) - AIF2 EQ Band 4 C
3055 */
3056#define WM8995_AIF2DAC_EQ_B4_C_MASK 0xFFFF /* AIF2DAC_EQ_B4_C - [15:0] */
3057#define WM8995_AIF2DAC_EQ_B4_C_SHIFT 0 /* AIF2DAC_EQ_B4_C - [15:0] */
3058#define WM8995_AIF2DAC_EQ_B4_C_WIDTH 16 /* AIF2DAC_EQ_B4_C - [15:0] */
3059
3060/*
3061 * R1424 (0x590) - AIF2 EQ Band 4 PG
3062 */
3063#define WM8995_AIF2DAC_EQ_B4_PG_MASK 0xFFFF /* AIF2DAC_EQ_B4_PG - [15:0] */
3064#define WM8995_AIF2DAC_EQ_B4_PG_SHIFT 0 /* AIF2DAC_EQ_B4_PG - [15:0] */
3065#define WM8995_AIF2DAC_EQ_B4_PG_WIDTH 16 /* AIF2DAC_EQ_B4_PG - [15:0] */
3066
3067/*
3068 * R1425 (0x591) - AIF2 EQ Band 5 A
3069 */
3070#define WM8995_AIF2DAC_EQ_B5_A_MASK 0xFFFF /* AIF2DAC_EQ_B5_A - [15:0] */
3071#define WM8995_AIF2DAC_EQ_B5_A_SHIFT 0 /* AIF2DAC_EQ_B5_A - [15:0] */
3072#define WM8995_AIF2DAC_EQ_B5_A_WIDTH 16 /* AIF2DAC_EQ_B5_A - [15:0] */
3073
3074/*
3075 * R1426 (0x592) - AIF2 EQ Band 5 B
3076 */
3077#define WM8995_AIF2DAC_EQ_B5_B_MASK 0xFFFF /* AIF2DAC_EQ_B5_B - [15:0] */
3078#define WM8995_AIF2DAC_EQ_B5_B_SHIFT 0 /* AIF2DAC_EQ_B5_B - [15:0] */
3079#define WM8995_AIF2DAC_EQ_B5_B_WIDTH 16 /* AIF2DAC_EQ_B5_B - [15:0] */
3080
3081/*
3082 * R1427 (0x593) - AIF2 EQ Band 5 PG
3083 */
3084#define WM8995_AIF2DAC_EQ_B5_PG_MASK 0xFFFF /* AIF2DAC_EQ_B5_PG - [15:0] */
3085#define WM8995_AIF2DAC_EQ_B5_PG_SHIFT 0 /* AIF2DAC_EQ_B5_PG - [15:0] */
3086#define WM8995_AIF2DAC_EQ_B5_PG_WIDTH 16 /* AIF2DAC_EQ_B5_PG - [15:0] */
3087
3088/*
3089 * R1536 (0x600) - DAC1 Mixer Volumes
3090 */
3091#define WM8995_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */
3092#define WM8995_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */
3093#define WM8995_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */
3094#define WM8995_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */
3095#define WM8995_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */
3096#define WM8995_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */
3097
3098/*
3099 * R1537 (0x601) - DAC1 Left Mixer Routing
3100 */
3101#define WM8995_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */
3102#define WM8995_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */
3103#define WM8995_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */
3104#define WM8995_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */
3105#define WM8995_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */
3106#define WM8995_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */
3107#define WM8995_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */
3108#define WM8995_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */
3109#define WM8995_AIF2DACL_TO_DAC1L 0x0004 /* AIF2DACL_TO_DAC1L */
3110#define WM8995_AIF2DACL_TO_DAC1L_MASK 0x0004 /* AIF2DACL_TO_DAC1L */
3111#define WM8995_AIF2DACL_TO_DAC1L_SHIFT 2 /* AIF2DACL_TO_DAC1L */
3112#define WM8995_AIF2DACL_TO_DAC1L_WIDTH 1 /* AIF2DACL_TO_DAC1L */
3113#define WM8995_AIF1DAC2L_TO_DAC1L 0x0002 /* AIF1DAC2L_TO_DAC1L */
3114#define WM8995_AIF1DAC2L_TO_DAC1L_MASK 0x0002 /* AIF1DAC2L_TO_DAC1L */
3115#define WM8995_AIF1DAC2L_TO_DAC1L_SHIFT 1 /* AIF1DAC2L_TO_DAC1L */
3116#define WM8995_AIF1DAC2L_TO_DAC1L_WIDTH 1 /* AIF1DAC2L_TO_DAC1L */
3117#define WM8995_AIF1DAC1L_TO_DAC1L 0x0001 /* AIF1DAC1L_TO_DAC1L */
3118#define WM8995_AIF1DAC1L_TO_DAC1L_MASK 0x0001 /* AIF1DAC1L_TO_DAC1L */
3119#define WM8995_AIF1DAC1L_TO_DAC1L_SHIFT 0 /* AIF1DAC1L_TO_DAC1L */
3120#define WM8995_AIF1DAC1L_TO_DAC1L_WIDTH 1 /* AIF1DAC1L_TO_DAC1L */
3121
3122/*
3123 * R1538 (0x602) - DAC1 Right Mixer Routing
3124 */
3125#define WM8995_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */
3126#define WM8995_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */
3127#define WM8995_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */
3128#define WM8995_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */
3129#define WM8995_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */
3130#define WM8995_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */
3131#define WM8995_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */
3132#define WM8995_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */
3133#define WM8995_AIF2DACR_TO_DAC1R 0x0004 /* AIF2DACR_TO_DAC1R */
3134#define WM8995_AIF2DACR_TO_DAC1R_MASK 0x0004 /* AIF2DACR_TO_DAC1R */
3135#define WM8995_AIF2DACR_TO_DAC1R_SHIFT 2 /* AIF2DACR_TO_DAC1R */
3136#define WM8995_AIF2DACR_TO_DAC1R_WIDTH 1 /* AIF2DACR_TO_DAC1R */
3137#define WM8995_AIF1DAC2R_TO_DAC1R 0x0002 /* AIF1DAC2R_TO_DAC1R */
3138#define WM8995_AIF1DAC2R_TO_DAC1R_MASK 0x0002 /* AIF1DAC2R_TO_DAC1R */
3139#define WM8995_AIF1DAC2R_TO_DAC1R_SHIFT 1 /* AIF1DAC2R_TO_DAC1R */
3140#define WM8995_AIF1DAC2R_TO_DAC1R_WIDTH 1 /* AIF1DAC2R_TO_DAC1R */
3141#define WM8995_AIF1DAC1R_TO_DAC1R 0x0001 /* AIF1DAC1R_TO_DAC1R */
3142#define WM8995_AIF1DAC1R_TO_DAC1R_MASK 0x0001 /* AIF1DAC1R_TO_DAC1R */
3143#define WM8995_AIF1DAC1R_TO_DAC1R_SHIFT 0 /* AIF1DAC1R_TO_DAC1R */
3144#define WM8995_AIF1DAC1R_TO_DAC1R_WIDTH 1 /* AIF1DAC1R_TO_DAC1R */
3145
3146/*
3147 * R1539 (0x603) - DAC2 Mixer Volumes
3148 */
3149#define WM8995_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */
3150#define WM8995_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */
3151#define WM8995_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */
3152#define WM8995_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */
3153#define WM8995_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */
3154#define WM8995_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */
3155
3156/*
3157 * R1540 (0x604) - DAC2 Left Mixer Routing
3158 */
3159#define WM8995_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */
3160#define WM8995_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */
3161#define WM8995_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */
3162#define WM8995_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */
3163#define WM8995_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */
3164#define WM8995_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */
3165#define WM8995_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */
3166#define WM8995_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */
3167#define WM8995_AIF2DACL_TO_DAC2L 0x0004 /* AIF2DACL_TO_DAC2L */
3168#define WM8995_AIF2DACL_TO_DAC2L_MASK 0x0004 /* AIF2DACL_TO_DAC2L */
3169#define WM8995_AIF2DACL_TO_DAC2L_SHIFT 2 /* AIF2DACL_TO_DAC2L */
3170#define WM8995_AIF2DACL_TO_DAC2L_WIDTH 1 /* AIF2DACL_TO_DAC2L */
3171#define WM8995_AIF1DAC2L_TO_DAC2L 0x0002 /* AIF1DAC2L_TO_DAC2L */
3172#define WM8995_AIF1DAC2L_TO_DAC2L_MASK 0x0002 /* AIF1DAC2L_TO_DAC2L */
3173#define WM8995_AIF1DAC2L_TO_DAC2L_SHIFT 1 /* AIF1DAC2L_TO_DAC2L */
3174#define WM8995_AIF1DAC2L_TO_DAC2L_WIDTH 1 /* AIF1DAC2L_TO_DAC2L */
3175#define WM8995_AIF1DAC1L_TO_DAC2L 0x0001 /* AIF1DAC1L_TO_DAC2L */
3176#define WM8995_AIF1DAC1L_TO_DAC2L_MASK 0x0001 /* AIF1DAC1L_TO_DAC2L */
3177#define WM8995_AIF1DAC1L_TO_DAC2L_SHIFT 0 /* AIF1DAC1L_TO_DAC2L */
3178#define WM8995_AIF1DAC1L_TO_DAC2L_WIDTH 1 /* AIF1DAC1L_TO_DAC2L */
3179
3180/*
3181 * R1541 (0x605) - DAC2 Right Mixer Routing
3182 */
3183#define WM8995_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */
3184#define WM8995_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */
3185#define WM8995_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */
3186#define WM8995_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */
3187#define WM8995_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */
3188#define WM8995_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */
3189#define WM8995_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */
3190#define WM8995_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */
3191#define WM8995_AIF2DACR_TO_DAC2R 0x0004 /* AIF2DACR_TO_DAC2R */
3192#define WM8995_AIF2DACR_TO_DAC2R_MASK 0x0004 /* AIF2DACR_TO_DAC2R */
3193#define WM8995_AIF2DACR_TO_DAC2R_SHIFT 2 /* AIF2DACR_TO_DAC2R */
3194#define WM8995_AIF2DACR_TO_DAC2R_WIDTH 1 /* AIF2DACR_TO_DAC2R */
3195#define WM8995_AIF1DAC2R_TO_DAC2R 0x0002 /* AIF1DAC2R_TO_DAC2R */
3196#define WM8995_AIF1DAC2R_TO_DAC2R_MASK 0x0002 /* AIF1DAC2R_TO_DAC2R */
3197#define WM8995_AIF1DAC2R_TO_DAC2R_SHIFT 1 /* AIF1DAC2R_TO_DAC2R */
3198#define WM8995_AIF1DAC2R_TO_DAC2R_WIDTH 1 /* AIF1DAC2R_TO_DAC2R */
3199#define WM8995_AIF1DAC1R_TO_DAC2R 0x0001 /* AIF1DAC1R_TO_DAC2R */
3200#define WM8995_AIF1DAC1R_TO_DAC2R_MASK 0x0001 /* AIF1DAC1R_TO_DAC2R */
3201#define WM8995_AIF1DAC1R_TO_DAC2R_SHIFT 0 /* AIF1DAC1R_TO_DAC2R */
3202#define WM8995_AIF1DAC1R_TO_DAC2R_WIDTH 1 /* AIF1DAC1R_TO_DAC2R */
3203
3204/*
3205 * R1542 (0x606) - AIF1 ADC1 Left Mixer Routing
3206 */
3207#define WM8995_ADC1L_TO_AIF1ADC1L 0x0002 /* ADC1L_TO_AIF1ADC1L */
3208#define WM8995_ADC1L_TO_AIF1ADC1L_MASK 0x0002 /* ADC1L_TO_AIF1ADC1L */
3209#define WM8995_ADC1L_TO_AIF1ADC1L_SHIFT 1 /* ADC1L_TO_AIF1ADC1L */
3210#define WM8995_ADC1L_TO_AIF1ADC1L_WIDTH 1 /* ADC1L_TO_AIF1ADC1L */
3211#define WM8995_AIF2DACL_TO_AIF1ADC1L 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
3212#define WM8995_AIF2DACL_TO_AIF1ADC1L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC1L */
3213#define WM8995_AIF2DACL_TO_AIF1ADC1L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC1L */
3214#define WM8995_AIF2DACL_TO_AIF1ADC1L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC1L */
3215
3216/*
3217 * R1543 (0x607) - AIF1 ADC1 Right Mixer Routing
3218 */
3219#define WM8995_ADC1R_TO_AIF1ADC1R 0x0002 /* ADC1R_TO_AIF1ADC1R */
3220#define WM8995_ADC1R_TO_AIF1ADC1R_MASK 0x0002 /* ADC1R_TO_AIF1ADC1R */
3221#define WM8995_ADC1R_TO_AIF1ADC1R_SHIFT 1 /* ADC1R_TO_AIF1ADC1R */
3222#define WM8995_ADC1R_TO_AIF1ADC1R_WIDTH 1 /* ADC1R_TO_AIF1ADC1R */
3223#define WM8995_AIF2DACR_TO_AIF1ADC1R 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
3224#define WM8995_AIF2DACR_TO_AIF1ADC1R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC1R */
3225#define WM8995_AIF2DACR_TO_AIF1ADC1R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC1R */
3226#define WM8995_AIF2DACR_TO_AIF1ADC1R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC1R */
3227
3228/*
3229 * R1544 (0x608) - AIF1 ADC2 Left Mixer Routing
3230 */
3231#define WM8995_ADC2L_TO_AIF1ADC2L 0x0002 /* ADC2L_TO_AIF1ADC2L */
3232#define WM8995_ADC2L_TO_AIF1ADC2L_MASK 0x0002 /* ADC2L_TO_AIF1ADC2L */
3233#define WM8995_ADC2L_TO_AIF1ADC2L_SHIFT 1 /* ADC2L_TO_AIF1ADC2L */
3234#define WM8995_ADC2L_TO_AIF1ADC2L_WIDTH 1 /* ADC2L_TO_AIF1ADC2L */
3235#define WM8995_AIF2DACL_TO_AIF1ADC2L 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
3236#define WM8995_AIF2DACL_TO_AIF1ADC2L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC2L */
3237#define WM8995_AIF2DACL_TO_AIF1ADC2L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC2L */
3238#define WM8995_AIF2DACL_TO_AIF1ADC2L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC2L */
3239
3240/*
3241 * R1545 (0x609) - AIF1 ADC2 Right mixer Routing
3242 */
3243#define WM8995_ADC2R_TO_AIF1ADC2R 0x0002 /* ADC2R_TO_AIF1ADC2R */
3244#define WM8995_ADC2R_TO_AIF1ADC2R_MASK 0x0002 /* ADC2R_TO_AIF1ADC2R */
3245#define WM8995_ADC2R_TO_AIF1ADC2R_SHIFT 1 /* ADC2R_TO_AIF1ADC2R */
3246#define WM8995_ADC2R_TO_AIF1ADC2R_WIDTH 1 /* ADC2R_TO_AIF1ADC2R */
3247#define WM8995_AIF2DACR_TO_AIF1ADC2R 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
3248#define WM8995_AIF2DACR_TO_AIF1ADC2R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC2R */
3249#define WM8995_AIF2DACR_TO_AIF1ADC2R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC2R */
3250#define WM8995_AIF2DACR_TO_AIF1ADC2R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC2R */
3251
3252/*
3253 * R1552 (0x610) - DAC Softmute
3254 */
3255#define WM8995_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */
3256#define WM8995_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */
3257#define WM8995_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */
3258#define WM8995_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */
3259#define WM8995_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */
3260#define WM8995_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */
3261#define WM8995_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */
3262#define WM8995_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */
3263
3264/*
3265 * R1568 (0x620) - Oversampling
3266 */
3267#define WM8995_ADC_OSR128 0x0002 /* ADC_OSR128 */
3268#define WM8995_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */
3269#define WM8995_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */
3270#define WM8995_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */
3271#define WM8995_DAC_OSR128 0x0001 /* DAC_OSR128 */
3272#define WM8995_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */
3273#define WM8995_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */
3274#define WM8995_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */
3275
3276/*
3277 * R1569 (0x621) - Sidetone
3278 */
3279#define WM8995_ST_LPF 0x1000 /* ST_LPF */
3280#define WM8995_ST_LPF_MASK 0x1000 /* ST_LPF */
3281#define WM8995_ST_LPF_SHIFT 12 /* ST_LPF */
3282#define WM8995_ST_LPF_WIDTH 1 /* ST_LPF */
3283#define WM8995_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */
3284#define WM8995_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */
3285#define WM8995_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */
3286#define WM8995_ST_HPF 0x0040 /* ST_HPF */
3287#define WM8995_ST_HPF_MASK 0x0040 /* ST_HPF */
3288#define WM8995_ST_HPF_SHIFT 6 /* ST_HPF */
3289#define WM8995_ST_HPF_WIDTH 1 /* ST_HPF */
3290#define WM8995_STR_SEL 0x0002 /* STR_SEL */
3291#define WM8995_STR_SEL_MASK 0x0002 /* STR_SEL */
3292#define WM8995_STR_SEL_SHIFT 1 /* STR_SEL */
3293#define WM8995_STR_SEL_WIDTH 1 /* STR_SEL */
3294#define WM8995_STL_SEL 0x0001 /* STL_SEL */
3295#define WM8995_STL_SEL_MASK 0x0001 /* STL_SEL */
3296#define WM8995_STL_SEL_SHIFT 0 /* STL_SEL */
3297#define WM8995_STL_SEL_WIDTH 1 /* STL_SEL */
3298
3299/*
3300 * R1792 (0x700) - GPIO 1
3301 */
3302#define WM8995_GP1_DIR 0x8000 /* GP1_DIR */
3303#define WM8995_GP1_DIR_MASK 0x8000 /* GP1_DIR */
3304#define WM8995_GP1_DIR_SHIFT 15 /* GP1_DIR */
3305#define WM8995_GP1_DIR_WIDTH 1 /* GP1_DIR */
3306#define WM8995_GP1_PU 0x4000 /* GP1_PU */
3307#define WM8995_GP1_PU_MASK 0x4000 /* GP1_PU */
3308#define WM8995_GP1_PU_SHIFT 14 /* GP1_PU */
3309#define WM8995_GP1_PU_WIDTH 1 /* GP1_PU */
3310#define WM8995_GP1_PD 0x2000 /* GP1_PD */
3311#define WM8995_GP1_PD_MASK 0x2000 /* GP1_PD */
3312#define WM8995_GP1_PD_SHIFT 13 /* GP1_PD */
3313#define WM8995_GP1_PD_WIDTH 1 /* GP1_PD */
3314#define WM8995_GP1_POL 0x0400 /* GP1_POL */
3315#define WM8995_GP1_POL_MASK 0x0400 /* GP1_POL */
3316#define WM8995_GP1_POL_SHIFT 10 /* GP1_POL */
3317#define WM8995_GP1_POL_WIDTH 1 /* GP1_POL */
3318#define WM8995_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */
3319#define WM8995_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */
3320#define WM8995_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */
3321#define WM8995_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */
3322#define WM8995_GP1_DB 0x0100 /* GP1_DB */
3323#define WM8995_GP1_DB_MASK 0x0100 /* GP1_DB */
3324#define WM8995_GP1_DB_SHIFT 8 /* GP1_DB */
3325#define WM8995_GP1_DB_WIDTH 1 /* GP1_DB */
3326#define WM8995_GP1_LVL 0x0040 /* GP1_LVL */
3327#define WM8995_GP1_LVL_MASK 0x0040 /* GP1_LVL */
3328#define WM8995_GP1_LVL_SHIFT 6 /* GP1_LVL */
3329#define WM8995_GP1_LVL_WIDTH 1 /* GP1_LVL */
3330#define WM8995_GP1_FN_MASK 0x001F /* GP1_FN - [4:0] */
3331#define WM8995_GP1_FN_SHIFT 0 /* GP1_FN - [4:0] */
3332#define WM8995_GP1_FN_WIDTH 5 /* GP1_FN - [4:0] */
3333
3334/*
3335 * R1793 (0x701) - GPIO 2
3336 */
3337#define WM8995_GP2_DIR 0x8000 /* GP2_DIR */
3338#define WM8995_GP2_DIR_MASK 0x8000 /* GP2_DIR */
3339#define WM8995_GP2_DIR_SHIFT 15 /* GP2_DIR */
3340#define WM8995_GP2_DIR_WIDTH 1 /* GP2_DIR */
3341#define WM8995_GP2_PU 0x4000 /* GP2_PU */
3342#define WM8995_GP2_PU_MASK 0x4000 /* GP2_PU */
3343#define WM8995_GP2_PU_SHIFT 14 /* GP2_PU */
3344#define WM8995_GP2_PU_WIDTH 1 /* GP2_PU */
3345#define WM8995_GP2_PD 0x2000 /* GP2_PD */
3346#define WM8995_GP2_PD_MASK 0x2000 /* GP2_PD */
3347#define WM8995_GP2_PD_SHIFT 13 /* GP2_PD */
3348#define WM8995_GP2_PD_WIDTH 1 /* GP2_PD */
3349#define WM8995_GP2_POL 0x0400 /* GP2_POL */
3350#define WM8995_GP2_POL_MASK 0x0400 /* GP2_POL */
3351#define WM8995_GP2_POL_SHIFT 10 /* GP2_POL */
3352#define WM8995_GP2_POL_WIDTH 1 /* GP2_POL */
3353#define WM8995_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */
3354#define WM8995_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */
3355#define WM8995_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */
3356#define WM8995_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */
3357#define WM8995_GP2_DB 0x0100 /* GP2_DB */
3358#define WM8995_GP2_DB_MASK 0x0100 /* GP2_DB */
3359#define WM8995_GP2_DB_SHIFT 8 /* GP2_DB */
3360#define WM8995_GP2_DB_WIDTH 1 /* GP2_DB */
3361#define WM8995_GP2_LVL 0x0040 /* GP2_LVL */
3362#define WM8995_GP2_LVL_MASK 0x0040 /* GP2_LVL */
3363#define WM8995_GP2_LVL_SHIFT 6 /* GP2_LVL */
3364#define WM8995_GP2_LVL_WIDTH 1 /* GP2_LVL */
3365#define WM8995_GP2_FN_MASK 0x001F /* GP2_FN - [4:0] */
3366#define WM8995_GP2_FN_SHIFT 0 /* GP2_FN - [4:0] */
3367#define WM8995_GP2_FN_WIDTH 5 /* GP2_FN - [4:0] */
3368
3369/*
3370 * R1794 (0x702) - GPIO 3
3371 */
3372#define WM8995_GP3_DIR 0x8000 /* GP3_DIR */
3373#define WM8995_GP3_DIR_MASK 0x8000 /* GP3_DIR */
3374#define WM8995_GP3_DIR_SHIFT 15 /* GP3_DIR */
3375#define WM8995_GP3_DIR_WIDTH 1 /* GP3_DIR */
3376#define WM8995_GP3_PU 0x4000 /* GP3_PU */
3377#define WM8995_GP3_PU_MASK 0x4000 /* GP3_PU */
3378#define WM8995_GP3_PU_SHIFT 14 /* GP3_PU */
3379#define WM8995_GP3_PU_WIDTH 1 /* GP3_PU */
3380#define WM8995_GP3_PD 0x2000 /* GP3_PD */
3381#define WM8995_GP3_PD_MASK 0x2000 /* GP3_PD */
3382#define WM8995_GP3_PD_SHIFT 13 /* GP3_PD */
3383#define WM8995_GP3_PD_WIDTH 1 /* GP3_PD */
3384#define WM8995_GP3_POL 0x0400 /* GP3_POL */
3385#define WM8995_GP3_POL_MASK 0x0400 /* GP3_POL */
3386#define WM8995_GP3_POL_SHIFT 10 /* GP3_POL */
3387#define WM8995_GP3_POL_WIDTH 1 /* GP3_POL */
3388#define WM8995_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */
3389#define WM8995_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */
3390#define WM8995_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */
3391#define WM8995_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */
3392#define WM8995_GP3_DB 0x0100 /* GP3_DB */
3393#define WM8995_GP3_DB_MASK 0x0100 /* GP3_DB */
3394#define WM8995_GP3_DB_SHIFT 8 /* GP3_DB */
3395#define WM8995_GP3_DB_WIDTH 1 /* GP3_DB */
3396#define WM8995_GP3_LVL 0x0040 /* GP3_LVL */
3397#define WM8995_GP3_LVL_MASK 0x0040 /* GP3_LVL */
3398#define WM8995_GP3_LVL_SHIFT 6 /* GP3_LVL */
3399#define WM8995_GP3_LVL_WIDTH 1 /* GP3_LVL */
3400#define WM8995_GP3_FN_MASK 0x001F /* GP3_FN - [4:0] */
3401#define WM8995_GP3_FN_SHIFT 0 /* GP3_FN - [4:0] */
3402#define WM8995_GP3_FN_WIDTH 5 /* GP3_FN - [4:0] */
3403
3404/*
3405 * R1795 (0x703) - GPIO 4
3406 */
3407#define WM8995_GP4_DIR 0x8000 /* GP4_DIR */
3408#define WM8995_GP4_DIR_MASK 0x8000 /* GP4_DIR */
3409#define WM8995_GP4_DIR_SHIFT 15 /* GP4_DIR */
3410#define WM8995_GP4_DIR_WIDTH 1 /* GP4_DIR */
3411#define WM8995_GP4_PU 0x4000 /* GP4_PU */
3412#define WM8995_GP4_PU_MASK 0x4000 /* GP4_PU */
3413#define WM8995_GP4_PU_SHIFT 14 /* GP4_PU */
3414#define WM8995_GP4_PU_WIDTH 1 /* GP4_PU */
3415#define WM8995_GP4_PD 0x2000 /* GP4_PD */
3416#define WM8995_GP4_PD_MASK 0x2000 /* GP4_PD */
3417#define WM8995_GP4_PD_SHIFT 13 /* GP4_PD */
3418#define WM8995_GP4_PD_WIDTH 1 /* GP4_PD */
3419#define WM8995_GP4_POL 0x0400 /* GP4_POL */
3420#define WM8995_GP4_POL_MASK 0x0400 /* GP4_POL */
3421#define WM8995_GP4_POL_SHIFT 10 /* GP4_POL */
3422#define WM8995_GP4_POL_WIDTH 1 /* GP4_POL */
3423#define WM8995_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */
3424#define WM8995_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */
3425#define WM8995_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */
3426#define WM8995_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */
3427#define WM8995_GP4_DB 0x0100 /* GP4_DB */
3428#define WM8995_GP4_DB_MASK 0x0100 /* GP4_DB */
3429#define WM8995_GP4_DB_SHIFT 8 /* GP4_DB */
3430#define WM8995_GP4_DB_WIDTH 1 /* GP4_DB */
3431#define WM8995_GP4_LVL 0x0040 /* GP4_LVL */
3432#define WM8995_GP4_LVL_MASK 0x0040 /* GP4_LVL */
3433#define WM8995_GP4_LVL_SHIFT 6 /* GP4_LVL */
3434#define WM8995_GP4_LVL_WIDTH 1 /* GP4_LVL */
3435#define WM8995_GP4_FN_MASK 0x001F /* GP4_FN - [4:0] */
3436#define WM8995_GP4_FN_SHIFT 0 /* GP4_FN - [4:0] */
3437#define WM8995_GP4_FN_WIDTH 5 /* GP4_FN - [4:0] */
3438
3439/*
3440 * R1796 (0x704) - GPIO 5
3441 */
3442#define WM8995_GP5_DIR 0x8000 /* GP5_DIR */
3443#define WM8995_GP5_DIR_MASK 0x8000 /* GP5_DIR */
3444#define WM8995_GP5_DIR_SHIFT 15 /* GP5_DIR */
3445#define WM8995_GP5_DIR_WIDTH 1 /* GP5_DIR */
3446#define WM8995_GP5_PU 0x4000 /* GP5_PU */
3447#define WM8995_GP5_PU_MASK 0x4000 /* GP5_PU */
3448#define WM8995_GP5_PU_SHIFT 14 /* GP5_PU */
3449#define WM8995_GP5_PU_WIDTH 1 /* GP5_PU */
3450#define WM8995_GP5_PD 0x2000 /* GP5_PD */
3451#define WM8995_GP5_PD_MASK 0x2000 /* GP5_PD */
3452#define WM8995_GP5_PD_SHIFT 13 /* GP5_PD */
3453#define WM8995_GP5_PD_WIDTH 1 /* GP5_PD */
3454#define WM8995_GP5_POL 0x0400 /* GP5_POL */
3455#define WM8995_GP5_POL_MASK 0x0400 /* GP5_POL */
3456#define WM8995_GP5_POL_SHIFT 10 /* GP5_POL */
3457#define WM8995_GP5_POL_WIDTH 1 /* GP5_POL */
3458#define WM8995_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */
3459#define WM8995_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */
3460#define WM8995_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */
3461#define WM8995_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */
3462#define WM8995_GP5_DB 0x0100 /* GP5_DB */
3463#define WM8995_GP5_DB_MASK 0x0100 /* GP5_DB */
3464#define WM8995_GP5_DB_SHIFT 8 /* GP5_DB */
3465#define WM8995_GP5_DB_WIDTH 1 /* GP5_DB */
3466#define WM8995_GP5_LVL 0x0040 /* GP5_LVL */
3467#define WM8995_GP5_LVL_MASK 0x0040 /* GP5_LVL */
3468#define WM8995_GP5_LVL_SHIFT 6 /* GP5_LVL */
3469#define WM8995_GP5_LVL_WIDTH 1 /* GP5_LVL */
3470#define WM8995_GP5_FN_MASK 0x001F /* GP5_FN - [4:0] */
3471#define WM8995_GP5_FN_SHIFT 0 /* GP5_FN - [4:0] */
3472#define WM8995_GP5_FN_WIDTH 5 /* GP5_FN - [4:0] */
3473
3474/*
3475 * R1797 (0x705) - GPIO 6
3476 */
3477#define WM8995_GP6_DIR 0x8000 /* GP6_DIR */
3478#define WM8995_GP6_DIR_MASK 0x8000 /* GP6_DIR */
3479#define WM8995_GP6_DIR_SHIFT 15 /* GP6_DIR */
3480#define WM8995_GP6_DIR_WIDTH 1 /* GP6_DIR */
3481#define WM8995_GP6_PU 0x4000 /* GP6_PU */
3482#define WM8995_GP6_PU_MASK 0x4000 /* GP6_PU */
3483#define WM8995_GP6_PU_SHIFT 14 /* GP6_PU */
3484#define WM8995_GP6_PU_WIDTH 1 /* GP6_PU */
3485#define WM8995_GP6_PD 0x2000 /* GP6_PD */
3486#define WM8995_GP6_PD_MASK 0x2000 /* GP6_PD */
3487#define WM8995_GP6_PD_SHIFT 13 /* GP6_PD */
3488#define WM8995_GP6_PD_WIDTH 1 /* GP6_PD */
3489#define WM8995_GP6_POL 0x0400 /* GP6_POL */
3490#define WM8995_GP6_POL_MASK 0x0400 /* GP6_POL */
3491#define WM8995_GP6_POL_SHIFT 10 /* GP6_POL */
3492#define WM8995_GP6_POL_WIDTH 1 /* GP6_POL */
3493#define WM8995_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */
3494#define WM8995_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */
3495#define WM8995_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */
3496#define WM8995_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */
3497#define WM8995_GP6_DB 0x0100 /* GP6_DB */
3498#define WM8995_GP6_DB_MASK 0x0100 /* GP6_DB */
3499#define WM8995_GP6_DB_SHIFT 8 /* GP6_DB */
3500#define WM8995_GP6_DB_WIDTH 1 /* GP6_DB */
3501#define WM8995_GP6_LVL 0x0040 /* GP6_LVL */
3502#define WM8995_GP6_LVL_MASK 0x0040 /* GP6_LVL */
3503#define WM8995_GP6_LVL_SHIFT 6 /* GP6_LVL */
3504#define WM8995_GP6_LVL_WIDTH 1 /* GP6_LVL */
3505#define WM8995_GP6_FN_MASK 0x001F /* GP6_FN - [4:0] */
3506#define WM8995_GP6_FN_SHIFT 0 /* GP6_FN - [4:0] */
3507#define WM8995_GP6_FN_WIDTH 5 /* GP6_FN - [4:0] */
3508
3509/*
3510 * R1798 (0x706) - GPIO 7
3511 */
3512#define WM8995_GP7_DIR 0x8000 /* GP7_DIR */
3513#define WM8995_GP7_DIR_MASK 0x8000 /* GP7_DIR */
3514#define WM8995_GP7_DIR_SHIFT 15 /* GP7_DIR */
3515#define WM8995_GP7_DIR_WIDTH 1 /* GP7_DIR */
3516#define WM8995_GP7_PU 0x4000 /* GP7_PU */
3517#define WM8995_GP7_PU_MASK 0x4000 /* GP7_PU */
3518#define WM8995_GP7_PU_SHIFT 14 /* GP7_PU */
3519#define WM8995_GP7_PU_WIDTH 1 /* GP7_PU */
3520#define WM8995_GP7_PD 0x2000 /* GP7_PD */
3521#define WM8995_GP7_PD_MASK 0x2000 /* GP7_PD */
3522#define WM8995_GP7_PD_SHIFT 13 /* GP7_PD */
3523#define WM8995_GP7_PD_WIDTH 1 /* GP7_PD */
3524#define WM8995_GP7_POL 0x0400 /* GP7_POL */
3525#define WM8995_GP7_POL_MASK 0x0400 /* GP7_POL */
3526#define WM8995_GP7_POL_SHIFT 10 /* GP7_POL */
3527#define WM8995_GP7_POL_WIDTH 1 /* GP7_POL */
3528#define WM8995_GP7_OP_CFG 0x0200 /* GP7_OP_CFG */
3529#define WM8995_GP7_OP_CFG_MASK 0x0200 /* GP7_OP_CFG */
3530#define WM8995_GP7_OP_CFG_SHIFT 9 /* GP7_OP_CFG */
3531#define WM8995_GP7_OP_CFG_WIDTH 1 /* GP7_OP_CFG */
3532#define WM8995_GP7_DB 0x0100 /* GP7_DB */
3533#define WM8995_GP7_DB_MASK 0x0100 /* GP7_DB */
3534#define WM8995_GP7_DB_SHIFT 8 /* GP7_DB */
3535#define WM8995_GP7_DB_WIDTH 1 /* GP7_DB */
3536#define WM8995_GP7_LVL 0x0040 /* GP7_LVL */
3537#define WM8995_GP7_LVL_MASK 0x0040 /* GP7_LVL */
3538#define WM8995_GP7_LVL_SHIFT 6 /* GP7_LVL */
3539#define WM8995_GP7_LVL_WIDTH 1 /* GP7_LVL */
3540#define WM8995_GP7_FN_MASK 0x001F /* GP7_FN - [4:0] */
3541#define WM8995_GP7_FN_SHIFT 0 /* GP7_FN - [4:0] */
3542#define WM8995_GP7_FN_WIDTH 5 /* GP7_FN - [4:0] */
3543
3544/*
3545 * R1799 (0x707) - GPIO 8
3546 */
3547#define WM8995_GP8_DIR 0x8000 /* GP8_DIR */
3548#define WM8995_GP8_DIR_MASK 0x8000 /* GP8_DIR */
3549#define WM8995_GP8_DIR_SHIFT 15 /* GP8_DIR */
3550#define WM8995_GP8_DIR_WIDTH 1 /* GP8_DIR */
3551#define WM8995_GP8_PU 0x4000 /* GP8_PU */
3552#define WM8995_GP8_PU_MASK 0x4000 /* GP8_PU */
3553#define WM8995_GP8_PU_SHIFT 14 /* GP8_PU */
3554#define WM8995_GP8_PU_WIDTH 1 /* GP8_PU */
3555#define WM8995_GP8_PD 0x2000 /* GP8_PD */
3556#define WM8995_GP8_PD_MASK 0x2000 /* GP8_PD */
3557#define WM8995_GP8_PD_SHIFT 13 /* GP8_PD */
3558#define WM8995_GP8_PD_WIDTH 1 /* GP8_PD */
3559#define WM8995_GP8_POL 0x0400 /* GP8_POL */
3560#define WM8995_GP8_POL_MASK 0x0400 /* GP8_POL */
3561#define WM8995_GP8_POL_SHIFT 10 /* GP8_POL */
3562#define WM8995_GP8_POL_WIDTH 1 /* GP8_POL */
3563#define WM8995_GP8_OP_CFG 0x0200 /* GP8_OP_CFG */
3564#define WM8995_GP8_OP_CFG_MASK 0x0200 /* GP8_OP_CFG */
3565#define WM8995_GP8_OP_CFG_SHIFT 9 /* GP8_OP_CFG */
3566#define WM8995_GP8_OP_CFG_WIDTH 1 /* GP8_OP_CFG */
3567#define WM8995_GP8_DB 0x0100 /* GP8_DB */
3568#define WM8995_GP8_DB_MASK 0x0100 /* GP8_DB */
3569#define WM8995_GP8_DB_SHIFT 8 /* GP8_DB */
3570#define WM8995_GP8_DB_WIDTH 1 /* GP8_DB */
3571#define WM8995_GP8_LVL 0x0040 /* GP8_LVL */
3572#define WM8995_GP8_LVL_MASK 0x0040 /* GP8_LVL */
3573#define WM8995_GP8_LVL_SHIFT 6 /* GP8_LVL */
3574#define WM8995_GP8_LVL_WIDTH 1 /* GP8_LVL */
3575#define WM8995_GP8_FN_MASK 0x001F /* GP8_FN - [4:0] */
3576#define WM8995_GP8_FN_SHIFT 0 /* GP8_FN - [4:0] */
3577#define WM8995_GP8_FN_WIDTH 5 /* GP8_FN - [4:0] */
3578
3579/*
3580 * R1800 (0x708) - GPIO 9
3581 */
3582#define WM8995_GP9_DIR 0x8000 /* GP9_DIR */
3583#define WM8995_GP9_DIR_MASK 0x8000 /* GP9_DIR */
3584#define WM8995_GP9_DIR_SHIFT 15 /* GP9_DIR */
3585#define WM8995_GP9_DIR_WIDTH 1 /* GP9_DIR */
3586#define WM8995_GP9_PU 0x4000 /* GP9_PU */
3587#define WM8995_GP9_PU_MASK 0x4000 /* GP9_PU */
3588#define WM8995_GP9_PU_SHIFT 14 /* GP9_PU */
3589#define WM8995_GP9_PU_WIDTH 1 /* GP9_PU */
3590#define WM8995_GP9_PD 0x2000 /* GP9_PD */
3591#define WM8995_GP9_PD_MASK 0x2000 /* GP9_PD */
3592#define WM8995_GP9_PD_SHIFT 13 /* GP9_PD */
3593#define WM8995_GP9_PD_WIDTH 1 /* GP9_PD */
3594#define WM8995_GP9_POL 0x0400 /* GP9_POL */
3595#define WM8995_GP9_POL_MASK 0x0400 /* GP9_POL */
3596#define WM8995_GP9_POL_SHIFT 10 /* GP9_POL */
3597#define WM8995_GP9_POL_WIDTH 1 /* GP9_POL */
3598#define WM8995_GP9_OP_CFG 0x0200 /* GP9_OP_CFG */
3599#define WM8995_GP9_OP_CFG_MASK 0x0200 /* GP9_OP_CFG */
3600#define WM8995_GP9_OP_CFG_SHIFT 9 /* GP9_OP_CFG */
3601#define WM8995_GP9_OP_CFG_WIDTH 1 /* GP9_OP_CFG */
3602#define WM8995_GP9_DB 0x0100 /* GP9_DB */
3603#define WM8995_GP9_DB_MASK 0x0100 /* GP9_DB */
3604#define WM8995_GP9_DB_SHIFT 8 /* GP9_DB */
3605#define WM8995_GP9_DB_WIDTH 1 /* GP9_DB */
3606#define WM8995_GP9_LVL 0x0040 /* GP9_LVL */
3607#define WM8995_GP9_LVL_MASK 0x0040 /* GP9_LVL */
3608#define WM8995_GP9_LVL_SHIFT 6 /* GP9_LVL */
3609#define WM8995_GP9_LVL_WIDTH 1 /* GP9_LVL */
3610#define WM8995_GP9_FN_MASK 0x001F /* GP9_FN - [4:0] */
3611#define WM8995_GP9_FN_SHIFT 0 /* GP9_FN - [4:0] */
3612#define WM8995_GP9_FN_WIDTH 5 /* GP9_FN - [4:0] */
3613
3614/*
3615 * R1801 (0x709) - GPIO 10
3616 */
3617#define WM8995_GP10_DIR 0x8000 /* GP10_DIR */
3618#define WM8995_GP10_DIR_MASK 0x8000 /* GP10_DIR */
3619#define WM8995_GP10_DIR_SHIFT 15 /* GP10_DIR */
3620#define WM8995_GP10_DIR_WIDTH 1 /* GP10_DIR */
3621#define WM8995_GP10_PU 0x4000 /* GP10_PU */
3622#define WM8995_GP10_PU_MASK 0x4000 /* GP10_PU */
3623#define WM8995_GP10_PU_SHIFT 14 /* GP10_PU */
3624#define WM8995_GP10_PU_WIDTH 1 /* GP10_PU */
3625#define WM8995_GP10_PD 0x2000 /* GP10_PD */
3626#define WM8995_GP10_PD_MASK 0x2000 /* GP10_PD */
3627#define WM8995_GP10_PD_SHIFT 13 /* GP10_PD */
3628#define WM8995_GP10_PD_WIDTH 1 /* GP10_PD */
3629#define WM8995_GP10_POL 0x0400 /* GP10_POL */
3630#define WM8995_GP10_POL_MASK 0x0400 /* GP10_POL */
3631#define WM8995_GP10_POL_SHIFT 10 /* GP10_POL */
3632#define WM8995_GP10_POL_WIDTH 1 /* GP10_POL */
3633#define WM8995_GP10_OP_CFG 0x0200 /* GP10_OP_CFG */
3634#define WM8995_GP10_OP_CFG_MASK 0x0200 /* GP10_OP_CFG */
3635#define WM8995_GP10_OP_CFG_SHIFT 9 /* GP10_OP_CFG */
3636#define WM8995_GP10_OP_CFG_WIDTH 1 /* GP10_OP_CFG */
3637#define WM8995_GP10_DB 0x0100 /* GP10_DB */
3638#define WM8995_GP10_DB_MASK 0x0100 /* GP10_DB */
3639#define WM8995_GP10_DB_SHIFT 8 /* GP10_DB */
3640#define WM8995_GP10_DB_WIDTH 1 /* GP10_DB */
3641#define WM8995_GP10_LVL 0x0040 /* GP10_LVL */
3642#define WM8995_GP10_LVL_MASK 0x0040 /* GP10_LVL */
3643#define WM8995_GP10_LVL_SHIFT 6 /* GP10_LVL */
3644#define WM8995_GP10_LVL_WIDTH 1 /* GP10_LVL */
3645#define WM8995_GP10_FN_MASK 0x001F /* GP10_FN - [4:0] */
3646#define WM8995_GP10_FN_SHIFT 0 /* GP10_FN - [4:0] */
3647#define WM8995_GP10_FN_WIDTH 5 /* GP10_FN - [4:0] */
3648
3649/*
3650 * R1802 (0x70A) - GPIO 11
3651 */
3652#define WM8995_GP11_DIR 0x8000 /* GP11_DIR */
3653#define WM8995_GP11_DIR_MASK 0x8000 /* GP11_DIR */
3654#define WM8995_GP11_DIR_SHIFT 15 /* GP11_DIR */
3655#define WM8995_GP11_DIR_WIDTH 1 /* GP11_DIR */
3656#define WM8995_GP11_PU 0x4000 /* GP11_PU */
3657#define WM8995_GP11_PU_MASK 0x4000 /* GP11_PU */
3658#define WM8995_GP11_PU_SHIFT 14 /* GP11_PU */
3659#define WM8995_GP11_PU_WIDTH 1 /* GP11_PU */
3660#define WM8995_GP11_PD 0x2000 /* GP11_PD */
3661#define WM8995_GP11_PD_MASK 0x2000 /* GP11_PD */
3662#define WM8995_GP11_PD_SHIFT 13 /* GP11_PD */
3663#define WM8995_GP11_PD_WIDTH 1 /* GP11_PD */
3664#define WM8995_GP11_POL 0x0400 /* GP11_POL */
3665#define WM8995_GP11_POL_MASK 0x0400 /* GP11_POL */
3666#define WM8995_GP11_POL_SHIFT 10 /* GP11_POL */
3667#define WM8995_GP11_POL_WIDTH 1 /* GP11_POL */
3668#define WM8995_GP11_OP_CFG 0x0200 /* GP11_OP_CFG */
3669#define WM8995_GP11_OP_CFG_MASK 0x0200 /* GP11_OP_CFG */
3670#define WM8995_GP11_OP_CFG_SHIFT 9 /* GP11_OP_CFG */
3671#define WM8995_GP11_OP_CFG_WIDTH 1 /* GP11_OP_CFG */
3672#define WM8995_GP11_DB 0x0100 /* GP11_DB */
3673#define WM8995_GP11_DB_MASK 0x0100 /* GP11_DB */
3674#define WM8995_GP11_DB_SHIFT 8 /* GP11_DB */
3675#define WM8995_GP11_DB_WIDTH 1 /* GP11_DB */
3676#define WM8995_GP11_LVL 0x0040 /* GP11_LVL */
3677#define WM8995_GP11_LVL_MASK 0x0040 /* GP11_LVL */
3678#define WM8995_GP11_LVL_SHIFT 6 /* GP11_LVL */
3679#define WM8995_GP11_LVL_WIDTH 1 /* GP11_LVL */
3680#define WM8995_GP11_FN_MASK 0x001F /* GP11_FN - [4:0] */
3681#define WM8995_GP11_FN_SHIFT 0 /* GP11_FN - [4:0] */
3682#define WM8995_GP11_FN_WIDTH 5 /* GP11_FN - [4:0] */
3683
3684/*
3685 * R1803 (0x70B) - GPIO 12
3686 */
3687#define WM8995_GP12_DIR 0x8000 /* GP12_DIR */
3688#define WM8995_GP12_DIR_MASK 0x8000 /* GP12_DIR */
3689#define WM8995_GP12_DIR_SHIFT 15 /* GP12_DIR */
3690#define WM8995_GP12_DIR_WIDTH 1 /* GP12_DIR */
3691#define WM8995_GP12_PU 0x4000 /* GP12_PU */
3692#define WM8995_GP12_PU_MASK 0x4000 /* GP12_PU */
3693#define WM8995_GP12_PU_SHIFT 14 /* GP12_PU */
3694#define WM8995_GP12_PU_WIDTH 1 /* GP12_PU */
3695#define WM8995_GP12_PD 0x2000 /* GP12_PD */
3696#define WM8995_GP12_PD_MASK 0x2000 /* GP12_PD */
3697#define WM8995_GP12_PD_SHIFT 13 /* GP12_PD */
3698#define WM8995_GP12_PD_WIDTH 1 /* GP12_PD */
3699#define WM8995_GP12_POL 0x0400 /* GP12_POL */
3700#define WM8995_GP12_POL_MASK 0x0400 /* GP12_POL */
3701#define WM8995_GP12_POL_SHIFT 10 /* GP12_POL */
3702#define WM8995_GP12_POL_WIDTH 1 /* GP12_POL */
3703#define WM8995_GP12_OP_CFG 0x0200 /* GP12_OP_CFG */
3704#define WM8995_GP12_OP_CFG_MASK 0x0200 /* GP12_OP_CFG */
3705#define WM8995_GP12_OP_CFG_SHIFT 9 /* GP12_OP_CFG */
3706#define WM8995_GP12_OP_CFG_WIDTH 1 /* GP12_OP_CFG */
3707#define WM8995_GP12_DB 0x0100 /* GP12_DB */
3708#define WM8995_GP12_DB_MASK 0x0100 /* GP12_DB */
3709#define WM8995_GP12_DB_SHIFT 8 /* GP12_DB */
3710#define WM8995_GP12_DB_WIDTH 1 /* GP12_DB */
3711#define WM8995_GP12_LVL 0x0040 /* GP12_LVL */
3712#define WM8995_GP12_LVL_MASK 0x0040 /* GP12_LVL */
3713#define WM8995_GP12_LVL_SHIFT 6 /* GP12_LVL */
3714#define WM8995_GP12_LVL_WIDTH 1 /* GP12_LVL */
3715#define WM8995_GP12_FN_MASK 0x001F /* GP12_FN - [4:0] */
3716#define WM8995_GP12_FN_SHIFT 0 /* GP12_FN - [4:0] */
3717#define WM8995_GP12_FN_WIDTH 5 /* GP12_FN - [4:0] */
3718
3719/*
3720 * R1804 (0x70C) - GPIO 13
3721 */
3722#define WM8995_GP13_DIR 0x8000 /* GP13_DIR */
3723#define WM8995_GP13_DIR_MASK 0x8000 /* GP13_DIR */
3724#define WM8995_GP13_DIR_SHIFT 15 /* GP13_DIR */
3725#define WM8995_GP13_DIR_WIDTH 1 /* GP13_DIR */
3726#define WM8995_GP13_PU 0x4000 /* GP13_PU */
3727#define WM8995_GP13_PU_MASK 0x4000 /* GP13_PU */
3728#define WM8995_GP13_PU_SHIFT 14 /* GP13_PU */
3729#define WM8995_GP13_PU_WIDTH 1 /* GP13_PU */
3730#define WM8995_GP13_PD 0x2000 /* GP13_PD */
3731#define WM8995_GP13_PD_MASK 0x2000 /* GP13_PD */
3732#define WM8995_GP13_PD_SHIFT 13 /* GP13_PD */
3733#define WM8995_GP13_PD_WIDTH 1 /* GP13_PD */
3734#define WM8995_GP13_POL 0x0400 /* GP13_POL */
3735#define WM8995_GP13_POL_MASK 0x0400 /* GP13_POL */
3736#define WM8995_GP13_POL_SHIFT 10 /* GP13_POL */
3737#define WM8995_GP13_POL_WIDTH 1 /* GP13_POL */
3738#define WM8995_GP13_OP_CFG 0x0200 /* GP13_OP_CFG */
3739#define WM8995_GP13_OP_CFG_MASK 0x0200 /* GP13_OP_CFG */
3740#define WM8995_GP13_OP_CFG_SHIFT 9 /* GP13_OP_CFG */
3741#define WM8995_GP13_OP_CFG_WIDTH 1 /* GP13_OP_CFG */
3742#define WM8995_GP13_DB 0x0100 /* GP13_DB */
3743#define WM8995_GP13_DB_MASK 0x0100 /* GP13_DB */
3744#define WM8995_GP13_DB_SHIFT 8 /* GP13_DB */
3745#define WM8995_GP13_DB_WIDTH 1 /* GP13_DB */
3746#define WM8995_GP13_LVL 0x0040 /* GP13_LVL */
3747#define WM8995_GP13_LVL_MASK 0x0040 /* GP13_LVL */
3748#define WM8995_GP13_LVL_SHIFT 6 /* GP13_LVL */
3749#define WM8995_GP13_LVL_WIDTH 1 /* GP13_LVL */
3750#define WM8995_GP13_FN_MASK 0x001F /* GP13_FN - [4:0] */
3751#define WM8995_GP13_FN_SHIFT 0 /* GP13_FN - [4:0] */
3752#define WM8995_GP13_FN_WIDTH 5 /* GP13_FN - [4:0] */
3753
3754/*
3755 * R1805 (0x70D) - GPIO 14
3756 */
3757#define WM8995_GP14_DIR 0x8000 /* GP14_DIR */
3758#define WM8995_GP14_DIR_MASK 0x8000 /* GP14_DIR */
3759#define WM8995_GP14_DIR_SHIFT 15 /* GP14_DIR */
3760#define WM8995_GP14_DIR_WIDTH 1 /* GP14_DIR */
3761#define WM8995_GP14_PU 0x4000 /* GP14_PU */
3762#define WM8995_GP14_PU_MASK 0x4000 /* GP14_PU */
3763#define WM8995_GP14_PU_SHIFT 14 /* GP14_PU */
3764#define WM8995_GP14_PU_WIDTH 1 /* GP14_PU */
3765#define WM8995_GP14_PD 0x2000 /* GP14_PD */
3766#define WM8995_GP14_PD_MASK 0x2000 /* GP14_PD */
3767#define WM8995_GP14_PD_SHIFT 13 /* GP14_PD */
3768#define WM8995_GP14_PD_WIDTH 1 /* GP14_PD */
3769#define WM8995_GP14_POL 0x0400 /* GP14_POL */
3770#define WM8995_GP14_POL_MASK 0x0400 /* GP14_POL */
3771#define WM8995_GP14_POL_SHIFT 10 /* GP14_POL */
3772#define WM8995_GP14_POL_WIDTH 1 /* GP14_POL */
3773#define WM8995_GP14_OP_CFG 0x0200 /* GP14_OP_CFG */
3774#define WM8995_GP14_OP_CFG_MASK 0x0200 /* GP14_OP_CFG */
3775#define WM8995_GP14_OP_CFG_SHIFT 9 /* GP14_OP_CFG */
3776#define WM8995_GP14_OP_CFG_WIDTH 1 /* GP14_OP_CFG */
3777#define WM8995_GP14_DB 0x0100 /* GP14_DB */
3778#define WM8995_GP14_DB_MASK 0x0100 /* GP14_DB */
3779#define WM8995_GP14_DB_SHIFT 8 /* GP14_DB */
3780#define WM8995_GP14_DB_WIDTH 1 /* GP14_DB */
3781#define WM8995_GP14_LVL 0x0040 /* GP14_LVL */
3782#define WM8995_GP14_LVL_MASK 0x0040 /* GP14_LVL */
3783#define WM8995_GP14_LVL_SHIFT 6 /* GP14_LVL */
3784#define WM8995_GP14_LVL_WIDTH 1 /* GP14_LVL */
3785#define WM8995_GP14_FN_MASK 0x001F /* GP14_FN - [4:0] */
3786#define WM8995_GP14_FN_SHIFT 0 /* GP14_FN - [4:0] */
3787#define WM8995_GP14_FN_WIDTH 5 /* GP14_FN - [4:0] */
3788
3789/*
3790 * R1824 (0x720) - Pull Control (1)
3791 */
3792#define WM8995_DMICDAT3_PD 0x4000 /* DMICDAT3_PD */
3793#define WM8995_DMICDAT3_PD_MASK 0x4000 /* DMICDAT3_PD */
3794#define WM8995_DMICDAT3_PD_SHIFT 14 /* DMICDAT3_PD */
3795#define WM8995_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */
3796#define WM8995_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */
3797#define WM8995_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */
3798#define WM8995_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */
3799#define WM8995_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */
3800#define WM8995_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */
3801#define WM8995_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */
3802#define WM8995_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */
3803#define WM8995_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */
3804#define WM8995_MCLK2_PU 0x0200 /* MCLK2_PU */
3805#define WM8995_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */
3806#define WM8995_MCLK2_PU_SHIFT 9 /* MCLK2_PU */
3807#define WM8995_MCLK2_PU_WIDTH 1 /* MCLK2_PU */
3808#define WM8995_MCLK2_PD 0x0100 /* MCLK2_PD */
3809#define WM8995_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */
3810#define WM8995_MCLK2_PD_SHIFT 8 /* MCLK2_PD */
3811#define WM8995_MCLK2_PD_WIDTH 1 /* MCLK2_PD */
3812#define WM8995_MCLK1_PU 0x0080 /* MCLK1_PU */
3813#define WM8995_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */
3814#define WM8995_MCLK1_PU_SHIFT 7 /* MCLK1_PU */
3815#define WM8995_MCLK1_PU_WIDTH 1 /* MCLK1_PU */
3816#define WM8995_MCLK1_PD 0x0040 /* MCLK1_PD */
3817#define WM8995_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */
3818#define WM8995_MCLK1_PD_SHIFT 6 /* MCLK1_PD */
3819#define WM8995_MCLK1_PD_WIDTH 1 /* MCLK1_PD */
3820#define WM8995_DACDAT1_PU 0x0020 /* DACDAT1_PU */
3821#define WM8995_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */
3822#define WM8995_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */
3823#define WM8995_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */
3824#define WM8995_DACDAT1_PD 0x0010 /* DACDAT1_PD */
3825#define WM8995_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */
3826#define WM8995_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */
3827#define WM8995_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */
3828#define WM8995_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */
3829#define WM8995_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */
3830#define WM8995_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */
3831#define WM8995_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */
3832#define WM8995_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */
3833#define WM8995_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */
3834#define WM8995_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */
3835#define WM8995_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */
3836#define WM8995_BCLK1_PU 0x0002 /* BCLK1_PU */
3837#define WM8995_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */
3838#define WM8995_BCLK1_PU_SHIFT 1 /* BCLK1_PU */
3839#define WM8995_BCLK1_PU_WIDTH 1 /* BCLK1_PU */
3840#define WM8995_BCLK1_PD 0x0001 /* BCLK1_PD */
3841#define WM8995_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */
3842#define WM8995_BCLK1_PD_SHIFT 0 /* BCLK1_PD */
3843#define WM8995_BCLK1_PD_WIDTH 1 /* BCLK1_PD */
3844
3845/*
3846 * R1825 (0x721) - Pull Control (2)
3847 */
3848#define WM8995_LDO1ENA_PD 0x0010 /* LDO1ENA_PD */
3849#define WM8995_LDO1ENA_PD_MASK 0x0010 /* LDO1ENA_PD */
3850#define WM8995_LDO1ENA_PD_SHIFT 4 /* LDO1ENA_PD */
3851#define WM8995_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */
3852#define WM8995_MODE_PD 0x0004 /* MODE_PD */
3853#define WM8995_MODE_PD_MASK 0x0004 /* MODE_PD */
3854#define WM8995_MODE_PD_SHIFT 2 /* MODE_PD */
3855#define WM8995_MODE_PD_WIDTH 1 /* MODE_PD */
3856#define WM8995_CSNADDR_PD 0x0001 /* CSNADDR_PD */
3857#define WM8995_CSNADDR_PD_MASK 0x0001 /* CSNADDR_PD */
3858#define WM8995_CSNADDR_PD_SHIFT 0 /* CSNADDR_PD */
3859#define WM8995_CSNADDR_PD_WIDTH 1 /* CSNADDR_PD */
3860
3861/*
3862 * R1840 (0x730) - Interrupt Status 1
3863 */
3864#define WM8995_GP14_EINT 0x2000 /* GP14_EINT */
3865#define WM8995_GP14_EINT_MASK 0x2000 /* GP14_EINT */
3866#define WM8995_GP14_EINT_SHIFT 13 /* GP14_EINT */
3867#define WM8995_GP14_EINT_WIDTH 1 /* GP14_EINT */
3868#define WM8995_GP13_EINT 0x1000 /* GP13_EINT */
3869#define WM8995_GP13_EINT_MASK 0x1000 /* GP13_EINT */
3870#define WM8995_GP13_EINT_SHIFT 12 /* GP13_EINT */
3871#define WM8995_GP13_EINT_WIDTH 1 /* GP13_EINT */
3872#define WM8995_GP12_EINT 0x0800 /* GP12_EINT */
3873#define WM8995_GP12_EINT_MASK 0x0800 /* GP12_EINT */
3874#define WM8995_GP12_EINT_SHIFT 11 /* GP12_EINT */
3875#define WM8995_GP12_EINT_WIDTH 1 /* GP12_EINT */
3876#define WM8995_GP11_EINT 0x0400 /* GP11_EINT */
3877#define WM8995_GP11_EINT_MASK 0x0400 /* GP11_EINT */
3878#define WM8995_GP11_EINT_SHIFT 10 /* GP11_EINT */
3879#define WM8995_GP11_EINT_WIDTH 1 /* GP11_EINT */
3880#define WM8995_GP10_EINT 0x0200 /* GP10_EINT */
3881#define WM8995_GP10_EINT_MASK 0x0200 /* GP10_EINT */
3882#define WM8995_GP10_EINT_SHIFT 9 /* GP10_EINT */
3883#define WM8995_GP10_EINT_WIDTH 1 /* GP10_EINT */
3884#define WM8995_GP9_EINT 0x0100 /* GP9_EINT */
3885#define WM8995_GP9_EINT_MASK 0x0100 /* GP9_EINT */
3886#define WM8995_GP9_EINT_SHIFT 8 /* GP9_EINT */
3887#define WM8995_GP9_EINT_WIDTH 1 /* GP9_EINT */
3888#define WM8995_GP8_EINT 0x0080 /* GP8_EINT */
3889#define WM8995_GP8_EINT_MASK 0x0080 /* GP8_EINT */
3890#define WM8995_GP8_EINT_SHIFT 7 /* GP8_EINT */
3891#define WM8995_GP8_EINT_WIDTH 1 /* GP8_EINT */
3892#define WM8995_GP7_EINT 0x0040 /* GP7_EINT */
3893#define WM8995_GP7_EINT_MASK 0x0040 /* GP7_EINT */
3894#define WM8995_GP7_EINT_SHIFT 6 /* GP7_EINT */
3895#define WM8995_GP7_EINT_WIDTH 1 /* GP7_EINT */
3896#define WM8995_GP6_EINT 0x0020 /* GP6_EINT */
3897#define WM8995_GP6_EINT_MASK 0x0020 /* GP6_EINT */
3898#define WM8995_GP6_EINT_SHIFT 5 /* GP6_EINT */
3899#define WM8995_GP6_EINT_WIDTH 1 /* GP6_EINT */
3900#define WM8995_GP5_EINT 0x0010 /* GP5_EINT */
3901#define WM8995_GP5_EINT_MASK 0x0010 /* GP5_EINT */
3902#define WM8995_GP5_EINT_SHIFT 4 /* GP5_EINT */
3903#define WM8995_GP5_EINT_WIDTH 1 /* GP5_EINT */
3904#define WM8995_GP4_EINT 0x0008 /* GP4_EINT */
3905#define WM8995_GP4_EINT_MASK 0x0008 /* GP4_EINT */
3906#define WM8995_GP4_EINT_SHIFT 3 /* GP4_EINT */
3907#define WM8995_GP4_EINT_WIDTH 1 /* GP4_EINT */
3908#define WM8995_GP3_EINT 0x0004 /* GP3_EINT */
3909#define WM8995_GP3_EINT_MASK 0x0004 /* GP3_EINT */
3910#define WM8995_GP3_EINT_SHIFT 2 /* GP3_EINT */
3911#define WM8995_GP3_EINT_WIDTH 1 /* GP3_EINT */
3912#define WM8995_GP2_EINT 0x0002 /* GP2_EINT */
3913#define WM8995_GP2_EINT_MASK 0x0002 /* GP2_EINT */
3914#define WM8995_GP2_EINT_SHIFT 1 /* GP2_EINT */
3915#define WM8995_GP2_EINT_WIDTH 1 /* GP2_EINT */
3916#define WM8995_GP1_EINT 0x0001 /* GP1_EINT */
3917#define WM8995_GP1_EINT_MASK 0x0001 /* GP1_EINT */
3918#define WM8995_GP1_EINT_SHIFT 0 /* GP1_EINT */
3919#define WM8995_GP1_EINT_WIDTH 1 /* GP1_EINT */
3920
3921/*
3922 * R1841 (0x731) - Interrupt Status 2
3923 */
3924#define WM8995_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */
3925#define WM8995_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */
3926#define WM8995_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */
3927#define WM8995_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */
3928#define WM8995_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */
3929#define WM8995_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */
3930#define WM8995_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */
3931#define WM8995_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */
3932#define WM8995_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */
3933#define WM8995_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */
3934#define WM8995_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */
3935#define WM8995_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */
3936#define WM8995_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */
3937#define WM8995_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */
3938#define WM8995_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */
3939#define WM8995_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */
3940#define WM8995_AIF2DRC_SIG_DET_EINT 0x0100 /* AIF2DRC_SIG_DET_EINT */
3941#define WM8995_AIF2DRC_SIG_DET_EINT_MASK 0x0100 /* AIF2DRC_SIG_DET_EINT */
3942#define WM8995_AIF2DRC_SIG_DET_EINT_SHIFT 8 /* AIF2DRC_SIG_DET_EINT */
3943#define WM8995_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* AIF2DRC_SIG_DET_EINT */
3944#define WM8995_AIF1DRC2_SIG_DET_EINT 0x0080 /* AIF1DRC2_SIG_DET_EINT */
3945#define WM8995_AIF1DRC2_SIG_DET_EINT_MASK 0x0080 /* AIF1DRC2_SIG_DET_EINT */
3946#define WM8995_AIF1DRC2_SIG_DET_EINT_SHIFT 7 /* AIF1DRC2_SIG_DET_EINT */
3947#define WM8995_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* AIF1DRC2_SIG_DET_EINT */
3948#define WM8995_AIF1DRC1_SIG_DET_EINT 0x0040 /* AIF1DRC1_SIG_DET_EINT */
3949#define WM8995_AIF1DRC1_SIG_DET_EINT_MASK 0x0040 /* AIF1DRC1_SIG_DET_EINT */
3950#define WM8995_AIF1DRC1_SIG_DET_EINT_SHIFT 6 /* AIF1DRC1_SIG_DET_EINT */
3951#define WM8995_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* AIF1DRC1_SIG_DET_EINT */
3952#define WM8995_SRC2_LOCK_EINT 0x0020 /* SRC2_LOCK_EINT */
3953#define WM8995_SRC2_LOCK_EINT_MASK 0x0020 /* SRC2_LOCK_EINT */
3954#define WM8995_SRC2_LOCK_EINT_SHIFT 5 /* SRC2_LOCK_EINT */
3955#define WM8995_SRC2_LOCK_EINT_WIDTH 1 /* SRC2_LOCK_EINT */
3956#define WM8995_SRC1_LOCK_EINT 0x0010 /* SRC1_LOCK_EINT */
3957#define WM8995_SRC1_LOCK_EINT_MASK 0x0010 /* SRC1_LOCK_EINT */
3958#define WM8995_SRC1_LOCK_EINT_SHIFT 4 /* SRC1_LOCK_EINT */
3959#define WM8995_SRC1_LOCK_EINT_WIDTH 1 /* SRC1_LOCK_EINT */
3960#define WM8995_FLL2_LOCK_EINT 0x0008 /* FLL2_LOCK_EINT */
3961#define WM8995_FLL2_LOCK_EINT_MASK 0x0008 /* FLL2_LOCK_EINT */
3962#define WM8995_FLL2_LOCK_EINT_SHIFT 3 /* FLL2_LOCK_EINT */
3963#define WM8995_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */
3964#define WM8995_FLL1_LOCK_EINT 0x0004 /* FLL1_LOCK_EINT */
3965#define WM8995_FLL1_LOCK_EINT_MASK 0x0004 /* FLL1_LOCK_EINT */
3966#define WM8995_FLL1_LOCK_EINT_SHIFT 2 /* FLL1_LOCK_EINT */
3967#define WM8995_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */
3968#define WM8995_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */
3969#define WM8995_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */
3970#define WM8995_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */
3971#define WM8995_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */
3972#define WM8995_MICD_EINT 0x0001 /* MICD_EINT */
3973#define WM8995_MICD_EINT_MASK 0x0001 /* MICD_EINT */
3974#define WM8995_MICD_EINT_SHIFT 0 /* MICD_EINT */
3975#define WM8995_MICD_EINT_WIDTH 1 /* MICD_EINT */
3976
3977/*
3978 * R1842 (0x732) - Interrupt Raw Status 2
3979 */
3980#define WM8995_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */
3981#define WM8995_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */
3982#define WM8995_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */
3983#define WM8995_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */
3984#define WM8995_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */
3985#define WM8995_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */
3986#define WM8995_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */
3987#define WM8995_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */
3988#define WM8995_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */
3989#define WM8995_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */
3990#define WM8995_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */
3991#define WM8995_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */
3992#define WM8995_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */
3993#define WM8995_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */
3994#define WM8995_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */
3995#define WM8995_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */
3996#define WM8995_AIF2DRC_SIG_DET_STS 0x0100 /* AIF2DRC_SIG_DET_STS */
3997#define WM8995_AIF2DRC_SIG_DET_STS_MASK 0x0100 /* AIF2DRC_SIG_DET_STS */
3998#define WM8995_AIF2DRC_SIG_DET_STS_SHIFT 8 /* AIF2DRC_SIG_DET_STS */
3999#define WM8995_AIF2DRC_SIG_DET_STS_WIDTH 1 /* AIF2DRC_SIG_DET_STS */
4000#define WM8995_AIF1DRC2_SIG_DET_STS 0x0080 /* AIF1DRC2_SIG_DET_STS */
4001#define WM8995_AIF1DRC2_SIG_DET_STS_MASK 0x0080 /* AIF1DRC2_SIG_DET_STS */
4002#define WM8995_AIF1DRC2_SIG_DET_STS_SHIFT 7 /* AIF1DRC2_SIG_DET_STS */
4003#define WM8995_AIF1DRC2_SIG_DET_STS_WIDTH 1 /* AIF1DRC2_SIG_DET_STS */
4004#define WM8995_AIF1DRC1_SIG_DET_STS 0x0040 /* AIF1DRC1_SIG_DET_STS */
4005#define WM8995_AIF1DRC1_SIG_DET_STS_MASK 0x0040 /* AIF1DRC1_SIG_DET_STS */
4006#define WM8995_AIF1DRC1_SIG_DET_STS_SHIFT 6 /* AIF1DRC1_SIG_DET_STS */
4007#define WM8995_AIF1DRC1_SIG_DET_STS_WIDTH 1 /* AIF1DRC1_SIG_DET_STS */
4008#define WM8995_SRC2_LOCK_STS 0x0020 /* SRC2_LOCK_STS */
4009#define WM8995_SRC2_LOCK_STS_MASK 0x0020 /* SRC2_LOCK_STS */
4010#define WM8995_SRC2_LOCK_STS_SHIFT 5 /* SRC2_LOCK_STS */
4011#define WM8995_SRC2_LOCK_STS_WIDTH 1 /* SRC2_LOCK_STS */
4012#define WM8995_SRC1_LOCK_STS 0x0010 /* SRC1_LOCK_STS */
4013#define WM8995_SRC1_LOCK_STS_MASK 0x0010 /* SRC1_LOCK_STS */
4014#define WM8995_SRC1_LOCK_STS_SHIFT 4 /* SRC1_LOCK_STS */
4015#define WM8995_SRC1_LOCK_STS_WIDTH 1 /* SRC1_LOCK_STS */
4016#define WM8995_FLL2_LOCK_STS 0x0008 /* FLL2_LOCK_STS */
4017#define WM8995_FLL2_LOCK_STS_MASK 0x0008 /* FLL2_LOCK_STS */
4018#define WM8995_FLL2_LOCK_STS_SHIFT 3 /* FLL2_LOCK_STS */
4019#define WM8995_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */
4020#define WM8995_FLL1_LOCK_STS 0x0004 /* FLL1_LOCK_STS */
4021#define WM8995_FLL1_LOCK_STS_MASK 0x0004 /* FLL1_LOCK_STS */
4022#define WM8995_FLL1_LOCK_STS_SHIFT 2 /* FLL1_LOCK_STS */
4023#define WM8995_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */
4024
4025/*
4026 * R1848 (0x738) - Interrupt Status 1 Mask
4027 */
4028#define WM8995_IM_GP14_EINT 0x2000 /* IM_GP14_EINT */
4029#define WM8995_IM_GP14_EINT_MASK 0x2000 /* IM_GP14_EINT */
4030#define WM8995_IM_GP14_EINT_SHIFT 13 /* IM_GP14_EINT */
4031#define WM8995_IM_GP14_EINT_WIDTH 1 /* IM_GP14_EINT */
4032#define WM8995_IM_GP13_EINT 0x1000 /* IM_GP13_EINT */
4033#define WM8995_IM_GP13_EINT_MASK 0x1000 /* IM_GP13_EINT */
4034#define WM8995_IM_GP13_EINT_SHIFT 12 /* IM_GP13_EINT */
4035#define WM8995_IM_GP13_EINT_WIDTH 1 /* IM_GP13_EINT */
4036#define WM8995_IM_GP12_EINT 0x0800 /* IM_GP12_EINT */
4037#define WM8995_IM_GP12_EINT_MASK 0x0800 /* IM_GP12_EINT */
4038#define WM8995_IM_GP12_EINT_SHIFT 11 /* IM_GP12_EINT */
4039#define WM8995_IM_GP12_EINT_WIDTH 1 /* IM_GP12_EINT */
4040#define WM8995_IM_GP11_EINT 0x0400 /* IM_GP11_EINT */
4041#define WM8995_IM_GP11_EINT_MASK 0x0400 /* IM_GP11_EINT */
4042#define WM8995_IM_GP11_EINT_SHIFT 10 /* IM_GP11_EINT */
4043#define WM8995_IM_GP11_EINT_WIDTH 1 /* IM_GP11_EINT */
4044#define WM8995_IM_GP10_EINT 0x0200 /* IM_GP10_EINT */
4045#define WM8995_IM_GP10_EINT_MASK 0x0200 /* IM_GP10_EINT */
4046#define WM8995_IM_GP10_EINT_SHIFT 9 /* IM_GP10_EINT */
4047#define WM8995_IM_GP10_EINT_WIDTH 1 /* IM_GP10_EINT */
4048#define WM8995_IM_GP9_EINT 0x0100 /* IM_GP9_EINT */
4049#define WM8995_IM_GP9_EINT_MASK 0x0100 /* IM_GP9_EINT */
4050#define WM8995_IM_GP9_EINT_SHIFT 8 /* IM_GP9_EINT */
4051#define WM8995_IM_GP9_EINT_WIDTH 1 /* IM_GP9_EINT */
4052#define WM8995_IM_GP8_EINT 0x0080 /* IM_GP8_EINT */
4053#define WM8995_IM_GP8_EINT_MASK 0x0080 /* IM_GP8_EINT */
4054#define WM8995_IM_GP8_EINT_SHIFT 7 /* IM_GP8_EINT */
4055#define WM8995_IM_GP8_EINT_WIDTH 1 /* IM_GP8_EINT */
4056#define WM8995_IM_GP7_EINT 0x0040 /* IM_GP7_EINT */
4057#define WM8995_IM_GP7_EINT_MASK 0x0040 /* IM_GP7_EINT */
4058#define WM8995_IM_GP7_EINT_SHIFT 6 /* IM_GP7_EINT */
4059#define WM8995_IM_GP7_EINT_WIDTH 1 /* IM_GP7_EINT */
4060#define WM8995_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */
4061#define WM8995_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */
4062#define WM8995_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */
4063#define WM8995_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */
4064#define WM8995_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */
4065#define WM8995_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */
4066#define WM8995_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */
4067#define WM8995_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */
4068#define WM8995_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */
4069#define WM8995_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */
4070#define WM8995_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */
4071#define WM8995_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */
4072#define WM8995_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */
4073#define WM8995_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */
4074#define WM8995_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */
4075#define WM8995_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */
4076#define WM8995_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */
4077#define WM8995_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */
4078#define WM8995_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */
4079#define WM8995_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */
4080#define WM8995_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */
4081#define WM8995_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */
4082#define WM8995_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */
4083#define WM8995_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */
4084
4085/*
4086 * R1849 (0x739) - Interrupt Status 2 Mask
4087 */
4088#define WM8995_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */
4089#define WM8995_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */
4090#define WM8995_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */
4091#define WM8995_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */
4092#define WM8995_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */
4093#define WM8995_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */
4094#define WM8995_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */
4095#define WM8995_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */
4096#define WM8995_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */
4097#define WM8995_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */
4098#define WM8995_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */
4099#define WM8995_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */
4100#define WM8995_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */
4101#define WM8995_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */
4102#define WM8995_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */
4103#define WM8995_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */
4104#define WM8995_IM_AIF2DRC_SIG_DET_EINT 0x0100 /* IM_AIF2DRC_SIG_DET_EINT */
4105#define WM8995_IM_AIF2DRC_SIG_DET_EINT_MASK 0x0100 /* IM_AIF2DRC_SIG_DET_EINT */
4106#define WM8995_IM_AIF2DRC_SIG_DET_EINT_SHIFT 8 /* IM_AIF2DRC_SIG_DET_EINT */
4107#define WM8995_IM_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* IM_AIF2DRC_SIG_DET_EINT */
4108#define WM8995_IM_AIF1DRC2_SIG_DET_EINT 0x0080 /* IM_AIF1DRC2_SIG_DET_EINT */
4109#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_MASK 0x0080 /* IM_AIF1DRC2_SIG_DET_EINT */
4110#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_SHIFT 7 /* IM_AIF1DRC2_SIG_DET_EINT */
4111#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC2_SIG_DET_EINT */
4112#define WM8995_IM_AIF1DRC1_SIG_DET_EINT 0x0040 /* IM_AIF1DRC1_SIG_DET_EINT */
4113#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_MASK 0x0040 /* IM_AIF1DRC1_SIG_DET_EINT */
4114#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_SHIFT 6 /* IM_AIF1DRC1_SIG_DET_EINT */
4115#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC1_SIG_DET_EINT */
4116#define WM8995_IM_SRC2_LOCK_EINT 0x0020 /* IM_SRC2_LOCK_EINT */
4117#define WM8995_IM_SRC2_LOCK_EINT_MASK 0x0020 /* IM_SRC2_LOCK_EINT */
4118#define WM8995_IM_SRC2_LOCK_EINT_SHIFT 5 /* IM_SRC2_LOCK_EINT */
4119#define WM8995_IM_SRC2_LOCK_EINT_WIDTH 1 /* IM_SRC2_LOCK_EINT */
4120#define WM8995_IM_SRC1_LOCK_EINT 0x0010 /* IM_SRC1_LOCK_EINT */
4121#define WM8995_IM_SRC1_LOCK_EINT_MASK 0x0010 /* IM_SRC1_LOCK_EINT */
4122#define WM8995_IM_SRC1_LOCK_EINT_SHIFT 4 /* IM_SRC1_LOCK_EINT */
4123#define WM8995_IM_SRC1_LOCK_EINT_WIDTH 1 /* IM_SRC1_LOCK_EINT */
4124#define WM8995_IM_FLL2_LOCK_EINT 0x0008 /* IM_FLL2_LOCK_EINT */
4125#define WM8995_IM_FLL2_LOCK_EINT_MASK 0x0008 /* IM_FLL2_LOCK_EINT */
4126#define WM8995_IM_FLL2_LOCK_EINT_SHIFT 3 /* IM_FLL2_LOCK_EINT */
4127#define WM8995_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */
4128#define WM8995_IM_FLL1_LOCK_EINT 0x0004 /* IM_FLL1_LOCK_EINT */
4129#define WM8995_IM_FLL1_LOCK_EINT_MASK 0x0004 /* IM_FLL1_LOCK_EINT */
4130#define WM8995_IM_FLL1_LOCK_EINT_SHIFT 2 /* IM_FLL1_LOCK_EINT */
4131#define WM8995_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */
4132#define WM8995_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */
4133#define WM8995_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */
4134#define WM8995_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */
4135#define WM8995_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */
4136#define WM8995_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */
4137#define WM8995_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */
4138#define WM8995_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */
4139#define WM8995_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */
4140
4141/*
4142 * R1856 (0x740) - Interrupt Control
4143 */
4144#define WM8995_IM_IRQ 0x0001 /* IM_IRQ */
4145#define WM8995_IM_IRQ_MASK 0x0001 /* IM_IRQ */
4146#define WM8995_IM_IRQ_SHIFT 0 /* IM_IRQ */
4147#define WM8995_IM_IRQ_WIDTH 1 /* IM_IRQ */
4148
4149/*
4150 * R2048 (0x800) - Left PDM Speaker 1
4151 */
4152#define WM8995_SPK1L_ENA 0x0010 /* SPK1L_ENA */
4153#define WM8995_SPK1L_ENA_MASK 0x0010 /* SPK1L_ENA */
4154#define WM8995_SPK1L_ENA_SHIFT 4 /* SPK1L_ENA */
4155#define WM8995_SPK1L_ENA_WIDTH 1 /* SPK1L_ENA */
4156#define WM8995_SPK1L_MUTE 0x0008 /* SPK1L_MUTE */
4157#define WM8995_SPK1L_MUTE_MASK 0x0008 /* SPK1L_MUTE */
4158#define WM8995_SPK1L_MUTE_SHIFT 3 /* SPK1L_MUTE */
4159#define WM8995_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */
4160#define WM8995_SPK1L_MUTE_ZC 0x0004 /* SPK1L_MUTE_ZC */
4161#define WM8995_SPK1L_MUTE_ZC_MASK 0x0004 /* SPK1L_MUTE_ZC */
4162#define WM8995_SPK1L_MUTE_ZC_SHIFT 2 /* SPK1L_MUTE_ZC */
4163#define WM8995_SPK1L_MUTE_ZC_WIDTH 1 /* SPK1L_MUTE_ZC */
4164#define WM8995_SPK1L_SRC_MASK 0x0003 /* SPK1L_SRC - [1:0] */
4165#define WM8995_SPK1L_SRC_SHIFT 0 /* SPK1L_SRC - [1:0] */
4166#define WM8995_SPK1L_SRC_WIDTH 2 /* SPK1L_SRC - [1:0] */
4167
4168/*
4169 * R2049 (0x801) - Right PDM Speaker 1
4170 */
4171#define WM8995_SPK1R_ENA 0x0010 /* SPK1R_ENA */
4172#define WM8995_SPK1R_ENA_MASK 0x0010 /* SPK1R_ENA */
4173#define WM8995_SPK1R_ENA_SHIFT 4 /* SPK1R_ENA */
4174#define WM8995_SPK1R_ENA_WIDTH 1 /* SPK1R_ENA */
4175#define WM8995_SPK1R_MUTE 0x0008 /* SPK1R_MUTE */
4176#define WM8995_SPK1R_MUTE_MASK 0x0008 /* SPK1R_MUTE */
4177#define WM8995_SPK1R_MUTE_SHIFT 3 /* SPK1R_MUTE */
4178#define WM8995_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */
4179#define WM8995_SPK1R_MUTE_ZC 0x0004 /* SPK1R_MUTE_ZC */
4180#define WM8995_SPK1R_MUTE_ZC_MASK 0x0004 /* SPK1R_MUTE_ZC */
4181#define WM8995_SPK1R_MUTE_ZC_SHIFT 2 /* SPK1R_MUTE_ZC */
4182#define WM8995_SPK1R_MUTE_ZC_WIDTH 1 /* SPK1R_MUTE_ZC */
4183#define WM8995_SPK1R_SRC_MASK 0x0003 /* SPK1R_SRC - [1:0] */
4184#define WM8995_SPK1R_SRC_SHIFT 0 /* SPK1R_SRC - [1:0] */
4185#define WM8995_SPK1R_SRC_WIDTH 2 /* SPK1R_SRC - [1:0] */
4186
4187/*
4188 * R2050 (0x802) - PDM Speaker 1 Mute Sequence
4189 */
4190#define WM8995_SPK1_MUTE_SEQ1_MASK 0x00FF /* SPK1_MUTE_SEQ1 - [7:0] */
4191#define WM8995_SPK1_MUTE_SEQ1_SHIFT 0 /* SPK1_MUTE_SEQ1 - [7:0] */
4192#define WM8995_SPK1_MUTE_SEQ1_WIDTH 8 /* SPK1_MUTE_SEQ1 - [7:0] */
4193
4194/*
4195 * R2056 (0x808) - Left PDM Speaker 2
4196 */
4197#define WM8995_SPK2L_ENA 0x0010 /* SPK2L_ENA */
4198#define WM8995_SPK2L_ENA_MASK 0x0010 /* SPK2L_ENA */
4199#define WM8995_SPK2L_ENA_SHIFT 4 /* SPK2L_ENA */
4200#define WM8995_SPK2L_ENA_WIDTH 1 /* SPK2L_ENA */
4201#define WM8995_SPK2L_MUTE 0x0008 /* SPK2L_MUTE */
4202#define WM8995_SPK2L_MUTE_MASK 0x0008 /* SPK2L_MUTE */
4203#define WM8995_SPK2L_MUTE_SHIFT 3 /* SPK2L_MUTE */
4204#define WM8995_SPK2L_MUTE_WIDTH 1 /* SPK2L_MUTE */
4205#define WM8995_SPK2L_MUTE_ZC 0x0004 /* SPK2L_MUTE_ZC */
4206#define WM8995_SPK2L_MUTE_ZC_MASK 0x0004 /* SPK2L_MUTE_ZC */
4207#define WM8995_SPK2L_MUTE_ZC_SHIFT 2 /* SPK2L_MUTE_ZC */
4208#define WM8995_SPK2L_MUTE_ZC_WIDTH 1 /* SPK2L_MUTE_ZC */
4209#define WM8995_SPK2L_SRC_MASK 0x0003 /* SPK2L_SRC - [1:0] */
4210#define WM8995_SPK2L_SRC_SHIFT 0 /* SPK2L_SRC - [1:0] */
4211#define WM8995_SPK2L_SRC_WIDTH 2 /* SPK2L_SRC - [1:0] */
4212
4213/*
4214 * R2057 (0x809) - Right PDM Speaker 2
4215 */
4216#define WM8995_SPK2R_ENA 0x0010 /* SPK2R_ENA */
4217#define WM8995_SPK2R_ENA_MASK 0x0010 /* SPK2R_ENA */
4218#define WM8995_SPK2R_ENA_SHIFT 4 /* SPK2R_ENA */
4219#define WM8995_SPK2R_ENA_WIDTH 1 /* SPK2R_ENA */
4220#define WM8995_SPK2R_MUTE 0x0008 /* SPK2R_MUTE */
4221#define WM8995_SPK2R_MUTE_MASK 0x0008 /* SPK2R_MUTE */
4222#define WM8995_SPK2R_MUTE_SHIFT 3 /* SPK2R_MUTE */
4223#define WM8995_SPK2R_MUTE_WIDTH 1 /* SPK2R_MUTE */
4224#define WM8995_SPK2R_MUTE_ZC 0x0004 /* SPK2R_MUTE_ZC */
4225#define WM8995_SPK2R_MUTE_ZC_MASK 0x0004 /* SPK2R_MUTE_ZC */
4226#define WM8995_SPK2R_MUTE_ZC_SHIFT 2 /* SPK2R_MUTE_ZC */
4227#define WM8995_SPK2R_MUTE_ZC_WIDTH 1 /* SPK2R_MUTE_ZC */
4228#define WM8995_SPK2R_SRC_MASK 0x0003 /* SPK2R_SRC - [1:0] */
4229#define WM8995_SPK2R_SRC_SHIFT 0 /* SPK2R_SRC - [1:0] */
4230#define WM8995_SPK2R_SRC_WIDTH 2 /* SPK2R_SRC - [1:0] */
4231
4232/*
4233 * R2058 (0x80A) - PDM Speaker 2 Mute Sequence
4234 */
4235#define WM8995_SPK2_MUTE_SEQ1_MASK 0x00FF /* SPK2_MUTE_SEQ1 - [7:0] */
4236#define WM8995_SPK2_MUTE_SEQ1_SHIFT 0 /* SPK2_MUTE_SEQ1 - [7:0] */
4237#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */
4238
4239#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \
4240{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
4241 .info = snd_soc_info_volsw, \
4242 .get = snd_soc_dapm_get_volsw, .put = wm8995_put_class_w, \
4243 .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) \
4244}
4245
4246struct wm8995_reg_access {
4247 u16 read;
4248 u16 write;
4249 u16 vol;
4250};
4251
4252/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */
4253enum clk_src {
4254 WM8995_SYSCLK_MCLK1 = 1,
4255 WM8995_SYSCLK_MCLK2,
4256 WM8995_SYSCLK_FLL1,
4257 WM8995_SYSCLK_FLL2,
4258 WM8995_SYSCLK_OPCLK
4259};
4260
4261#define WM8995_FLL1 1
4262#define WM8995_FLL2 2
4263
4264#define WM8995_FLL_SRC_MCLK1 1
4265#define WM8995_FLL_SRC_MCLK2 2
4266#define WM8995_FLL_SRC_LRCLK 3
4267#define WM8995_FLL_SRC_BCLK 4
4268
4269#endif /* _WM8995_H */
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index a486670966bd..43825b2102a5 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -23,7 +23,6 @@
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 26#include <sound/initval.h>
28#include <sound/tlv.h> 27#include <sound/tlv.h>
29 28
@@ -158,7 +157,6 @@ static struct {
158struct wm9081_priv { 157struct wm9081_priv {
159 enum snd_soc_control_type control_type; 158 enum snd_soc_control_type control_type;
160 void *control_data; 159 void *control_data;
161 u16 reg_cache[WM9081_MAX_REGISTER + 1];
162 int sysclk_source; 160 int sysclk_source;
163 int mclk_rate; 161 int mclk_rate;
164 int sysclk_rate; 162 int sysclk_rate;
@@ -591,6 +589,10 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
591 reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT; 589 reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT;
592 snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5); 590 snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5);
593 591
592 /* Set gain to the recommended value */
593 snd_soc_update_bits(codec, WM9081_FLL_CONTROL_4,
594 WM9081_FLL_GAIN_MASK, 0);
595
594 /* Enable the FLL */ 596 /* Enable the FLL */
595 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA); 597 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);
596 598
@@ -805,7 +807,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
805 807
806 case SND_SOC_BIAS_STANDBY: 808 case SND_SOC_BIAS_STANDBY:
807 /* Initial cold start */ 809 /* Initial cold start */
808 if (codec->bias_level == SND_SOC_BIAS_OFF) { 810 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
809 /* Disable LINEOUT discharge */ 811 /* Disable LINEOUT discharge */
810 reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL); 812 reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
811 reg &= ~WM9081_LINEOUT_DISCH; 813 reg &= ~WM9081_LINEOUT_DISCH;
@@ -865,7 +867,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
865 break; 867 break;
866 } 868 }
867 869
868 codec->bias_level = level; 870 codec->dapm.bias_level = level;
869 871
870 return 0; 872 return 0;
871} 873}
@@ -1228,6 +1230,7 @@ static struct snd_soc_dai_driver wm9081_dai = {
1228static int wm9081_probe(struct snd_soc_codec *codec) 1230static int wm9081_probe(struct snd_soc_codec *codec)
1229{ 1231{
1230 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1232 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1233 struct snd_soc_dapm_context *dapm = &codec->dapm;
1231 int ret; 1234 int ret;
1232 u16 reg; 1235 u16 reg;
1233 1236
@@ -1269,9 +1272,9 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1269 ARRAY_SIZE(wm9081_eq_controls)); 1272 ARRAY_SIZE(wm9081_eq_controls));
1270 } 1273 }
1271 1274
1272 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets, 1275 snd_soc_dapm_new_controls(dapm, wm9081_dapm_widgets,
1273 ARRAY_SIZE(wm9081_dapm_widgets)); 1276 ARRAY_SIZE(wm9081_dapm_widgets));
1274 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); 1277 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
1275 1278
1276 return ret; 1279 return ret;
1277} 1280}
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 6e5f64f627cb..a788c4297046 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -28,7 +28,6 @@
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <sound/initval.h> 29#include <sound/initval.h>
30#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/tlv.h> 31#include <sound/tlv.h>
33#include <sound/wm9090.h> 32#include <sound/wm9090.h>
34 33
@@ -442,31 +441,32 @@ static const struct snd_soc_dapm_route audio_map_in2_diff[] = {
442static int wm9090_add_controls(struct snd_soc_codec *codec) 441static int wm9090_add_controls(struct snd_soc_codec *codec)
443{ 442{
444 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); 443 struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec);
444 struct snd_soc_dapm_context *dapm = &codec->dapm;
445 int i; 445 int i;
446 446
447 snd_soc_dapm_new_controls(codec, wm9090_dapm_widgets, 447 snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets,
448 ARRAY_SIZE(wm9090_dapm_widgets)); 448 ARRAY_SIZE(wm9090_dapm_widgets));
449 449
450 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 450 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
451 451
452 snd_soc_add_controls(codec, wm9090_controls, 452 snd_soc_add_controls(codec, wm9090_controls,
453 ARRAY_SIZE(wm9090_controls)); 453 ARRAY_SIZE(wm9090_controls));
454 454
455 if (wm9090->pdata.lin1_diff) { 455 if (wm9090->pdata.lin1_diff) {
456 snd_soc_dapm_add_routes(codec, audio_map_in1_diff, 456 snd_soc_dapm_add_routes(dapm, audio_map_in1_diff,
457 ARRAY_SIZE(audio_map_in1_diff)); 457 ARRAY_SIZE(audio_map_in1_diff));
458 } else { 458 } else {
459 snd_soc_dapm_add_routes(codec, audio_map_in1_se, 459 snd_soc_dapm_add_routes(dapm, audio_map_in1_se,
460 ARRAY_SIZE(audio_map_in1_se)); 460 ARRAY_SIZE(audio_map_in1_se));
461 snd_soc_add_controls(codec, wm9090_in1_se_controls, 461 snd_soc_add_controls(codec, wm9090_in1_se_controls,
462 ARRAY_SIZE(wm9090_in1_se_controls)); 462 ARRAY_SIZE(wm9090_in1_se_controls));
463 } 463 }
464 464
465 if (wm9090->pdata.lin2_diff) { 465 if (wm9090->pdata.lin2_diff) {
466 snd_soc_dapm_add_routes(codec, audio_map_in2_diff, 466 snd_soc_dapm_add_routes(dapm, audio_map_in2_diff,
467 ARRAY_SIZE(audio_map_in2_diff)); 467 ARRAY_SIZE(audio_map_in2_diff));
468 } else { 468 } else {
469 snd_soc_dapm_add_routes(codec, audio_map_in2_se, 469 snd_soc_dapm_add_routes(dapm, audio_map_in2_se,
470 ARRAY_SIZE(audio_map_in2_se)); 470 ARRAY_SIZE(audio_map_in2_se));
471 snd_soc_add_controls(codec, wm9090_in2_se_controls, 471 snd_soc_add_controls(codec, wm9090_in2_se_controls,
472 ARRAY_SIZE(wm9090_in2_se_controls)); 472 ARRAY_SIZE(wm9090_in2_se_controls));
@@ -513,7 +513,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
513 break; 513 break;
514 514
515 case SND_SOC_BIAS_STANDBY: 515 case SND_SOC_BIAS_STANDBY:
516 if (codec->bias_level == SND_SOC_BIAS_OFF) { 516 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
517 /* Restore the register cache */ 517 /* Restore the register cache */
518 for (i = 1; i < codec->driver->reg_cache_size; i++) { 518 for (i = 1; i < codec->driver->reg_cache_size; i++) {
519 if (reg_cache[i] == wm9090_reg_defaults[i]) 519 if (reg_cache[i] == wm9090_reg_defaults[i])
@@ -543,7 +543,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec,
543 break; 543 break;
544 } 544 }
545 545
546 codec->bias_level = level; 546 codec->dapm.bias_level = level;
547 547
548 return 0; 548 return 0;
549} 549}
diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c
index a144acda751c..47b357adabdd 100644
--- a/sound/soc/codecs/wm9705.c
+++ b/sound/soc/codecs/wm9705.c
@@ -19,7 +19,6 @@
19#include <sound/ac97_codec.h> 19#include <sound/ac97_codec.h>
20#include <sound/initval.h> 20#include <sound/initval.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23 22
24#include "wm9705.h" 23#include "wm9705.h"
25 24
@@ -203,9 +202,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
203 202
204static int wm9705_add_widgets(struct snd_soc_codec *codec) 203static int wm9705_add_widgets(struct snd_soc_codec *codec)
205{ 204{
206 snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets, 205 struct snd_soc_dapm_context *dapm = &codec->dapm;
206
207 snd_soc_dapm_new_controls(dapm, wm9705_dapm_widgets,
207 ARRAY_SIZE(wm9705_dapm_widgets)); 208 ARRAY_SIZE(wm9705_dapm_widgets));
208 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 209 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
209 210
210 return 0; 211 return 0;
211} 212}
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index d2f224d62744..bf5d4ef1a2a6 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -20,7 +20,6 @@
20#include <sound/ac97_codec.h> 20#include <sound/ac97_codec.h>
21#include <sound/initval.h> 21#include <sound/initval.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include "wm9712.h" 23#include "wm9712.h"
25 24
26#define WM9712_VERSION "0.4" 25#define WM9712_VERSION "0.4"
@@ -432,10 +431,11 @@ static const struct snd_soc_dapm_route audio_map[] = {
432 431
433static int wm9712_add_widgets(struct snd_soc_codec *codec) 432static int wm9712_add_widgets(struct snd_soc_codec *codec)
434{ 433{
435 snd_soc_dapm_new_controls(codec, wm9712_dapm_widgets, 434 struct snd_soc_dapm_context *dapm = &codec->dapm;
436 ARRAY_SIZE(wm9712_dapm_widgets));
437 435
438 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 436 snd_soc_dapm_new_controls(dapm, wm9712_dapm_widgets,
437 ARRAY_SIZE(wm9712_dapm_widgets));
438 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
439 439
440 return 0; 440 return 0;
441} 441}
@@ -570,7 +570,7 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec,
570 ac97_write(codec, AC97_POWERDOWN, 0xffff); 570 ac97_write(codec, AC97_POWERDOWN, 0xffff);
571 break; 571 break;
572 } 572 }
573 codec->bias_level = level; 573 codec->dapm.bias_level = level;
574 return 0; 574 return 0;
575} 575}
576 576
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 7da13b07a53d..38ed98558718 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -26,7 +26,6 @@
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27#include <sound/tlv.h> 27#include <sound/tlv.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30 29
31#include "wm9713.h" 30#include "wm9713.h"
32 31
@@ -647,10 +646,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
647 646
648static int wm9713_add_widgets(struct snd_soc_codec *codec) 647static int wm9713_add_widgets(struct snd_soc_codec *codec)
649{ 648{
650 snd_soc_dapm_new_controls(codec, wm9713_dapm_widgets, 649 struct snd_soc_dapm_context *dapm = &codec->dapm;
650
651 snd_soc_dapm_new_controls(dapm, wm9713_dapm_widgets,
651 ARRAY_SIZE(wm9713_dapm_widgets)); 652 ARRAY_SIZE(wm9713_dapm_widgets));
652 653
653 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 654 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
654 655
655 return 0; 656 return 0;
656} 657}
@@ -1147,7 +1148,7 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec,
1147 ac97_write(codec, AC97_POWERDOWN, 0xffff); 1148 ac97_write(codec, AC97_POWERDOWN, 0xffff);
1148 break; 1149 break;
1149 } 1150 }
1150 codec->bias_level = level; 1151 codec->dapm.bias_level = level;
1151 return 0; 1152 return 0;
1152} 1153}
1153 1154
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index 0e24092722c3..c466982eed23 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -22,7 +22,6 @@
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/pcm_params.h> 23#include <sound/pcm_params.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <sound/initval.h> 25#include <sound/initval.h>
27#include <sound/tlv.h> 26#include <sound/tlv.h>
28 27
@@ -94,41 +93,61 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
94 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); 93 struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
95 u16 reg, reg_l, reg_r, dcs_cfg; 94 u16 reg, reg_l, reg_r, dcs_cfg;
96 95
97 /* Set for 32 series updates */ 96 /* If we're using a digital only path and have a previously
98 snd_soc_update_bits(codec, WM8993_DC_SERVO_1, 97 * callibrated DC servo offset stored then use that. */
99 WM8993_DCS_SERIES_NO_01_MASK, 98 if (hubs->class_w && hubs->class_w_dcs) {
100 32 << WM8993_DCS_SERIES_NO_01_SHIFT); 99 dev_dbg(codec->dev, "Using cached DC servo offset %x\n",
101 wait_for_dc_servo(codec, 100 hubs->class_w_dcs);
102 WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1); 101 snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs);
102 wait_for_dc_servo(codec,
103 WM8993_DCS_TRIG_DAC_WR_0 |
104 WM8993_DCS_TRIG_DAC_WR_1);
105 return;
106 }
107
108 /* Devices not using a DCS code correction have startup mode */
109 if (hubs->dcs_codes) {
110 /* Set for 32 series updates */
111 snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
112 WM8993_DCS_SERIES_NO_01_MASK,
113 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
114 wait_for_dc_servo(codec,
115 WM8993_DCS_TRIG_SERIES_0 |
116 WM8993_DCS_TRIG_SERIES_1);
117 } else {
118 wait_for_dc_servo(codec,
119 WM8993_DCS_TRIG_STARTUP_0 |
120 WM8993_DCS_TRIG_STARTUP_1);
121 }
122
123 /* Different chips in the family support different readback
124 * methods.
125 */
126 switch (hubs->dcs_readback_mode) {
127 case 0:
128 reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
129 & WM8993_DCS_INTEG_CHAN_0_MASK;
130 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
131 & WM8993_DCS_INTEG_CHAN_1_MASK;
132 break;
133 case 1:
134 reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
135 reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
136 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
137 reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
138 break;
139 default:
140 WARN(1, "Unknown DCS readback method\n");
141 break;
142 }
143
144 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
103 145
104 /* Apply correction to DC servo result */ 146 /* Apply correction to DC servo result */
105 if (hubs->dcs_codes) { 147 if (hubs->dcs_codes) {
106 dev_dbg(codec->dev, "Applying %d code DC servo correction\n", 148 dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
107 hubs->dcs_codes); 149 hubs->dcs_codes);
108 150
109 /* Different chips in the family support different
110 * readback methods.
111 */
112 switch (hubs->dcs_readback_mode) {
113 case 0:
114 reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
115 & WM8993_DCS_INTEG_CHAN_0_MASK;;
116 reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
117 & WM8993_DCS_INTEG_CHAN_1_MASK;
118 break;
119 case 1:
120 reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
121 reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
122 >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
123 reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
124 break;
125 default:
126 WARN(1, "Unknown DCS readback method\n");
127 break;
128 }
129
130 dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
131
132 /* HPOUT1L */ 151 /* HPOUT1L */
133 if (reg_l + hubs->dcs_codes > 0 && 152 if (reg_l + hubs->dcs_codes > 0 &&
134 reg_l + hubs->dcs_codes < 0xff) 153 reg_l + hubs->dcs_codes < 0xff)
@@ -148,7 +167,15 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
148 wait_for_dc_servo(codec, 167 wait_for_dc_servo(codec,
149 WM8993_DCS_TRIG_DAC_WR_0 | 168 WM8993_DCS_TRIG_DAC_WR_0 |
150 WM8993_DCS_TRIG_DAC_WR_1); 169 WM8993_DCS_TRIG_DAC_WR_1);
170 } else {
171 dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
172 dcs_cfg |= reg_r;
151 } 173 }
174
175 /* Save the callibrated offset if we're in class W mode and
176 * therefore don't have any analogue signal mixed in. */
177 if (hubs->class_w)
178 hubs->class_w_dcs = dcs_cfg;
152} 179}
153 180
154/* 181/*
@@ -163,6 +190,9 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
163 190
164 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 191 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
165 192
193 /* Updating the analogue gains invalidates the DC servo cache */
194 hubs->class_w_dcs = 0;
195
166 /* If we're applying an offset correction then updating the 196 /* If we're applying an offset correction then updating the
167 * callibration would be likely to introduce further offsets. */ 197 * callibration would be likely to introduce further offsets. */
168 if (hubs->dcs_codes) 198 if (hubs->dcs_codes)
@@ -791,6 +821,8 @@ static const struct snd_soc_dapm_route lineout2_se_routes[] = {
791 821
792int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) 822int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
793{ 823{
824 struct snd_soc_dapm_context *dapm = &codec->dapm;
825
794 /* Latch volume update bits & default ZC on */ 826 /* Latch volume update bits & default ZC on */
795 snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME, 827 snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME,
796 WM8993_IN1_VU, WM8993_IN1_VU); 828 WM8993_IN1_VU, WM8993_IN1_VU);
@@ -819,7 +851,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec)
819 snd_soc_add_controls(codec, analogue_snd_controls, 851 snd_soc_add_controls(codec, analogue_snd_controls,
820 ARRAY_SIZE(analogue_snd_controls)); 852 ARRAY_SIZE(analogue_snd_controls));
821 853
822 snd_soc_dapm_new_controls(codec, analogue_dapm_widgets, 854 snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets,
823 ARRAY_SIZE(analogue_dapm_widgets)); 855 ARRAY_SIZE(analogue_dapm_widgets));
824 return 0; 856 return 0;
825} 857}
@@ -828,24 +860,26 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls);
828int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec, 860int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec,
829 int lineout1_diff, int lineout2_diff) 861 int lineout1_diff, int lineout2_diff)
830{ 862{
831 snd_soc_dapm_add_routes(codec, analogue_routes, 863 struct snd_soc_dapm_context *dapm = &codec->dapm;
864
865 snd_soc_dapm_add_routes(dapm, analogue_routes,
832 ARRAY_SIZE(analogue_routes)); 866 ARRAY_SIZE(analogue_routes));
833 867
834 if (lineout1_diff) 868 if (lineout1_diff)
835 snd_soc_dapm_add_routes(codec, 869 snd_soc_dapm_add_routes(dapm,
836 lineout1_diff_routes, 870 lineout1_diff_routes,
837 ARRAY_SIZE(lineout1_diff_routes)); 871 ARRAY_SIZE(lineout1_diff_routes));
838 else 872 else
839 snd_soc_dapm_add_routes(codec, 873 snd_soc_dapm_add_routes(dapm,
840 lineout1_se_routes, 874 lineout1_se_routes,
841 ARRAY_SIZE(lineout1_se_routes)); 875 ARRAY_SIZE(lineout1_se_routes));
842 876
843 if (lineout2_diff) 877 if (lineout2_diff)
844 snd_soc_dapm_add_routes(codec, 878 snd_soc_dapm_add_routes(dapm,
845 lineout2_diff_routes, 879 lineout2_diff_routes,
846 ARRAY_SIZE(lineout2_diff_routes)); 880 ARRAY_SIZE(lineout2_diff_routes));
847 else 881 else
848 snd_soc_dapm_add_routes(codec, 882 snd_soc_dapm_add_routes(dapm,
849 lineout2_se_routes, 883 lineout2_se_routes,
850 ARRAY_SIZE(lineout2_se_routes)); 884 ARRAY_SIZE(lineout2_se_routes));
851 885
@@ -872,7 +906,7 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec,
872 * VMID as an output and can disable it. 906 * VMID as an output and can disable it.
873 */ 907 */
874 if (lineout1_diff && lineout2_diff) 908 if (lineout1_diff && lineout2_diff)
875 codec->idle_bias_off = 1; 909 codec->dapm.idle_bias_off = 1;
876 910
877 if (lineout1fb) 911 if (lineout1fb)
878 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, 912 snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL,
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h
index e51c16683589..f8a5e976b5e6 100644
--- a/sound/soc/codecs/wm_hubs.h
+++ b/sound/soc/codecs/wm_hubs.h
@@ -23,6 +23,9 @@ struct wm_hubs_data {
23 int dcs_codes; 23 int dcs_codes;
24 int dcs_readback_mode; 24 int dcs_readback_mode;
25 int hp_startup_mode; 25 int hp_startup_mode;
26
27 bool class_w;
28 u16 class_w_dcs;
26}; 29};
27 30
28extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); 31extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *);
diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c
index bc9e6b0b3f6f..0c2d6bacc681 100644
--- a/sound/soc/davinci/davinci-evm.c
+++ b/sound/soc/davinci/davinci-evm.c
@@ -18,7 +18,6 @@
18#include <sound/core.h> 18#include <sound/core.h>
19#include <sound/pcm.h> 19#include <sound/pcm.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22 21
23#include <asm/dma.h> 22#include <asm/dma.h>
24#include <asm/mach-types.h> 23#include <asm/mach-types.h>
@@ -27,7 +26,6 @@
27#include <mach/edma.h> 26#include <mach/edma.h>
28#include <mach/mux.h> 27#include <mach/mux.h>
29 28
30#include "../codecs/tlv320aic3x.h"
31#include "davinci-pcm.h" 29#include "davinci-pcm.h"
32#include "davinci-i2s.h" 30#include "davinci-i2s.h"
33#include "davinci-mcasp.h" 31#include "davinci-mcasp.h"
@@ -132,26 +130,27 @@ static const struct snd_soc_dapm_route audio_map[] = {
132static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) 130static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd)
133{ 131{
134 struct snd_soc_codec *codec = rtd->codec; 132 struct snd_soc_codec *codec = rtd->codec;
133 struct snd_soc_dapm_context *dapm = &codec->dapm;
135 134
136 /* Add davinci-evm specific widgets */ 135 /* Add davinci-evm specific widgets */
137 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, 136 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
138 ARRAY_SIZE(aic3x_dapm_widgets)); 137 ARRAY_SIZE(aic3x_dapm_widgets));
139 138
140 /* Set up davinci-evm specific audio path audio_map */ 139 /* Set up davinci-evm specific audio path audio_map */
141 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 140 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
142 141
143 /* not connected */ 142 /* not connected */
144 snd_soc_dapm_disable_pin(codec, "MONO_LOUT"); 143 snd_soc_dapm_disable_pin(dapm, "MONO_LOUT");
145 snd_soc_dapm_disable_pin(codec, "HPLCOM"); 144 snd_soc_dapm_disable_pin(dapm, "HPLCOM");
146 snd_soc_dapm_disable_pin(codec, "HPRCOM"); 145 snd_soc_dapm_disable_pin(dapm, "HPRCOM");
147 146
148 /* always connected */ 147 /* always connected */
149 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 148 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
150 snd_soc_dapm_enable_pin(codec, "Line Out"); 149 snd_soc_dapm_enable_pin(dapm, "Line Out");
151 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 150 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
152 snd_soc_dapm_enable_pin(codec, "Line In"); 151 snd_soc_dapm_enable_pin(dapm, "Line In");
153 152
154 snd_soc_dapm_sync(codec); 153 snd_soc_dapm_sync(dapm);
155 154
156 return 0; 155 return 0;
157} 156}
diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c
index 6c6666a1f942..0fe558c65145 100644
--- a/sound/soc/davinci/davinci-sffsdr.c
+++ b/sound/soc/davinci/davinci-sffsdr.c
@@ -21,7 +21,6 @@
21#include <sound/core.h> 21#include <sound/core.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25 24
26#include <asm/dma.h> 25#include <asm/dma.h>
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c
index 4f4873359613..9ac93f6b4f85 100644
--- a/sound/soc/ep93xx/ep93xx-i2s.c
+++ b/sound/soc/ep93xx/ep93xx-i2s.c
@@ -352,13 +352,13 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = {
352 .playback = { 352 .playback = {
353 .channels_min = 2, 353 .channels_min = 2,
354 .channels_max = 2, 354 .channels_max = 2,
355 .rates = SNDRV_PCM_RATE_8000_48000, 355 .rates = SNDRV_PCM_RATE_8000_96000,
356 .formats = EP93XX_I2S_FORMATS, 356 .formats = EP93XX_I2S_FORMATS,
357 }, 357 },
358 .capture = { 358 .capture = {
359 .channels_min = 2, 359 .channels_min = 2,
360 .channels_max = 2, 360 .channels_max = 2,
361 .rates = SNDRV_PCM_RATE_8000_48000, 361 .rates = SNDRV_PCM_RATE_8000_96000,
362 .formats = EP93XX_I2S_FORMATS, 362 .formats = EP93XX_I2S_FORMATS,
363 }, 363 },
364 .ops = &ep93xx_i2s_dai_ops, 364 .ops = &ep93xx_i2s_dai_ops,
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 2f121ddbe4bb..06670776f649 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -35,9 +35,9 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = {
35 SNDRV_PCM_INFO_INTERLEAVED | 35 SNDRV_PCM_INFO_INTERLEAVED |
36 SNDRV_PCM_INFO_BLOCK_TRANSFER), 36 SNDRV_PCM_INFO_BLOCK_TRANSFER),
37 37
38 .rates = SNDRV_PCM_RATE_8000_48000, 38 .rates = SNDRV_PCM_RATE_8000_96000,
39 .rate_min = SNDRV_PCM_RATE_8000, 39 .rate_min = SNDRV_PCM_RATE_8000,
40 .rate_max = SNDRV_PCM_RATE_48000, 40 .rate_max = SNDRV_PCM_RATE_96000,
41 41
42 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 42 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
43 SNDRV_PCM_FMTBIT_S24_LE | 43 SNDRV_PCM_FMTBIT_S24_LE |
diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c
index 28ab5ff772ac..dfe1d7f74ea6 100644
--- a/sound/soc/ep93xx/snappercl15.c
+++ b/sound/soc/ep93xx/snappercl15.c
@@ -15,7 +15,6 @@
15#include <sound/core.h> 15#include <sound/core.h>
16#include <sound/pcm.h> 16#include <sound/pcm.h>
17#include <sound/soc.h> 17#include <sound/soc.h>
18#include <sound/soc-dapm.h>
19 18
20#include <asm/mach-types.h> 19#include <asm/mach-types.h>
21#include <mach/hardware.h> 20#include <mach/hardware.h>
@@ -79,11 +78,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
79static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) 78static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
80{ 79{
81 struct snd_soc_codec *codec = rtd->codec; 80 struct snd_soc_codec *codec = rtd->codec;
81 struct snd_soc_dapm_context *dapm = &codec->dapm;
82 82
83 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 83 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
84 ARRAY_SIZE(tlv320aic23_dapm_widgets)); 84 ARRAY_SIZE(tlv320aic23_dapm_widgets));
85 85
86 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 86 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
87 return 0; 87 return 0;
88} 88}
89 89
diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c
index dd4fffdbd177..e20c9e1457c0 100644
--- a/sound/soc/imx/eukrea-tlv320.c
+++ b/sound/soc/imx/eukrea-tlv320.c
@@ -22,7 +22,6 @@
22#include <sound/core.h> 22#include <sound/core.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26#include <asm/mach-types.h> 25#include <asm/mach-types.h>
27 26
28#include "../codecs/tlv320aic23.h" 27#include "../codecs/tlv320aic23.h"
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 390b6ffc2658..30894ea7f333 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -456,13 +456,13 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai)
456static struct snd_soc_dai_driver imx_ssi_dai = { 456static struct snd_soc_dai_driver imx_ssi_dai = {
457 .probe = imx_ssi_dai_probe, 457 .probe = imx_ssi_dai_probe,
458 .playback = { 458 .playback = {
459 .channels_min = 2, 459 .channels_min = 1,
460 .channels_max = 2, 460 .channels_max = 2,
461 .rates = SNDRV_PCM_RATE_8000_96000, 461 .rates = SNDRV_PCM_RATE_8000_96000,
462 .formats = SNDRV_PCM_FMTBIT_S16_LE, 462 .formats = SNDRV_PCM_FMTBIT_S16_LE,
463 }, 463 },
464 .capture = { 464 .capture = {
465 .channels_min = 2, 465 .channels_min = 1,
466 .channels_max = 2, 466 .channels_max = 2,
467 .rates = SNDRV_PCM_RATE_8000_96000, 467 .rates = SNDRV_PCM_RATE_8000_96000,
468 .formats = SNDRV_PCM_FMTBIT_S16_LE, 468 .formats = SNDRV_PCM_FMTBIT_S16_LE,
diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c
index 9eabc28667e6..a7deb5cb2433 100644
--- a/sound/soc/imx/phycore-ac97.c
+++ b/sound/soc/imx/phycore-ac97.c
@@ -17,7 +17,6 @@
17#include <sound/core.h> 17#include <sound/core.h>
18#include <sound/pcm.h> 18#include <sound/pcm.h>
19#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21#include <asm/mach-types.h> 20#include <asm/mach-types.h>
22 21
23static struct snd_soc_card imx_phycore; 22static struct snd_soc_card imx_phycore;
diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c
index 30fdb15065be..75b4c72787e2 100644
--- a/sound/soc/imx/wm1133-ev1.c
+++ b/sound/soc/imx/wm1133-ev1.c
@@ -19,7 +19,6 @@
19#include <sound/pcm.h> 19#include <sound/pcm.h>
20#include <sound/pcm_params.h> 20#include <sound/pcm_params.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23 22
24#include <mach/audmux.h> 23#include <mach/audmux.h>
25 24
@@ -213,11 +212,12 @@ static struct snd_soc_jack_pin mic_jack_pins[] = {
213static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) 212static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
214{ 213{
215 struct snd_soc_codec *codec = rtd->codec; 214 struct snd_soc_codec *codec = rtd->codec;
215 struct snd_soc_dapm_context *dapm = &codec->dapm;
216 216
217 snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets, 217 snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets,
218 ARRAY_SIZE(wm1133_ev1_widgets)); 218 ARRAY_SIZE(wm1133_ev1_widgets));
219 219
220 snd_soc_dapm_add_routes(codec, wm1133_ev1_map, 220 snd_soc_dapm_add_routes(dapm, wm1133_ev1_map,
221 ARRAY_SIZE(wm1133_ev1_map)); 221 ARRAY_SIZE(wm1133_ev1_map));
222 222
223 /* Headphone jack detection */ 223 /* Headphone jack detection */
@@ -234,7 +234,7 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd)
234 wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE, 234 wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE,
235 SND_JACK_BTN_0); 235 SND_JACK_BTN_0);
236 236
237 snd_soc_dapm_force_enable_pin(codec, "Mic Bias"); 237 snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
238 238
239 return 0; 239 return 0;
240} 240}
diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c
index f3cffd183401..419bf4f5534a 100644
--- a/sound/soc/jz4740/jz4740-i2s.c
+++ b/sound/soc/jz4740/jz4740-i2s.c
@@ -28,7 +28,6 @@
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29#include <sound/pcm_params.h> 29#include <sound/pcm_params.h>
30#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/initval.h> 31#include <sound/initval.h>
33 32
34#include "jz4740-i2s.h" 33#include "jz4740-i2s.h"
diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c
index ef1a99e6a3bd..49723e3e7e38 100644
--- a/sound/soc/jz4740/qi_lb60.c
+++ b/sound/soc/jz4740/qi_lb60.c
@@ -19,7 +19,6 @@
19#include <sound/core.h> 19#include <sound/core.h>
20#include <sound/pcm.h> 20#include <sound/pcm.h>
21#include <sound/soc.h> 21#include <sound/soc.h>
22#include <sound/soc-dapm.h>
23#include <linux/gpio.h> 22#include <linux/gpio.h>
24 23
25#define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29) 24#define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29)
@@ -59,10 +58,11 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
59{ 58{
60 struct snd_soc_codec *codec = rtd->codec; 59 struct snd_soc_codec *codec = rtd->codec;
61 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 60 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
61 struct snd_soc_dapm_context *dapm = &codec->dapm;
62 int ret; 62 int ret;
63 63
64 snd_soc_dapm_nc_pin(codec, "LIN"); 64 snd_soc_dapm_nc_pin(dapm, "LIN");
65 snd_soc_dapm_nc_pin(codec, "RIN"); 65 snd_soc_dapm_nc_pin(dapm, "RIN");
66 66
67 ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT); 67 ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT);
68 if (ret < 0) { 68 if (ret < 0) {
@@ -70,9 +70,11 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd)
70 return ret; 70 return ret;
71 } 71 }
72 72
73 snd_soc_dapm_new_controls(codec, qi_lb60_widgets, ARRAY_SIZE(qi_lb60_widgets)); 73 snd_soc_dapm_new_controls(dapm, qi_lb60_widgets,
74 snd_soc_dapm_add_routes(codec, qi_lb60_routes, ARRAY_SIZE(qi_lb60_routes)); 74 ARRAY_SIZE(qi_lb60_widgets));
75 snd_soc_dapm_sync(codec); 75 snd_soc_dapm_add_routes(dapm, qi_lb60_routes,
76 ARRAY_SIZE(qi_lb60_routes));
77 snd_soc_dapm_sync(dapm);
76 78
77 return 0; 79 return 0;
78} 80}
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig
index 16ec2a2dba4d..8f49e165f4d1 100644
--- a/sound/soc/kirkwood/Kconfig
+++ b/sound/soc/kirkwood/Kconfig
@@ -11,10 +11,19 @@ config SND_KIRKWOOD_SOC_I2S
11 11
12config SND_KIRKWOOD_SOC_OPENRD 12config SND_KIRKWOOD_SOC_OPENRD
13 tristate "SoC Audio support for Kirkwood Openrd Client" 13 tristate "SoC Audio support for Kirkwood Openrd Client"
14 depends on SND_KIRKWOOD_SOC && MACH_OPENRD_CLIENT 14 depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE)
15 select SND_KIRKWOOD_SOC_I2S 15 select SND_KIRKWOOD_SOC_I2S
16 select SND_SOC_CS42L51 16 select SND_SOC_CS42L51
17 help 17 help
18 Say Y if you want to add support for SoC audio on 18 Say Y if you want to add support for SoC audio on
19 Openrd Client. 19 Openrd Client.
20 20
21config SND_KIRKWOOD_SOC_T5325
22 tristate "SoC Audio support for HP t5325"
23 depends on SND_KIRKWOOD_SOC && MACH_T5325
24 select SND_KIRKWOOD_SOC_I2S
25 select SND_SOC_ALC5623
26 help
27 Say Y if you want to add support for SoC audio on
28 the HP t5325 thin client.
29
diff --git a/sound/soc/kirkwood/Makefile b/sound/soc/kirkwood/Makefile
index 33a16dcab5b5..3e62ae9e7bbe 100644
--- a/sound/soc/kirkwood/Makefile
+++ b/sound/soc/kirkwood/Makefile
@@ -5,5 +5,7 @@ obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o
5obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o 5obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o
6 6
7snd-soc-openrd-objs := kirkwood-openrd.o 7snd-soc-openrd-objs := kirkwood-openrd.o
8snd-soc-t5325-objs := kirkwood-t5325.o
8 9
9obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o 10obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o
11obj-$(CONFIG_SND_KIRKWOOD_SOC_T5325) += snd-soc-t5325.o
diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c
index 9d7c81e921f1..d863afb3ee52 100644
--- a/sound/soc/kirkwood/kirkwood-openrd.c
+++ b/sound/soc/kirkwood/kirkwood-openrd.c
@@ -86,7 +86,7 @@ static int __init openrd_client_init(void)
86{ 86{
87 int ret; 87 int ret;
88 88
89 if (!machine_is_openrd_client()) 89 if (!machine_is_openrd_client() && !machine_is_openrd_ultimate())
90 return 0; 90 return 0;
91 91
92 openrd_client_snd_device = platform_device_alloc("soc-audio", -1); 92 openrd_client_snd_device = platform_device_alloc("soc-audio", -1);
diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c
new file mode 100644
index 000000000000..c8d21956ab52
--- /dev/null
+++ b/sound/soc/kirkwood/kirkwood-t5325.c
@@ -0,0 +1,141 @@
1/*
2 * kirkwood-t5325.c
3 *
4 * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
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#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/interrupt.h>
15#include <linux/platform_device.h>
16#include <linux/slab.h>
17#include <sound/soc.h>
18#include <mach/kirkwood.h>
19#include <plat/audio.h>
20#include <asm/mach-types.h>
21#include "../codecs/alc5623.h"
22
23static int t5325_hw_params(struct snd_pcm_substream *substream,
24 struct snd_pcm_hw_params *params)
25{
26 struct snd_soc_pcm_runtime *rtd = substream->private_data;
27 struct snd_soc_dai *codec_dai = rtd->codec_dai;
28 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
29 int ret;
30 unsigned int freq, fmt;
31
32 fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS;
33 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
34 if (ret < 0)
35 return ret;
36
37 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
38 if (ret < 0)
39 return ret;
40
41 freq = params_rate(params) * 256;
42
43 return snd_soc_dai_set_sysclk(codec_dai, 0, freq, SND_SOC_CLOCK_IN);
44
45}
46
47static struct snd_soc_ops t5325_ops = {
48 .hw_params = t5325_hw_params,
49};
50
51static const struct snd_soc_dapm_widget t5325_dapm_widgets[] = {
52 SND_SOC_DAPM_HP("Headphone Jack", NULL),
53 SND_SOC_DAPM_SPK("Speaker", NULL),
54 SND_SOC_DAPM_MIC("Mic Jack", NULL),
55};
56
57static const struct snd_soc_dapm_route t5325_route[] = {
58 { "Headphone Jack", NULL, "HPL" },
59 { "Headphone Jack", NULL, "HPR" },
60
61 {"Speaker", NULL, "SPKOUT"},
62 {"Speaker", NULL, "SPKOUTN"},
63
64 { "MIC1", NULL, "Mic Jack" },
65 { "MIC2", NULL, "Mic Jack" },
66};
67
68static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd)
69{
70 struct snd_soc_codec *codec = rtd->codec;
71 struct snd_soc_dapm_context *dapm = &codec->dapm;
72
73 snd_soc_dapm_new_controls(dapm, t5325_dapm_widgets,
74 ARRAY_SIZE(t5325_dapm_widgets));
75
76 snd_soc_dapm_add_routes(dapm, t5325_route, ARRAY_SIZE(t5325_route));
77
78 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
79 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
80 snd_soc_dapm_enable_pin(dapm, "Speaker");
81
82 snd_soc_dapm_sync(dapm);
83
84 return 0;
85}
86
87static struct snd_soc_dai_link t5325_dai[] = {
88{
89 .name = "ALC5621",
90 .stream_name = "ALC5621 HiFi",
91 .cpu_dai_name = "kirkwood-i2s",
92 .platform_name = "kirkwood-pcm-audio",
93 .codec_dai_name = "alc5621-hifi",
94 .codec_name = "alc562x-codec.0-001a",
95 .ops = &t5325_ops,
96 .init = t5325_dai_init,
97},
98};
99
100
101static struct snd_soc_card t5325 = {
102 .name = "t5325",
103 .dai_link = t5325_dai,
104 .num_links = ARRAY_SIZE(t5325_dai),
105};
106
107static struct platform_device *t5325_snd_device;
108
109static int __init t5325_init(void)
110{
111 int ret;
112
113 if (!machine_is_t5325())
114 return 0;
115
116 t5325_snd_device = platform_device_alloc("soc-audio", -1);
117 if (!t5325_snd_device)
118 return -ENOMEM;
119
120 platform_set_drvdata(t5325_snd_device,
121 &t5325);
122
123 ret = platform_device_add(t5325_snd_device);
124 if (ret) {
125 printk(KERN_ERR "%s: platform_device_add failed\n", __func__);
126 platform_device_put(t5325_snd_device);
127 }
128
129 return ret;
130}
131module_init(t5325_init);
132
133static void __exit t5325_exit(void)
134{
135 platform_device_unregister(t5325_snd_device);
136}
137module_exit(t5325_exit);
138
139MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
140MODULE_DESCRIPTION("ALSA SoC t5325 audio client");
141MODULE_LICENSE("GPL");
diff --git a/sound/soc/nuc900/nuc900-audio.c b/sound/soc/nuc900/nuc900-audio.c
index 161f5b667d7b..38a2d0d883b5 100644
--- a/sound/soc/nuc900/nuc900-audio.c
+++ b/sound/soc/nuc900/nuc900-audio.c
@@ -18,7 +18,6 @@
18#include <sound/core.h> 18#include <sound/core.h>
19#include <sound/pcm.h> 19#include <sound/pcm.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22 21
23#include "nuc900-audio.h" 22#include "nuc900-audio.h"
24 23
diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c
index 979dd508305f..161750443ebc 100644
--- a/sound/soc/omap/am3517evm.c
+++ b/sound/soc/omap/am3517evm.c
@@ -22,7 +22,6 @@
22#include <sound/core.h> 22#include <sound/core.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26 25
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
28#include <mach/hardware.h> 27#include <mach/hardware.h>
@@ -114,20 +113,21 @@ static const struct snd_soc_dapm_route audio_map[] = {
114static int am3517evm_aic23_init(struct snd_soc_pcm_runtime *rtd) 113static int am3517evm_aic23_init(struct snd_soc_pcm_runtime *rtd)
115{ 114{
116 struct snd_soc_codec *codec = rtd->codec; 115 struct snd_soc_codec *codec = rtd->codec;
116 struct snd_soc_dapm_context *dapm = &codec->dapm;
117 117
118 /* Add am3517-evm specific widgets */ 118 /* Add am3517-evm specific widgets */
119 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 119 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
120 ARRAY_SIZE(tlv320aic23_dapm_widgets)); 120 ARRAY_SIZE(tlv320aic23_dapm_widgets));
121 121
122 /* Set up davinci-evm specific audio path audio_map */ 122 /* Set up davinci-evm specific audio path audio_map */
123 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 123 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
124 124
125 /* always connected */ 125 /* always connected */
126 snd_soc_dapm_enable_pin(codec, "Line Out"); 126 snd_soc_dapm_enable_pin(dapm, "Line Out");
127 snd_soc_dapm_enable_pin(codec, "Line In"); 127 snd_soc_dapm_enable_pin(dapm, "Line In");
128 snd_soc_dapm_enable_pin(codec, "Mic In"); 128 snd_soc_dapm_enable_pin(dapm, "Mic In");
129 129
130 snd_soc_dapm_sync(codec); 130 snd_soc_dapm_sync(dapm);
131 131
132 return 0; 132 return 0;
133} 133}
diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c
index 438146addbb8..2101bdcee21f 100644
--- a/sound/soc/omap/ams-delta.c
+++ b/sound/soc/omap/ams-delta.c
@@ -26,7 +26,7 @@
26#include <linux/spinlock.h> 26#include <linux/spinlock.h>
27#include <linux/tty.h> 27#include <linux/tty.h>
28 28
29#include <sound/soc-dapm.h> 29#include <sound/soc.h>
30#include <sound/jack.h> 30#include <sound/jack.h>
31 31
32#include <asm/mach-types.h> 32#include <asm/mach-types.h>
@@ -94,6 +94,7 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
94 struct snd_ctl_elem_value *ucontrol) 94 struct snd_ctl_elem_value *ucontrol)
95{ 95{
96 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 96 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
97 struct snd_soc_dapm_context *dapm = &codec->dapm;
97 struct soc_enum *control = (struct soc_enum *)kcontrol->private_value; 98 struct soc_enum *control = (struct soc_enum *)kcontrol->private_value;
98 unsigned short pins; 99 unsigned short pins;
99 int pin, changed = 0; 100 int pin, changed = 0;
@@ -112,48 +113,48 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol,
112 113
113 /* Setup pins after corresponding bits if changed */ 114 /* Setup pins after corresponding bits if changed */
114 pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE)); 115 pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE));
115 if (pin != snd_soc_dapm_get_pin_status(codec, "Mouthpiece")) { 116 if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) {
116 changed = 1; 117 changed = 1;
117 if (pin) 118 if (pin)
118 snd_soc_dapm_enable_pin(codec, "Mouthpiece"); 119 snd_soc_dapm_enable_pin(dapm, "Mouthpiece");
119 else 120 else
120 snd_soc_dapm_disable_pin(codec, "Mouthpiece"); 121 snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
121 } 122 }
122 pin = !!(pins & (1 << AMS_DELTA_EARPIECE)); 123 pin = !!(pins & (1 << AMS_DELTA_EARPIECE));
123 if (pin != snd_soc_dapm_get_pin_status(codec, "Earpiece")) { 124 if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) {
124 changed = 1; 125 changed = 1;
125 if (pin) 126 if (pin)
126 snd_soc_dapm_enable_pin(codec, "Earpiece"); 127 snd_soc_dapm_enable_pin(dapm, "Earpiece");
127 else 128 else
128 snd_soc_dapm_disable_pin(codec, "Earpiece"); 129 snd_soc_dapm_disable_pin(dapm, "Earpiece");
129 } 130 }
130 pin = !!(pins & (1 << AMS_DELTA_MICROPHONE)); 131 pin = !!(pins & (1 << AMS_DELTA_MICROPHONE));
131 if (pin != snd_soc_dapm_get_pin_status(codec, "Microphone")) { 132 if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) {
132 changed = 1; 133 changed = 1;
133 if (pin) 134 if (pin)
134 snd_soc_dapm_enable_pin(codec, "Microphone"); 135 snd_soc_dapm_enable_pin(dapm, "Microphone");
135 else 136 else
136 snd_soc_dapm_disable_pin(codec, "Microphone"); 137 snd_soc_dapm_disable_pin(dapm, "Microphone");
137 } 138 }
138 pin = !!(pins & (1 << AMS_DELTA_SPEAKER)); 139 pin = !!(pins & (1 << AMS_DELTA_SPEAKER));
139 if (pin != snd_soc_dapm_get_pin_status(codec, "Speaker")) { 140 if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) {
140 changed = 1; 141 changed = 1;
141 if (pin) 142 if (pin)
142 snd_soc_dapm_enable_pin(codec, "Speaker"); 143 snd_soc_dapm_enable_pin(dapm, "Speaker");
143 else 144 else
144 snd_soc_dapm_disable_pin(codec, "Speaker"); 145 snd_soc_dapm_disable_pin(dapm, "Speaker");
145 } 146 }
146 pin = !!(pins & (1 << AMS_DELTA_AGC)); 147 pin = !!(pins & (1 << AMS_DELTA_AGC));
147 if (pin != ams_delta_audio_agc) { 148 if (pin != ams_delta_audio_agc) {
148 ams_delta_audio_agc = pin; 149 ams_delta_audio_agc = pin;
149 changed = 1; 150 changed = 1;
150 if (pin) 151 if (pin)
151 snd_soc_dapm_enable_pin(codec, "AGCIN"); 152 snd_soc_dapm_enable_pin(dapm, "AGCIN");
152 else 153 else
153 snd_soc_dapm_disable_pin(codec, "AGCIN"); 154 snd_soc_dapm_disable_pin(dapm, "AGCIN");
154 } 155 }
155 if (changed) 156 if (changed)
156 snd_soc_dapm_sync(codec); 157 snd_soc_dapm_sync(dapm);
157 158
158 mutex_unlock(&codec->mutex); 159 mutex_unlock(&codec->mutex);
159 160
@@ -164,19 +165,20 @@ static int ams_delta_get_audio_mode(struct snd_kcontrol *kcontrol,
164 struct snd_ctl_elem_value *ucontrol) 165 struct snd_ctl_elem_value *ucontrol)
165{ 166{
166 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 167 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
168 struct snd_soc_dapm_context *dapm = &codec->dapm;
167 unsigned short pins, mode; 169 unsigned short pins, mode;
168 170
169 pins = ((snd_soc_dapm_get_pin_status(codec, "Mouthpiece") << 171 pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") <<
170 AMS_DELTA_MOUTHPIECE) | 172 AMS_DELTA_MOUTHPIECE) |
171 (snd_soc_dapm_get_pin_status(codec, "Earpiece") << 173 (snd_soc_dapm_get_pin_status(dapm, "Earpiece") <<
172 AMS_DELTA_EARPIECE)); 174 AMS_DELTA_EARPIECE));
173 if (pins) 175 if (pins)
174 pins |= (snd_soc_dapm_get_pin_status(codec, "Microphone") << 176 pins |= (snd_soc_dapm_get_pin_status(dapm, "Microphone") <<
175 AMS_DELTA_MICROPHONE); 177 AMS_DELTA_MICROPHONE);
176 else 178 else
177 pins = ((snd_soc_dapm_get_pin_status(codec, "Microphone") << 179 pins = ((snd_soc_dapm_get_pin_status(dapm, "Microphone") <<
178 AMS_DELTA_MICROPHONE) | 180 AMS_DELTA_MICROPHONE) |
179 (snd_soc_dapm_get_pin_status(codec, "Speaker") << 181 (snd_soc_dapm_get_pin_status(dapm, "Speaker") <<
180 AMS_DELTA_SPEAKER) | 182 AMS_DELTA_SPEAKER) |
181 (ams_delta_audio_agc << AMS_DELTA_AGC)); 183 (ams_delta_audio_agc << AMS_DELTA_AGC));
182 184
@@ -300,6 +302,7 @@ static int cx81801_open(struct tty_struct *tty)
300static void cx81801_close(struct tty_struct *tty) 302static void cx81801_close(struct tty_struct *tty)
301{ 303{
302 struct snd_soc_codec *codec = tty->disc_data; 304 struct snd_soc_codec *codec = tty->disc_data;
305 struct snd_soc_dapm_context *dapm = &codec->dapm;
303 306
304 del_timer_sync(&cx81801_timer); 307 del_timer_sync(&cx81801_timer);
305 308
@@ -312,12 +315,12 @@ static void cx81801_close(struct tty_struct *tty)
312 v253_ops.close(tty); 315 v253_ops.close(tty);
313 316
314 /* Revert back to default audio input/output constellation */ 317 /* Revert back to default audio input/output constellation */
315 snd_soc_dapm_disable_pin(codec, "Mouthpiece"); 318 snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
316 snd_soc_dapm_enable_pin(codec, "Earpiece"); 319 snd_soc_dapm_enable_pin(dapm, "Earpiece");
317 snd_soc_dapm_enable_pin(codec, "Microphone"); 320 snd_soc_dapm_enable_pin(dapm, "Microphone");
318 snd_soc_dapm_disable_pin(codec, "Speaker"); 321 snd_soc_dapm_disable_pin(dapm, "Speaker");
319 snd_soc_dapm_disable_pin(codec, "AGCIN"); 322 snd_soc_dapm_disable_pin(dapm, "AGCIN");
320 snd_soc_dapm_sync(codec); 323 snd_soc_dapm_sync(dapm);
321} 324}
322 325
323/* Line discipline .hangup() */ 326/* Line discipline .hangup() */
@@ -432,16 +435,16 @@ static int ams_delta_set_bias_level(struct snd_soc_card *card,
432 case SND_SOC_BIAS_ON: 435 case SND_SOC_BIAS_ON:
433 case SND_SOC_BIAS_PREPARE: 436 case SND_SOC_BIAS_PREPARE:
434 case SND_SOC_BIAS_STANDBY: 437 case SND_SOC_BIAS_STANDBY:
435 if (codec->bias_level == SND_SOC_BIAS_OFF) 438 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
436 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, 439 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
437 AMS_DELTA_LATCH2_MODEM_NRESET); 440 AMS_DELTA_LATCH2_MODEM_NRESET);
438 break; 441 break;
439 case SND_SOC_BIAS_OFF: 442 case SND_SOC_BIAS_OFF:
440 if (codec->bias_level != SND_SOC_BIAS_OFF) 443 if (codec->dapm.bias_level != SND_SOC_BIAS_OFF)
441 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, 444 ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET,
442 0); 445 0);
443 } 446 }
444 codec->bias_level = level; 447 codec->dapm.bias_level = level;
445 448
446 return 0; 449 return 0;
447} 450}
@@ -492,6 +495,7 @@ static void ams_delta_shutdown(struct snd_pcm_substream *substream)
492static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) 495static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
493{ 496{
494 struct snd_soc_codec *codec = rtd->codec; 497 struct snd_soc_codec *codec = rtd->codec;
498 struct snd_soc_dapm_context *dapm = &codec->dapm;
495 struct snd_soc_dai *codec_dai = rtd->codec_dai; 499 struct snd_soc_dai *codec_dai = rtd->codec_dai;
496 struct snd_soc_card *card = rtd->card; 500 struct snd_soc_card *card = rtd->card;
497 int ret; 501 int ret;
@@ -541,7 +545,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
541 } 545 }
542 546
543 /* Add board specific DAPM widgets and routes */ 547 /* Add board specific DAPM widgets and routes */
544 ret = snd_soc_dapm_new_controls(codec, ams_delta_dapm_widgets, 548 ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets,
545 ARRAY_SIZE(ams_delta_dapm_widgets)); 549 ARRAY_SIZE(ams_delta_dapm_widgets));
546 if (ret) { 550 if (ret) {
547 dev_warn(card->dev, 551 dev_warn(card->dev,
@@ -550,7 +554,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
550 return 0; 554 return 0;
551 } 555 }
552 556
553 ret = snd_soc_dapm_add_routes(codec, ams_delta_audio_map, 557 ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map,
554 ARRAY_SIZE(ams_delta_audio_map)); 558 ARRAY_SIZE(ams_delta_audio_map));
555 if (ret) { 559 if (ret) {
556 dev_warn(card->dev, 560 dev_warn(card->dev,
@@ -560,13 +564,13 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd)
560 } 564 }
561 565
562 /* Set up initial pin constellation */ 566 /* Set up initial pin constellation */
563 snd_soc_dapm_disable_pin(codec, "Mouthpiece"); 567 snd_soc_dapm_disable_pin(dapm, "Mouthpiece");
564 snd_soc_dapm_enable_pin(codec, "Earpiece"); 568 snd_soc_dapm_enable_pin(dapm, "Earpiece");
565 snd_soc_dapm_enable_pin(codec, "Microphone"); 569 snd_soc_dapm_enable_pin(dapm, "Microphone");
566 snd_soc_dapm_disable_pin(codec, "Speaker"); 570 snd_soc_dapm_disable_pin(dapm, "Speaker");
567 snd_soc_dapm_disable_pin(codec, "AGCIN"); 571 snd_soc_dapm_disable_pin(dapm, "AGCIN");
568 snd_soc_dapm_disable_pin(codec, "AGCOUT"); 572 snd_soc_dapm_disable_pin(dapm, "AGCOUT");
569 snd_soc_dapm_sync(codec); 573 snd_soc_dapm_sync(dapm);
570 574
571 /* Add virtual switch */ 575 /* Add virtual switch */
572 ret = snd_soc_add_controls(codec, ams_delta_audio_controls, 576 ret = snd_soc_add_controls(codec, ams_delta_audio_controls,
diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c
index fd3a40f309c8..0ae34702995b 100644
--- a/sound/soc/omap/igep0020.c
+++ b/sound/soc/omap/igep0020.c
@@ -24,7 +24,6 @@
24#include <sound/core.h> 24#include <sound/core.h>
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28 27
29#include <asm/mach-types.h> 28#include <asm/mach-types.h>
30#include <mach/hardware.h> 29#include <mach/hardware.h>
diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c
index a3b6d897ad84..83d213bfd3d1 100644
--- a/sound/soc/omap/n810.c
+++ b/sound/soc/omap/n810.c
@@ -27,7 +27,6 @@
27#include <sound/core.h> 27#include <sound/core.h>
28#include <sound/pcm.h> 28#include <sound/pcm.h>
29#include <sound/soc.h> 29#include <sound/soc.h>
30#include <sound/soc-dapm.h>
31 30
32#include <asm/mach-types.h> 31#include <asm/mach-types.h>
33#include <mach/hardware.h> 32#include <mach/hardware.h>
@@ -36,7 +35,6 @@
36 35
37#include "omap-mcbsp.h" 36#include "omap-mcbsp.h"
38#include "omap-pcm.h" 37#include "omap-pcm.h"
39#include "../codecs/tlv320aic3x.h"
40 38
41#define N810_HEADSET_AMP_GPIO 10 39#define N810_HEADSET_AMP_GPIO 10
42#define N810_SPEAKER_AMP_GPIO 101 40#define N810_SPEAKER_AMP_GPIO 101
@@ -58,6 +56,7 @@ static int n810_dmic_func;
58 56
59static void n810_ext_control(struct snd_soc_codec *codec) 57static void n810_ext_control(struct snd_soc_codec *codec)
60{ 58{
59 struct snd_soc_dapm_context *dapm = &codec->dapm;
61 int hp = 0, line1l = 0; 60 int hp = 0, line1l = 0;
62 61
63 switch (n810_jack_func) { 62 switch (n810_jack_func) {
@@ -72,25 +71,25 @@ static void n810_ext_control(struct snd_soc_codec *codec)
72 } 71 }
73 72
74 if (n810_spk_func) 73 if (n810_spk_func)
75 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 74 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
76 else 75 else
77 snd_soc_dapm_disable_pin(codec, "Ext Spk"); 76 snd_soc_dapm_disable_pin(dapm, "Ext Spk");
78 77
79 if (hp) 78 if (hp)
80 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 79 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
81 else 80 else
82 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 81 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
83 if (line1l) 82 if (line1l)
84 snd_soc_dapm_enable_pin(codec, "LINE1L"); 83 snd_soc_dapm_enable_pin(dapm, "LINE1L");
85 else 84 else
86 snd_soc_dapm_disable_pin(codec, "LINE1L"); 85 snd_soc_dapm_disable_pin(dapm, "LINE1L");
87 86
88 if (n810_dmic_func) 87 if (n810_dmic_func)
89 snd_soc_dapm_enable_pin(codec, "DMic"); 88 snd_soc_dapm_enable_pin(dapm, "DMic");
90 else 89 else
91 snd_soc_dapm_disable_pin(codec, "DMic"); 90 snd_soc_dapm_disable_pin(dapm, "DMic");
92 91
93 snd_soc_dapm_sync(codec); 92 snd_soc_dapm_sync(dapm);
94} 93}
95 94
96static int n810_startup(struct snd_pcm_substream *substream) 95static int n810_startup(struct snd_pcm_substream *substream)
@@ -274,17 +273,18 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = {
274static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd) 273static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
275{ 274{
276 struct snd_soc_codec *codec = rtd->codec; 275 struct snd_soc_codec *codec = rtd->codec;
276 struct snd_soc_dapm_context *dapm = &codec->dapm;
277 int err; 277 int err;
278 278
279 /* Not connected */ 279 /* Not connected */
280 snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); 280 snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
281 snd_soc_dapm_nc_pin(codec, "HPLCOM"); 281 snd_soc_dapm_nc_pin(dapm, "HPLCOM");
282 snd_soc_dapm_nc_pin(codec, "HPRCOM"); 282 snd_soc_dapm_nc_pin(dapm, "HPRCOM");
283 snd_soc_dapm_nc_pin(codec, "MIC3L"); 283 snd_soc_dapm_nc_pin(dapm, "MIC3L");
284 snd_soc_dapm_nc_pin(codec, "MIC3R"); 284 snd_soc_dapm_nc_pin(dapm, "MIC3R");
285 snd_soc_dapm_nc_pin(codec, "LINE1R"); 285 snd_soc_dapm_nc_pin(dapm, "LINE1R");
286 snd_soc_dapm_nc_pin(codec, "LINE2L"); 286 snd_soc_dapm_nc_pin(dapm, "LINE2L");
287 snd_soc_dapm_nc_pin(codec, "LINE2R"); 287 snd_soc_dapm_nc_pin(dapm, "LINE2R");
288 288
289 /* Add N810 specific controls */ 289 /* Add N810 specific controls */
290 err = snd_soc_add_controls(codec, aic33_n810_controls, 290 err = snd_soc_add_controls(codec, aic33_n810_controls,
@@ -293,13 +293,13 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd)
293 return err; 293 return err;
294 294
295 /* Add N810 specific widgets */ 295 /* Add N810 specific widgets */
296 snd_soc_dapm_new_controls(codec, aic33_dapm_widgets, 296 snd_soc_dapm_new_controls(dapm, aic33_dapm_widgets,
297 ARRAY_SIZE(aic33_dapm_widgets)); 297 ARRAY_SIZE(aic33_dapm_widgets));
298 298
299 /* Set up N810 specific audio path audio_map */ 299 /* Set up N810 specific audio path audio_map */
300 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 300 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
301 301
302 snd_soc_dapm_sync(codec); 302 snd_soc_dapm_sync(dapm);
303 303
304 return 0; 304 return 0;
305} 305}
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 7e84f24b9a88..d203f4da18a0 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -102,6 +102,17 @@ static const int omap24xx_dma_reqs[][2] = {
102static const int omap24xx_dma_reqs[][2] = {}; 102static const int omap24xx_dma_reqs[][2] = {};
103#endif 103#endif
104 104
105#if defined(CONFIG_ARCH_OMAP4)
106static const int omap44xx_dma_reqs[][2] = {
107 { OMAP44XX_DMA_MCBSP1_TX, OMAP44XX_DMA_MCBSP1_RX },
108 { OMAP44XX_DMA_MCBSP2_TX, OMAP44XX_DMA_MCBSP2_RX },
109 { OMAP44XX_DMA_MCBSP3_TX, OMAP44XX_DMA_MCBSP3_RX },
110 { OMAP44XX_DMA_MCBSP4_TX, OMAP44XX_DMA_MCBSP4_RX },
111};
112#else
113static const int omap44xx_dma_reqs[][2] = {};
114#endif
115
105#if defined(CONFIG_ARCH_OMAP2420) 116#if defined(CONFIG_ARCH_OMAP2420)
106static const unsigned long omap2420_mcbsp_port[][2] = { 117static const unsigned long omap2420_mcbsp_port[][2] = {
107 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, 118 { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1,
@@ -147,6 +158,21 @@ static const unsigned long omap34xx_mcbsp_port[][2] = {
147static const unsigned long omap34xx_mcbsp_port[][2] = {}; 158static const unsigned long omap34xx_mcbsp_port[][2] = {};
148#endif 159#endif
149 160
161#if defined(CONFIG_ARCH_OMAP4)
162static const unsigned long omap44xx_mcbsp_port[][2] = {
163 { OMAP44XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR,
164 OMAP44XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR },
165 { OMAP44XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR,
166 OMAP44XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR },
167 { OMAP44XX_MCBSP3_BASE + OMAP_MCBSP_REG_DXR,
168 OMAP44XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR },
169 { OMAP44XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR,
170 OMAP44XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR },
171};
172#else
173static const unsigned long omap44xx_mcbsp_port[][2] = {};
174#endif
175
150static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) 176static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream)
151{ 177{
152 struct snd_soc_pcm_runtime *rtd = substream->private_data; 178 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -224,7 +250,7 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream,
224 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) 250 * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words)
225 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) 251 * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words)
226 */ 252 */
227 if (cpu_is_omap343x()) { 253 if (cpu_is_omap343x() || cpu_is_omap44xx()) {
228 /* 254 /*
229 * Rule for the buffer size. We should not allow 255 * Rule for the buffer size. We should not allow
230 * smaller buffer than the FIFO size to avoid underruns 256 * smaller buffer than the FIFO size to avoid underruns
@@ -332,6 +358,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
332 } else if (cpu_is_omap343x()) { 358 } else if (cpu_is_omap343x()) {
333 dma = omap24xx_dma_reqs[bus_id][substream->stream]; 359 dma = omap24xx_dma_reqs[bus_id][substream->stream];
334 port = omap34xx_mcbsp_port[bus_id][substream->stream]; 360 port = omap34xx_mcbsp_port[bus_id][substream->stream];
361 } else if (cpu_is_omap44xx()) {
362 dma = omap44xx_dma_reqs[bus_id][substream->stream];
363 port = omap44xx_mcbsp_port[bus_id][substream->stream];
335 } else { 364 } else {
336 return -ENODEV; 365 return -ENODEV;
337 } 366 }
@@ -498,11 +527,11 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai,
498 regs->spcr2 |= XINTM(3) | FREE; 527 regs->spcr2 |= XINTM(3) | FREE;
499 regs->spcr1 |= RINTM(3); 528 regs->spcr1 |= RINTM(3);
500 /* RFIG and XFIG are not defined in 34xx */ 529 /* RFIG and XFIG are not defined in 34xx */
501 if (!cpu_is_omap34xx()) { 530 if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) {
502 regs->rcr2 |= RFIG; 531 regs->rcr2 |= RFIG;
503 regs->xcr2 |= XFIG; 532 regs->xcr2 |= XFIG;
504 } 533 }
505 if (cpu_is_omap2430() || cpu_is_omap34xx()) { 534 if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) {
506 regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; 535 regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE;
507 regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; 536 regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE;
508 } 537 }
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index ffdcc5abb7b9..110c106611d3 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -50,6 +50,10 @@ enum omap_mcbsp_div {
50#undef NUM_LINKS 50#undef NUM_LINKS
51#define NUM_LINKS 3 51#define NUM_LINKS 3
52#endif 52#endif
53#if defined(CONFIG_ARCH_OMAP4)
54#undef NUM_LINKS
55#define NUM_LINKS 4
56#endif
53#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) 57#if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3)
54#undef NUM_LINKS 58#undef NUM_LINKS
55#define NUM_LINKS 5 59#define NUM_LINKS 5
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c
index cf3fc8a675b5..29b60d6796e7 100644
--- a/sound/soc/omap/omap2evm.c
+++ b/sound/soc/omap/omap2evm.c
@@ -26,7 +26,6 @@
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/pcm.h> 27#include <sound/pcm.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30 29
31#include <asm/mach-types.h> 30#include <asm/mach-types.h>
32#include <mach/hardware.h> 31#include <mach/hardware.h>
diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c
index e56832b0c444..40db813c0795 100644
--- a/sound/soc/omap/omap3beagle.c
+++ b/sound/soc/omap/omap3beagle.c
@@ -24,7 +24,6 @@
24#include <sound/core.h> 24#include <sound/core.h>
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28 27
29#include <asm/mach-types.h> 28#include <asm/mach-types.h>
30#include <mach/hardware.h> 29#include <mach/hardware.h>
diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c
index 810f1e36da21..0daa04469836 100644
--- a/sound/soc/omap/omap3evm.c
+++ b/sound/soc/omap/omap3evm.c
@@ -22,7 +22,6 @@
22#include <sound/core.h> 22#include <sound/core.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26 25
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
28#include <mach/hardware.h> 27#include <mach/hardware.h>
diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c
index 4ee33ce2cb98..8047c521e318 100644
--- a/sound/soc/omap/omap3pandora.c
+++ b/sound/soc/omap/omap3pandora.c
@@ -28,7 +28,6 @@
28#include <sound/core.h> 28#include <sound/core.h>
29#include <sound/pcm.h> 29#include <sound/pcm.h>
30#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32 31
33#include <asm/mach-types.h> 32#include <asm/mach-types.h>
34#include <plat/mcbsp.h> 33#include <plat/mcbsp.h>
@@ -170,51 +169,53 @@ static const struct snd_soc_dapm_route omap3pandora_in_map[] = {
170static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd) 169static int omap3pandora_out_init(struct snd_soc_pcm_runtime *rtd)
171{ 170{
172 struct snd_soc_codec *codec = rtd->codec; 171 struct snd_soc_codec *codec = rtd->codec;
172 struct snd_soc_dapm_context *dapm = &codec->dapm;
173 int ret; 173 int ret;
174 174
175 /* All TWL4030 output pins are floating */ 175 /* All TWL4030 output pins are floating */
176 snd_soc_dapm_nc_pin(codec, "EARPIECE"); 176 snd_soc_dapm_nc_pin(dapm, "EARPIECE");
177 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); 177 snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
178 snd_soc_dapm_nc_pin(codec, "PREDRIVER"); 178 snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
179 snd_soc_dapm_nc_pin(codec, "HSOL"); 179 snd_soc_dapm_nc_pin(dapm, "HSOL");
180 snd_soc_dapm_nc_pin(codec, "HSOR"); 180 snd_soc_dapm_nc_pin(dapm, "HSOR");
181 snd_soc_dapm_nc_pin(codec, "CARKITL"); 181 snd_soc_dapm_nc_pin(dapm, "CARKITL");
182 snd_soc_dapm_nc_pin(codec, "CARKITR"); 182 snd_soc_dapm_nc_pin(dapm, "CARKITR");
183 snd_soc_dapm_nc_pin(codec, "HFL"); 183 snd_soc_dapm_nc_pin(dapm, "HFL");
184 snd_soc_dapm_nc_pin(codec, "HFR"); 184 snd_soc_dapm_nc_pin(dapm, "HFR");
185 snd_soc_dapm_nc_pin(codec, "VIBRA"); 185 snd_soc_dapm_nc_pin(dapm, "VIBRA");
186 186
187 ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets, 187 ret = snd_soc_dapm_new_controls(dapm, omap3pandora_out_dapm_widgets,
188 ARRAY_SIZE(omap3pandora_out_dapm_widgets)); 188 ARRAY_SIZE(omap3pandora_out_dapm_widgets));
189 if (ret < 0) 189 if (ret < 0)
190 return ret; 190 return ret;
191 191
192 snd_soc_dapm_add_routes(codec, omap3pandora_out_map, 192 snd_soc_dapm_add_routes(dapm, omap3pandora_out_map,
193 ARRAY_SIZE(omap3pandora_out_map)); 193 ARRAY_SIZE(omap3pandora_out_map));
194 194
195 return snd_soc_dapm_sync(codec); 195 return snd_soc_dapm_sync(dapm);
196} 196}
197 197
198static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd) 198static int omap3pandora_in_init(struct snd_soc_pcm_runtime *rtd)
199{ 199{
200 struct snd_soc_codec *codec = rtd->codec; 200 struct snd_soc_codec *codec = rtd->codec;
201 struct snd_soc_dapm_context *dapm = &codec->dapm;
201 int ret; 202 int ret;
202 203
203 /* Not comnnected */ 204 /* Not comnnected */
204 snd_soc_dapm_nc_pin(codec, "HSMIC"); 205 snd_soc_dapm_nc_pin(dapm, "HSMIC");
205 snd_soc_dapm_nc_pin(codec, "CARKITMIC"); 206 snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
206 snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); 207 snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
207 snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); 208 snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
208 209
209 ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets, 210 ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets,
210 ARRAY_SIZE(omap3pandora_in_dapm_widgets)); 211 ARRAY_SIZE(omap3pandora_in_dapm_widgets));
211 if (ret < 0) 212 if (ret < 0)
212 return ret; 213 return ret;
213 214
214 snd_soc_dapm_add_routes(codec, omap3pandora_in_map, 215 snd_soc_dapm_add_routes(dapm, omap3pandora_in_map,
215 ARRAY_SIZE(omap3pandora_in_map)); 216 ARRAY_SIZE(omap3pandora_in_map));
216 217
217 return snd_soc_dapm_sync(codec); 218 return snd_soc_dapm_sync(dapm);
218} 219}
219 220
220static struct snd_soc_ops omap3pandora_ops = { 221static struct snd_soc_ops omap3pandora_ops = {
diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c
index 65ae00e976ef..7e75e775fb4a 100644
--- a/sound/soc/omap/osk5912.c
+++ b/sound/soc/omap/osk5912.c
@@ -26,7 +26,6 @@
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/pcm.h> 27#include <sound/pcm.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30 29
31#include <asm/mach-types.h> 30#include <asm/mach-types.h>
32#include <mach/hardware.h> 31#include <mach/hardware.h>
@@ -116,19 +115,20 @@ static const struct snd_soc_dapm_route audio_map[] = {
116static int osk_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) 115static int osk_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
117{ 116{
118 struct snd_soc_codec *codec = rtd->codec; 117 struct snd_soc_codec *codec = rtd->codec;
118 struct snd_soc_dapm_context *dapm = &codec->dapm;
119 119
120 /* Add osk5912 specific widgets */ 120 /* Add osk5912 specific widgets */
121 snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, 121 snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets,
122 ARRAY_SIZE(tlv320aic23_dapm_widgets)); 122 ARRAY_SIZE(tlv320aic23_dapm_widgets));
123 123
124 /* Set up osk5912 specific audio path audio_map */ 124 /* Set up osk5912 specific audio path audio_map */
125 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 125 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
126 126
127 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 127 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
128 snd_soc_dapm_enable_pin(codec, "Line In"); 128 snd_soc_dapm_enable_pin(dapm, "Line In");
129 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 129 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
130 130
131 snd_soc_dapm_sync(codec); 131 snd_soc_dapm_sync(dapm);
132 132
133 return 0; 133 return 0;
134} 134}
diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c
index e95a607937de..bbcf380bfb56 100644
--- a/sound/soc/omap/overo.c
+++ b/sound/soc/omap/overo.c
@@ -24,7 +24,6 @@
24#include <sound/core.h> 24#include <sound/core.h>
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28 27
29#include <asm/mach-types.h> 28#include <asm/mach-types.h>
30#include <mach/hardware.h> 29#include <mach/hardware.h>
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 04b5723bf89b..09fb0df8d416 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -30,14 +30,12 @@
30#include <sound/jack.h> 30#include <sound/jack.h>
31#include <sound/pcm.h> 31#include <sound/pcm.h>
32#include <sound/soc.h> 32#include <sound/soc.h>
33#include <sound/soc-dapm.h>
34#include <plat/mcbsp.h> 33#include <plat/mcbsp.h>
35 34
36#include <asm/mach-types.h> 35#include <asm/mach-types.h>
37 36
38#include "omap-mcbsp.h" 37#include "omap-mcbsp.h"
39#include "omap-pcm.h" 38#include "omap-pcm.h"
40#include "../codecs/tlv320aic3x.h"
41 39
42#define RX51_TVOUT_SEL_GPIO 40 40#define RX51_TVOUT_SEL_GPIO 40
43#define RX51_JACK_DETECT_GPIO 177 41#define RX51_JACK_DETECT_GPIO 177
@@ -58,19 +56,21 @@ static int rx51_jack_func;
58 56
59static void rx51_ext_control(struct snd_soc_codec *codec) 57static void rx51_ext_control(struct snd_soc_codec *codec)
60{ 58{
59 struct snd_soc_dapm_context *dapm = &codec->dapm;
60
61 if (rx51_spk_func) 61 if (rx51_spk_func)
62 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 62 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
63 else 63 else
64 snd_soc_dapm_disable_pin(codec, "Ext Spk"); 64 snd_soc_dapm_disable_pin(dapm, "Ext Spk");
65 if (rx51_dmic_func) 65 if (rx51_dmic_func)
66 snd_soc_dapm_enable_pin(codec, "DMic"); 66 snd_soc_dapm_enable_pin(dapm, "DMic");
67 else 67 else
68 snd_soc_dapm_disable_pin(codec, "DMic"); 68 snd_soc_dapm_disable_pin(dapm, "DMic");
69 69
70 gpio_set_value(RX51_TVOUT_SEL_GPIO, 70 gpio_set_value(RX51_TVOUT_SEL_GPIO,
71 rx51_jack_func == RX51_JACK_TVOUT); 71 rx51_jack_func == RX51_JACK_TVOUT);
72 72
73 snd_soc_dapm_sync(codec); 73 snd_soc_dapm_sync(dapm);
74} 74}
75 75
76static int rx51_startup(struct snd_pcm_substream *substream) 76static int rx51_startup(struct snd_pcm_substream *substream)
@@ -244,12 +244,13 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
244static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) 244static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
245{ 245{
246 struct snd_soc_codec *codec = rtd->codec; 246 struct snd_soc_codec *codec = rtd->codec;
247 struct snd_soc_dapm_context *dapm = &codec->dapm;
247 int err; 248 int err;
248 249
249 /* Set up NC codec pins */ 250 /* Set up NC codec pins */
250 snd_soc_dapm_nc_pin(codec, "MIC3L"); 251 snd_soc_dapm_nc_pin(dapm, "MIC3L");
251 snd_soc_dapm_nc_pin(codec, "MIC3R"); 252 snd_soc_dapm_nc_pin(dapm, "MIC3R");
252 snd_soc_dapm_nc_pin(codec, "LINE1R"); 253 snd_soc_dapm_nc_pin(dapm, "LINE1R");
253 254
254 /* Add RX-51 specific controls */ 255 /* Add RX-51 specific controls */
255 err = snd_soc_add_controls(codec, aic34_rx51_controls, 256 err = snd_soc_add_controls(codec, aic34_rx51_controls,
@@ -258,13 +259,13 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
258 return err; 259 return err;
259 260
260 /* Add RX-51 specific widgets */ 261 /* Add RX-51 specific widgets */
261 snd_soc_dapm_new_controls(codec, aic34_dapm_widgets, 262 snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets,
262 ARRAY_SIZE(aic34_dapm_widgets)); 263 ARRAY_SIZE(aic34_dapm_widgets));
263 264
264 /* Set up RX-51 specific audio path audio_map */ 265 /* Set up RX-51 specific audio path audio_map */
265 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 266 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
266 267
267 snd_soc_dapm_sync(codec); 268 snd_soc_dapm_sync(dapm);
268 269
269 /* AV jack detection */ 270 /* AV jack detection */
270 err = snd_soc_jack_new(codec, "AV Jack", 271 err = snd_soc_jack_new(codec, "AV Jack",
diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c
index 07fbcf7d2411..3f72d17d1ef0 100644
--- a/sound/soc/omap/sdp3430.c
+++ b/sound/soc/omap/sdp3430.c
@@ -28,7 +28,6 @@
28#include <sound/core.h> 28#include <sound/core.h>
29#include <sound/pcm.h> 29#include <sound/pcm.h>
30#include <sound/soc.h> 30#include <sound/soc.h>
31#include <sound/soc-dapm.h>
32#include <sound/jack.h> 31#include <sound/jack.h>
33 32
34#include <asm/mach-types.h> 33#include <asm/mach-types.h>
@@ -191,39 +190,40 @@ static const struct snd_soc_dapm_route audio_map[] = {
191static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd) 190static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd)
192{ 191{
193 struct snd_soc_codec *codec = rtd->codec; 192 struct snd_soc_codec *codec = rtd->codec;
193 struct snd_soc_dapm_context *dapm = &codec->dapm;
194 int ret; 194 int ret;
195 195
196 /* Add SDP3430 specific widgets */ 196 /* Add SDP3430 specific widgets */
197 ret = snd_soc_dapm_new_controls(codec, sdp3430_twl4030_dapm_widgets, 197 ret = snd_soc_dapm_new_controls(dapm, sdp3430_twl4030_dapm_widgets,
198 ARRAY_SIZE(sdp3430_twl4030_dapm_widgets)); 198 ARRAY_SIZE(sdp3430_twl4030_dapm_widgets));
199 if (ret) 199 if (ret)
200 return ret; 200 return ret;
201 201
202 /* Set up SDP3430 specific audio path audio_map */ 202 /* Set up SDP3430 specific audio path audio_map */
203 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 203 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
204 204
205 /* SDP3430 connected pins */ 205 /* SDP3430 connected pins */
206 snd_soc_dapm_enable_pin(codec, "Ext Mic"); 206 snd_soc_dapm_enable_pin(dapm, "Ext Mic");
207 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 207 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
208 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 208 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
209 snd_soc_dapm_disable_pin(codec, "Headset Stereophone"); 209 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
210 210
211 /* TWL4030 not connected pins */ 211 /* TWL4030 not connected pins */
212 snd_soc_dapm_nc_pin(codec, "AUXL"); 212 snd_soc_dapm_nc_pin(dapm, "AUXL");
213 snd_soc_dapm_nc_pin(codec, "AUXR"); 213 snd_soc_dapm_nc_pin(dapm, "AUXR");
214 snd_soc_dapm_nc_pin(codec, "CARKITMIC"); 214 snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
215 snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); 215 snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
216 snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); 216 snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
217 217
218 snd_soc_dapm_nc_pin(codec, "OUTL"); 218 snd_soc_dapm_nc_pin(dapm, "OUTL");
219 snd_soc_dapm_nc_pin(codec, "OUTR"); 219 snd_soc_dapm_nc_pin(dapm, "OUTR");
220 snd_soc_dapm_nc_pin(codec, "EARPIECE"); 220 snd_soc_dapm_nc_pin(dapm, "EARPIECE");
221 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); 221 snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
222 snd_soc_dapm_nc_pin(codec, "PREDRIVER"); 222 snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
223 snd_soc_dapm_nc_pin(codec, "CARKITL"); 223 snd_soc_dapm_nc_pin(dapm, "CARKITL");
224 snd_soc_dapm_nc_pin(codec, "CARKITR"); 224 snd_soc_dapm_nc_pin(dapm, "CARKITR");
225 225
226 ret = snd_soc_dapm_sync(codec); 226 ret = snd_soc_dapm_sync(dapm);
227 if (ret) 227 if (ret)
228 return ret; 228 return ret;
229 229
diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c
index 4b4463db6ba0..189e03900637 100644
--- a/sound/soc/omap/sdp4430.c
+++ b/sound/soc/omap/sdp4430.c
@@ -24,7 +24,7 @@
24#include <sound/core.h> 24#include <sound/core.h>
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h> 27#include <sound/jack.h>
28 28
29#include <asm/mach-types.h> 29#include <asm/mach-types.h>
30#include <plat/hardware.h> 30#include <plat/hardware.h>
@@ -66,6 +66,21 @@ static struct snd_soc_ops sdp4430_ops = {
66 .hw_params = sdp4430_hw_params, 66 .hw_params = sdp4430_hw_params,
67}; 67};
68 68
69/* Headset jack */
70static struct snd_soc_jack hs_jack;
71
72/*Headset jack detection DAPM pins */
73static struct snd_soc_jack_pin hs_jack_pins[] = {
74 {
75 .pin = "Headset Mic",
76 .mask = SND_JACK_MICROPHONE,
77 },
78 {
79 .pin = "Headset Stereophone",
80 .mask = SND_JACK_HEADPHONE,
81 },
82};
83
69static int sdp4430_get_power_mode(struct snd_kcontrol *kcontrol, 84static int sdp4430_get_power_mode(struct snd_kcontrol *kcontrol,
70 struct snd_ctl_elem_value *ucontrol) 85 struct snd_ctl_elem_value *ucontrol)
71{ 86{
@@ -102,6 +117,7 @@ static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = {
102 SND_SOC_DAPM_MIC("Headset Mic", NULL), 117 SND_SOC_DAPM_MIC("Headset Mic", NULL),
103 SND_SOC_DAPM_HP("Headset Stereophone", NULL), 118 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
104 SND_SOC_DAPM_SPK("Earphone Spk", NULL), 119 SND_SOC_DAPM_SPK("Earphone Spk", NULL),
120 SND_SOC_DAPM_INPUT("Aux/FM Stereo In"),
105}; 121};
106 122
107static const struct snd_soc_dapm_route audio_map[] = { 123static const struct snd_soc_dapm_route audio_map[] = {
@@ -124,11 +140,16 @@ static const struct snd_soc_dapm_route audio_map[] = {
124 140
125 /* Earphone speaker */ 141 /* Earphone speaker */
126 {"Earphone Spk", NULL, "EP"}, 142 {"Earphone Spk", NULL, "EP"},
143
144 /* Aux/FM Stereo In: AFML, AFMR */
145 {"AFML", NULL, "Aux/FM Stereo In"},
146 {"AFMR", NULL, "Aux/FM Stereo In"},
127}; 147};
128 148
129static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) 149static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
130{ 150{
131 struct snd_soc_codec *codec = rtd->codec; 151 struct snd_soc_codec *codec = rtd->codec;
152 struct snd_soc_dapm_context *dapm = &codec->dapm;
132 int ret; 153 int ret;
133 154
134 /* Add SDP4430 specific controls */ 155 /* Add SDP4430 specific controls */
@@ -138,25 +159,39 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd)
138 return ret; 159 return ret;
139 160
140 /* Add SDP4430 specific widgets */ 161 /* Add SDP4430 specific widgets */
141 ret = snd_soc_dapm_new_controls(codec, sdp4430_twl6040_dapm_widgets, 162 ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets,
142 ARRAY_SIZE(sdp4430_twl6040_dapm_widgets)); 163 ARRAY_SIZE(sdp4430_twl6040_dapm_widgets));
143 if (ret) 164 if (ret)
144 return ret; 165 return ret;
145 166
146 /* Set up SDP4430 specific audio path audio_map */ 167 /* Set up SDP4430 specific audio path audio_map */
147 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 168 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
148 169
149 /* SDP4430 connected pins */ 170 /* SDP4430 connected pins */
150 snd_soc_dapm_enable_pin(codec, "Ext Mic"); 171 snd_soc_dapm_enable_pin(dapm, "Ext Mic");
151 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 172 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
152 snd_soc_dapm_enable_pin(codec, "Headset Mic"); 173 snd_soc_dapm_enable_pin(dapm, "AFML");
153 snd_soc_dapm_enable_pin(codec, "Headset Stereophone"); 174 snd_soc_dapm_enable_pin(dapm, "AFMR");
175 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
176 snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
177
178 ret = snd_soc_dapm_sync(dapm);
179 if (ret)
180 return ret;
181
182 /* Headset jack detection */
183 ret = snd_soc_jack_new(codec, "Headset Jack",
184 SND_JACK_HEADSET, &hs_jack);
185 if (ret)
186 return ret;
154 187
155 /* TWL6040 not connected pins */ 188 ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
156 snd_soc_dapm_nc_pin(codec, "AFML"); 189 hs_jack_pins);
157 snd_soc_dapm_nc_pin(codec, "AFMR");
158 190
159 ret = snd_soc_dapm_sync(codec); 191 if (machine_is_omap_4430sdp())
192 twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET);
193 else
194 snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET);
160 195
161 return ret; 196 return ret;
162} 197}
diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c
index 718031eeac34..01709940a43c 100644
--- a/sound/soc/omap/zoom2.c
+++ b/sound/soc/omap/zoom2.c
@@ -24,7 +24,6 @@
24#include <sound/core.h> 24#include <sound/core.h>
25#include <sound/pcm.h> 25#include <sound/pcm.h>
26#include <sound/soc.h> 26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28 27
29#include <asm/mach-types.h> 28#include <asm/mach-types.h>
30#include <mach/hardware.h> 29#include <mach/hardware.h>
@@ -162,35 +161,36 @@ static const struct snd_soc_dapm_route audio_map[] = {
162static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd) 161static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd)
163{ 162{
164 struct snd_soc_codec *codec = rtd->codec; 163 struct snd_soc_codec *codec = rtd->codec;
164 struct snd_soc_dapm_context *dapm = &codec->dapm;
165 int ret; 165 int ret;
166 166
167 /* Add Zoom2 specific widgets */ 167 /* Add Zoom2 specific widgets */
168 ret = snd_soc_dapm_new_controls(codec, zoom2_twl4030_dapm_widgets, 168 ret = snd_soc_dapm_new_controls(dapm, zoom2_twl4030_dapm_widgets,
169 ARRAY_SIZE(zoom2_twl4030_dapm_widgets)); 169 ARRAY_SIZE(zoom2_twl4030_dapm_widgets));
170 if (ret) 170 if (ret)
171 return ret; 171 return ret;
172 172
173 /* Set up Zoom2 specific audio path audio_map */ 173 /* Set up Zoom2 specific audio path audio_map */
174 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 174 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
175 175
176 /* Zoom2 connected pins */ 176 /* Zoom2 connected pins */
177 snd_soc_dapm_enable_pin(codec, "Ext Mic"); 177 snd_soc_dapm_enable_pin(dapm, "Ext Mic");
178 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 178 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
179 snd_soc_dapm_enable_pin(codec, "Headset Mic"); 179 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
180 snd_soc_dapm_enable_pin(codec, "Headset Stereophone"); 180 snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
181 snd_soc_dapm_enable_pin(codec, "Aux In"); 181 snd_soc_dapm_enable_pin(dapm, "Aux In");
182 182
183 /* TWL4030 not connected pins */ 183 /* TWL4030 not connected pins */
184 snd_soc_dapm_nc_pin(codec, "CARKITMIC"); 184 snd_soc_dapm_nc_pin(dapm, "CARKITMIC");
185 snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); 185 snd_soc_dapm_nc_pin(dapm, "DIGIMIC0");
186 snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); 186 snd_soc_dapm_nc_pin(dapm, "DIGIMIC1");
187 snd_soc_dapm_nc_pin(codec, "EARPIECE"); 187 snd_soc_dapm_nc_pin(dapm, "EARPIECE");
188 snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); 188 snd_soc_dapm_nc_pin(dapm, "PREDRIVEL");
189 snd_soc_dapm_nc_pin(codec, "PREDRIVER"); 189 snd_soc_dapm_nc_pin(dapm, "PREDRIVER");
190 snd_soc_dapm_nc_pin(codec, "CARKITL"); 190 snd_soc_dapm_nc_pin(dapm, "CARKITL");
191 snd_soc_dapm_nc_pin(codec, "CARKITR"); 191 snd_soc_dapm_nc_pin(dapm, "CARKITR");
192 192
193 ret = snd_soc_dapm_sync(codec); 193 ret = snd_soc_dapm_sync(dapm);
194 194
195 return ret; 195 return ret;
196} 196}
diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c
index f451acd4935b..fc592f0d5fc7 100644
--- a/sound/soc/pxa/corgi.c
+++ b/sound/soc/pxa/corgi.c
@@ -23,7 +23,6 @@
23#include <sound/core.h> 23#include <sound/core.h>
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27 26
28#include <asm/mach-types.h> 27#include <asm/mach-types.h>
29#include <mach/corgi.h> 28#include <mach/corgi.h>
@@ -48,51 +47,53 @@ static int corgi_spk_func;
48 47
49static void corgi_ext_control(struct snd_soc_codec *codec) 48static void corgi_ext_control(struct snd_soc_codec *codec)
50{ 49{
50 struct snd_soc_dapm_context *dapm = &codec->dapm;
51
51 /* set up jack connection */ 52 /* set up jack connection */
52 switch (corgi_jack_func) { 53 switch (corgi_jack_func) {
53 case CORGI_HP: 54 case CORGI_HP:
54 /* set = unmute headphone */ 55 /* set = unmute headphone */
55 gpio_set_value(CORGI_GPIO_MUTE_L, 1); 56 gpio_set_value(CORGI_GPIO_MUTE_L, 1);
56 gpio_set_value(CORGI_GPIO_MUTE_R, 1); 57 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
57 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 58 snd_soc_dapm_disable_pin(dapm, "Mic Jack");
58 snd_soc_dapm_disable_pin(codec, "Line Jack"); 59 snd_soc_dapm_disable_pin(dapm, "Line Jack");
59 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 60 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
60 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 61 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
61 break; 62 break;
62 case CORGI_MIC: 63 case CORGI_MIC:
63 /* reset = mute headphone */ 64 /* reset = mute headphone */
64 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 65 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
65 gpio_set_value(CORGI_GPIO_MUTE_R, 0); 66 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
66 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 67 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
67 snd_soc_dapm_disable_pin(codec, "Line Jack"); 68 snd_soc_dapm_disable_pin(dapm, "Line Jack");
68 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 69 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
69 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 70 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
70 break; 71 break;
71 case CORGI_LINE: 72 case CORGI_LINE:
72 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 73 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
73 gpio_set_value(CORGI_GPIO_MUTE_R, 0); 74 gpio_set_value(CORGI_GPIO_MUTE_R, 0);
74 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 75 snd_soc_dapm_disable_pin(dapm, "Mic Jack");
75 snd_soc_dapm_enable_pin(codec, "Line Jack"); 76 snd_soc_dapm_enable_pin(dapm, "Line Jack");
76 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 77 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
77 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 78 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
78 break; 79 break;
79 case CORGI_HEADSET: 80 case CORGI_HEADSET:
80 gpio_set_value(CORGI_GPIO_MUTE_L, 0); 81 gpio_set_value(CORGI_GPIO_MUTE_L, 0);
81 gpio_set_value(CORGI_GPIO_MUTE_R, 1); 82 gpio_set_value(CORGI_GPIO_MUTE_R, 1);
82 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 83 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
83 snd_soc_dapm_disable_pin(codec, "Line Jack"); 84 snd_soc_dapm_disable_pin(dapm, "Line Jack");
84 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 85 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
85 snd_soc_dapm_enable_pin(codec, "Headset Jack"); 86 snd_soc_dapm_enable_pin(dapm, "Headset Jack");
86 break; 87 break;
87 } 88 }
88 89
89 if (corgi_spk_func == CORGI_SPK_ON) 90 if (corgi_spk_func == CORGI_SPK_ON)
90 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 91 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
91 else 92 else
92 snd_soc_dapm_disable_pin(codec, "Ext Spk"); 93 snd_soc_dapm_disable_pin(dapm, "Ext Spk");
93 94
94 /* signal a DAPM event */ 95 /* signal a DAPM event */
95 snd_soc_dapm_sync(codec); 96 snd_soc_dapm_sync(dapm);
96} 97}
97 98
98static int corgi_startup(struct snd_pcm_substream *substream) 99static int corgi_startup(struct snd_pcm_substream *substream)
@@ -279,10 +280,11 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = {
279static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) 280static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
280{ 281{
281 struct snd_soc_codec *codec = rtd->codec; 282 struct snd_soc_codec *codec = rtd->codec;
283 struct snd_soc_dapm_context *dapm = &codec->dapm;
282 int err; 284 int err;
283 285
284 snd_soc_dapm_nc_pin(codec, "LLINEIN"); 286 snd_soc_dapm_nc_pin(dapm, "LLINEIN");
285 snd_soc_dapm_nc_pin(codec, "RLINEIN"); 287 snd_soc_dapm_nc_pin(dapm, "RLINEIN");
286 288
287 /* Add corgi specific controls */ 289 /* Add corgi specific controls */
288 err = snd_soc_add_controls(codec, wm8731_corgi_controls, 290 err = snd_soc_add_controls(codec, wm8731_corgi_controls,
@@ -291,13 +293,13 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd)
291 return err; 293 return err;
292 294
293 /* Add corgi specific widgets */ 295 /* Add corgi specific widgets */
294 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, 296 snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
295 ARRAY_SIZE(wm8731_dapm_widgets)); 297 ARRAY_SIZE(wm8731_dapm_widgets));
296 298
297 /* Set up corgi specific audio path audio_map */ 299 /* Set up corgi specific audio path audio_map */
298 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 300 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
299 301
300 snd_soc_dapm_sync(codec); 302 snd_soc_dapm_sync(dapm);
301 return 0; 303 return 0;
302} 304}
303 305
diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c
index c82cedb602fd..28333e7d9c50 100644
--- a/sound/soc/pxa/e740_wm9705.c
+++ b/sound/soc/pxa/e740_wm9705.c
@@ -16,7 +16,6 @@
16#include <sound/core.h> 16#include <sound/core.h>
17#include <sound/pcm.h> 17#include <sound/pcm.h>
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20 19
21#include <mach/audio.h> 20#include <mach/audio.h>
22#include <mach/eseries-gpio.h> 21#include <mach/eseries-gpio.h>
@@ -92,23 +91,24 @@ static const struct snd_soc_dapm_route audio_map[] = {
92static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd) 91static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd)
93{ 92{
94 struct snd_soc_codec *codec = rtd->codec; 93 struct snd_soc_codec *codec = rtd->codec;
95 94 struct snd_soc_dapm_context *dapm = &codec->dapm;
96 snd_soc_dapm_nc_pin(codec, "HPOUTL"); 95
97 snd_soc_dapm_nc_pin(codec, "HPOUTR"); 96 snd_soc_dapm_nc_pin(dapm, "HPOUTL");
98 snd_soc_dapm_nc_pin(codec, "PHONE"); 97 snd_soc_dapm_nc_pin(dapm, "HPOUTR");
99 snd_soc_dapm_nc_pin(codec, "LINEINL"); 98 snd_soc_dapm_nc_pin(dapm, "PHONE");
100 snd_soc_dapm_nc_pin(codec, "LINEINR"); 99 snd_soc_dapm_nc_pin(dapm, "LINEINL");
101 snd_soc_dapm_nc_pin(codec, "CDINL"); 100 snd_soc_dapm_nc_pin(dapm, "LINEINR");
102 snd_soc_dapm_nc_pin(codec, "CDINR"); 101 snd_soc_dapm_nc_pin(dapm, "CDINL");
103 snd_soc_dapm_nc_pin(codec, "PCBEEP"); 102 snd_soc_dapm_nc_pin(dapm, "CDINR");
104 snd_soc_dapm_nc_pin(codec, "MIC2"); 103 snd_soc_dapm_nc_pin(dapm, "PCBEEP");
105 104 snd_soc_dapm_nc_pin(dapm, "MIC2");
106 snd_soc_dapm_new_controls(codec, e740_dapm_widgets, 105
106 snd_soc_dapm_new_controls(dapm, e740_dapm_widgets,
107 ARRAY_SIZE(e740_dapm_widgets)); 107 ARRAY_SIZE(e740_dapm_widgets));
108 108
109 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 109 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
110 110
111 snd_soc_dapm_sync(codec); 111 snd_soc_dapm_sync(dapm);
112 112
113 return 0; 113 return 0;
114} 114}
diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c
index 4c143803a75e..01bf31675c55 100644
--- a/sound/soc/pxa/e750_wm9705.c
+++ b/sound/soc/pxa/e750_wm9705.c
@@ -16,7 +16,6 @@
16#include <sound/core.h> 16#include <sound/core.h>
17#include <sound/pcm.h> 17#include <sound/pcm.h>
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20 19
21#include <mach/audio.h> 20#include <mach/audio.h>
22#include <mach/eseries-gpio.h> 21#include <mach/eseries-gpio.h>
@@ -74,23 +73,24 @@ static const struct snd_soc_dapm_route audio_map[] = {
74static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd) 73static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd)
75{ 74{
76 struct snd_soc_codec *codec = rtd->codec; 75 struct snd_soc_codec *codec = rtd->codec;
77 76 struct snd_soc_dapm_context *dapm = &codec->dapm;
78 snd_soc_dapm_nc_pin(codec, "LOUT"); 77
79 snd_soc_dapm_nc_pin(codec, "ROUT"); 78 snd_soc_dapm_nc_pin(dapm, "LOUT");
80 snd_soc_dapm_nc_pin(codec, "PHONE"); 79 snd_soc_dapm_nc_pin(dapm, "ROUT");
81 snd_soc_dapm_nc_pin(codec, "LINEINL"); 80 snd_soc_dapm_nc_pin(dapm, "PHONE");
82 snd_soc_dapm_nc_pin(codec, "LINEINR"); 81 snd_soc_dapm_nc_pin(dapm, "LINEINL");
83 snd_soc_dapm_nc_pin(codec, "CDINL"); 82 snd_soc_dapm_nc_pin(dapm, "LINEINR");
84 snd_soc_dapm_nc_pin(codec, "CDINR"); 83 snd_soc_dapm_nc_pin(dapm, "CDINL");
85 snd_soc_dapm_nc_pin(codec, "PCBEEP"); 84 snd_soc_dapm_nc_pin(dapm, "CDINR");
86 snd_soc_dapm_nc_pin(codec, "MIC2"); 85 snd_soc_dapm_nc_pin(dapm, "PCBEEP");
87 86 snd_soc_dapm_nc_pin(dapm, "MIC2");
88 snd_soc_dapm_new_controls(codec, e750_dapm_widgets, 87
88 snd_soc_dapm_new_controls(dapm, e750_dapm_widgets,
89 ARRAY_SIZE(e750_dapm_widgets)); 89 ARRAY_SIZE(e750_dapm_widgets));
90 90
91 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 91 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
92 92
93 snd_soc_dapm_sync(codec); 93 snd_soc_dapm_sync(dapm);
94 94
95 return 0; 95 return 0;
96} 96}
diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c
index d42e5fe832c5..c6a37c6ef23b 100644
--- a/sound/soc/pxa/e800_wm9712.c
+++ b/sound/soc/pxa/e800_wm9712.c
@@ -16,7 +16,6 @@
16#include <sound/core.h> 16#include <sound/core.h>
17#include <sound/pcm.h> 17#include <sound/pcm.h>
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20 19
21#include <asm/mach-types.h> 20#include <asm/mach-types.h>
22#include <mach/audio.h> 21#include <mach/audio.h>
@@ -75,12 +74,13 @@ static const struct snd_soc_dapm_route audio_map[] = {
75static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd) 74static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd)
76{ 75{
77 struct snd_soc_codec *codec = rtd->codec; 76 struct snd_soc_codec *codec = rtd->codec;
77 struct snd_soc_dapm_context *dapm = &codec->dapm;
78 78
79 snd_soc_dapm_new_controls(codec, e800_dapm_widgets, 79 snd_soc_dapm_new_controls(dapm, e800_dapm_widgets,
80 ARRAY_SIZE(e800_dapm_widgets)); 80 ARRAY_SIZE(e800_dapm_widgets));
81 81
82 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 82 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
83 snd_soc_dapm_sync(codec); 83 snd_soc_dapm_sync(dapm);
84 84
85 return 0; 85 return 0;
86} 86}
diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c
index eadf9d351a04..fc22e6eefc98 100644
--- a/sound/soc/pxa/em-x270.c
+++ b/sound/soc/pxa/em-x270.c
@@ -26,7 +26,6 @@
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/pcm.h> 27#include <sound/pcm.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30 29
31#include <asm/mach-types.h> 30#include <asm/mach-types.h>
32#include <mach/audio.h> 31#include <mach/audio.h>
diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c
index 5ef0526924b9..67dcc36cd621 100644
--- a/sound/soc/pxa/magician.c
+++ b/sound/soc/pxa/magician.c
@@ -26,7 +26,6 @@
26#include <sound/pcm.h> 26#include <sound/pcm.h>
27#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/uda1380.h> 29#include <sound/uda1380.h>
31 30
32#include <mach/magician.h> 31#include <mach/magician.h>
@@ -44,27 +43,29 @@ static int magician_in_sel = MAGICIAN_MIC;
44 43
45static void magician_ext_control(struct snd_soc_codec *codec) 44static void magician_ext_control(struct snd_soc_codec *codec)
46{ 45{
46 struct snd_soc_dapm_context *dapm = &codec->dapm;
47
47 if (magician_spk_switch) 48 if (magician_spk_switch)
48 snd_soc_dapm_enable_pin(codec, "Speaker"); 49 snd_soc_dapm_enable_pin(dapm, "Speaker");
49 else 50 else
50 snd_soc_dapm_disable_pin(codec, "Speaker"); 51 snd_soc_dapm_disable_pin(dapm, "Speaker");
51 if (magician_hp_switch) 52 if (magician_hp_switch)
52 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 53 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
53 else 54 else
54 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 55 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
55 56
56 switch (magician_in_sel) { 57 switch (magician_in_sel) {
57 case MAGICIAN_MIC: 58 case MAGICIAN_MIC:
58 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 59 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
59 snd_soc_dapm_enable_pin(codec, "Call Mic"); 60 snd_soc_dapm_enable_pin(dapm, "Call Mic");
60 break; 61 break;
61 case MAGICIAN_MIC_EXT: 62 case MAGICIAN_MIC_EXT:
62 snd_soc_dapm_disable_pin(codec, "Call Mic"); 63 snd_soc_dapm_disable_pin(dapm, "Call Mic");
63 snd_soc_dapm_enable_pin(codec, "Headset Mic"); 64 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
64 break; 65 break;
65 } 66 }
66 67
67 snd_soc_dapm_sync(codec); 68 snd_soc_dapm_sync(dapm);
68} 69}
69 70
70static int magician_startup(struct snd_pcm_substream *substream) 71static int magician_startup(struct snd_pcm_substream *substream)
@@ -399,15 +400,16 @@ static const struct snd_kcontrol_new uda1380_magician_controls[] = {
399static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd) 400static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
400{ 401{
401 struct snd_soc_codec *codec = rtd->codec; 402 struct snd_soc_codec *codec = rtd->codec;
403 struct snd_soc_dapm_context *dapm = &codec->dapm;
402 int err; 404 int err;
403 405
404 /* NC codec pins */ 406 /* NC codec pins */
405 snd_soc_dapm_nc_pin(codec, "VOUTLHP"); 407 snd_soc_dapm_nc_pin(dapm, "VOUTLHP");
406 snd_soc_dapm_nc_pin(codec, "VOUTRHP"); 408 snd_soc_dapm_nc_pin(dapm, "VOUTRHP");
407 409
408 /* FIXME: is anything connected here? */ 410 /* FIXME: is anything connected here? */
409 snd_soc_dapm_nc_pin(codec, "VINL"); 411 snd_soc_dapm_nc_pin(dapm, "VINL");
410 snd_soc_dapm_nc_pin(codec, "VINR"); 412 snd_soc_dapm_nc_pin(dapm, "VINR");
411 413
412 /* Add magician specific controls */ 414 /* Add magician specific controls */
413 err = snd_soc_add_controls(codec, uda1380_magician_controls, 415 err = snd_soc_add_controls(codec, uda1380_magician_controls,
@@ -416,13 +418,13 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd)
416 return err; 418 return err;
417 419
418 /* Add magician specific widgets */ 420 /* Add magician specific widgets */
419 snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, 421 snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
420 ARRAY_SIZE(uda1380_dapm_widgets)); 422 ARRAY_SIZE(uda1380_dapm_widgets));
421 423
422 /* Set up magician specific audio path interconnects */ 424 /* Set up magician specific audio path interconnects */
423 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 425 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
424 426
425 snd_soc_dapm_sync(codec); 427 snd_soc_dapm_sync(dapm);
426 return 0; 428 return 0;
427} 429}
428 430
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index f284cc54bc80..0d70fc8c12bd 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -50,7 +50,6 @@
50#include <sound/core.h> 50#include <sound/core.h>
51#include <sound/pcm.h> 51#include <sound/pcm.h>
52#include <sound/soc.h> 52#include <sound/soc.h>
53#include <sound/soc-dapm.h>
54#include <sound/initval.h> 53#include <sound/initval.h>
55#include <sound/ac97_codec.h> 54#include <sound/ac97_codec.h>
56 55
@@ -130,13 +129,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
130static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd) 129static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
131{ 130{
132 struct snd_soc_codec *codec = rtd->codec; 131 struct snd_soc_codec *codec = rtd->codec;
132 struct snd_soc_dapm_context *dapm = &codec->dapm;
133 unsigned short reg; 133 unsigned short reg;
134 134
135 /* Add mioa701 specific widgets */ 135 /* Add mioa701 specific widgets */
136 snd_soc_dapm_new_controls(codec, ARRAY_AND_SIZE(mioa701_dapm_widgets)); 136 snd_soc_dapm_new_controls(dapm, ARRAY_AND_SIZE(mioa701_dapm_widgets));
137 137
138 /* Set up mioa701 specific audio path audio_mapnects */ 138 /* Set up mioa701 specific audio path audio_mapnects */
139 snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map)); 139 snd_soc_dapm_add_routes(dapm, ARRAY_AND_SIZE(audio_map));
140 140
141 /* Prepare GPIO8 for rear speaker amplifier */ 141 /* Prepare GPIO8 for rear speaker amplifier */
142 reg = codec->driver->read(codec, AC97_GPIO_CFG); 142 reg = codec->driver->read(codec, AC97_GPIO_CFG);
@@ -146,12 +146,12 @@ static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd)
146 reg = codec->driver->read(codec, AC97_3D_CONTROL); 146 reg = codec->driver->read(codec, AC97_3D_CONTROL);
147 codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000); 147 codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000);
148 148
149 snd_soc_dapm_enable_pin(codec, "Front Speaker"); 149 snd_soc_dapm_enable_pin(dapm, "Front Speaker");
150 snd_soc_dapm_enable_pin(codec, "Rear Speaker"); 150 snd_soc_dapm_enable_pin(dapm, "Rear Speaker");
151 snd_soc_dapm_enable_pin(codec, "Front Mic"); 151 snd_soc_dapm_enable_pin(dapm, "Front Mic");
152 snd_soc_dapm_enable_pin(codec, "GSM Line In"); 152 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
153 snd_soc_dapm_enable_pin(codec, "GSM Line Out"); 153 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
154 snd_soc_dapm_sync(codec); 154 snd_soc_dapm_sync(dapm);
155 155
156 return 0; 156 return 0;
157} 157}
diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c
index 13f6d485d571..857db96d4a4f 100644
--- a/sound/soc/pxa/palm27x.c
+++ b/sound/soc/pxa/palm27x.c
@@ -21,7 +21,6 @@
21#include <sound/core.h> 21#include <sound/core.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25#include <sound/jack.h> 24#include <sound/jack.h>
26 25
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
@@ -77,37 +76,38 @@ static struct snd_soc_card palm27x_asoc;
77static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) 76static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd)
78{ 77{
79 struct snd_soc_codec *codec = rtd->codec; 78 struct snd_soc_codec *codec = rtd->codec;
79 struct snd_soc_dapm_context *dapm = &codec->dapm;
80 int err; 80 int err;
81 81
82 /* add palm27x specific widgets */ 82 /* add palm27x specific widgets */
83 err = snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets, 83 err = snd_soc_dapm_new_controls(dapm, palm27x_dapm_widgets,
84 ARRAY_SIZE(palm27x_dapm_widgets)); 84 ARRAY_SIZE(palm27x_dapm_widgets));
85 if (err) 85 if (err)
86 return err; 86 return err;
87 87
88 /* set up palm27x specific audio path audio_map */ 88 /* set up palm27x specific audio path audio_map */
89 err = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 89 err = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
90 if (err) 90 if (err)
91 return err; 91 return err;
92 92
93 /* connected pins */ 93 /* connected pins */
94 if (machine_is_palmld()) 94 if (machine_is_palmld())
95 snd_soc_dapm_enable_pin(codec, "MIC1"); 95 snd_soc_dapm_enable_pin(dapm, "MIC1");
96 snd_soc_dapm_enable_pin(codec, "HPOUTL"); 96 snd_soc_dapm_enable_pin(dapm, "HPOUTL");
97 snd_soc_dapm_enable_pin(codec, "HPOUTR"); 97 snd_soc_dapm_enable_pin(dapm, "HPOUTR");
98 snd_soc_dapm_enable_pin(codec, "LOUT2"); 98 snd_soc_dapm_enable_pin(dapm, "LOUT2");
99 snd_soc_dapm_enable_pin(codec, "ROUT2"); 99 snd_soc_dapm_enable_pin(dapm, "ROUT2");
100 100
101 /* not connected pins */ 101 /* not connected pins */
102 snd_soc_dapm_nc_pin(codec, "OUT3"); 102 snd_soc_dapm_nc_pin(dapm, "OUT3");
103 snd_soc_dapm_nc_pin(codec, "MONOOUT"); 103 snd_soc_dapm_nc_pin(dapm, "MONOOUT");
104 snd_soc_dapm_nc_pin(codec, "LINEINL"); 104 snd_soc_dapm_nc_pin(dapm, "LINEINL");
105 snd_soc_dapm_nc_pin(codec, "LINEINR"); 105 snd_soc_dapm_nc_pin(dapm, "LINEINR");
106 snd_soc_dapm_nc_pin(codec, "PCBEEP"); 106 snd_soc_dapm_nc_pin(dapm, "PCBEEP");
107 snd_soc_dapm_nc_pin(codec, "PHONE"); 107 snd_soc_dapm_nc_pin(dapm, "PHONE");
108 snd_soc_dapm_nc_pin(codec, "MIC2"); 108 snd_soc_dapm_nc_pin(dapm, "MIC2");
109 109
110 err = snd_soc_dapm_sync(codec); 110 err = snd_soc_dapm_sync(dapm);
111 if (err) 111 if (err)
112 return err; 112 return err;
113 113
diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c
index 84edd0385a21..6298ee115e27 100644
--- a/sound/soc/pxa/poodle.c
+++ b/sound/soc/pxa/poodle.c
@@ -23,7 +23,6 @@
23#include <sound/core.h> 23#include <sound/core.h>
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27 26
28#include <asm/mach-types.h> 27#include <asm/mach-types.h>
29#include <asm/hardware/locomo.h> 28#include <asm/hardware/locomo.h>
@@ -46,6 +45,8 @@ static int poodle_spk_func;
46 45
47static void poodle_ext_control(struct snd_soc_codec *codec) 46static void poodle_ext_control(struct snd_soc_codec *codec)
48{ 47{
48 struct snd_soc_dapm_context *dapm = &codec->dapm;
49
49 /* set up jack connection */ 50 /* set up jack connection */
50 if (poodle_jack_func == POODLE_HP) { 51 if (poodle_jack_func == POODLE_HP) {
51 /* set = unmute headphone */ 52 /* set = unmute headphone */
@@ -53,23 +54,23 @@ static void poodle_ext_control(struct snd_soc_codec *codec)
53 POODLE_LOCOMO_GPIO_MUTE_L, 1); 54 POODLE_LOCOMO_GPIO_MUTE_L, 1);
54 locomo_gpio_write(&poodle_locomo_device.dev, 55 locomo_gpio_write(&poodle_locomo_device.dev,
55 POODLE_LOCOMO_GPIO_MUTE_R, 1); 56 POODLE_LOCOMO_GPIO_MUTE_R, 1);
56 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 57 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
57 } else { 58 } else {
58 locomo_gpio_write(&poodle_locomo_device.dev, 59 locomo_gpio_write(&poodle_locomo_device.dev,
59 POODLE_LOCOMO_GPIO_MUTE_L, 0); 60 POODLE_LOCOMO_GPIO_MUTE_L, 0);
60 locomo_gpio_write(&poodle_locomo_device.dev, 61 locomo_gpio_write(&poodle_locomo_device.dev,
61 POODLE_LOCOMO_GPIO_MUTE_R, 0); 62 POODLE_LOCOMO_GPIO_MUTE_R, 0);
62 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 63 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
63 } 64 }
64 65
65 /* set the enpoints to their new connetion states */ 66 /* set the enpoints to their new connetion states */
66 if (poodle_spk_func == POODLE_SPK_ON) 67 if (poodle_spk_func == POODLE_SPK_ON)
67 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 68 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
68 else 69 else
69 snd_soc_dapm_disable_pin(codec, "Ext Spk"); 70 snd_soc_dapm_disable_pin(dapm, "Ext Spk");
70 71
71 /* signal a DAPM event */ 72 /* signal a DAPM event */
72 snd_soc_dapm_sync(codec); 73 snd_soc_dapm_sync(dapm);
73} 74}
74 75
75static int poodle_startup(struct snd_pcm_substream *substream) 76static int poodle_startup(struct snd_pcm_substream *substream)
@@ -244,11 +245,12 @@ static const struct snd_kcontrol_new wm8731_poodle_controls[] = {
244static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd) 245static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
245{ 246{
246 struct snd_soc_codec *codec = rtd->codec; 247 struct snd_soc_codec *codec = rtd->codec;
248 struct snd_soc_dapm_context *dapm = &codec->dapm;
247 int err; 249 int err;
248 250
249 snd_soc_dapm_nc_pin(codec, "LLINEIN"); 251 snd_soc_dapm_nc_pin(dapm, "LLINEIN");
250 snd_soc_dapm_nc_pin(codec, "RLINEIN"); 252 snd_soc_dapm_nc_pin(dapm, "RLINEIN");
251 snd_soc_dapm_enable_pin(codec, "MICIN"); 253 snd_soc_dapm_enable_pin(dapm, "MICIN");
252 254
253 /* Add poodle specific controls */ 255 /* Add poodle specific controls */
254 err = snd_soc_add_controls(codec, wm8731_poodle_controls, 256 err = snd_soc_add_controls(codec, wm8731_poodle_controls,
@@ -257,13 +259,13 @@ static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd)
257 return err; 259 return err;
258 260
259 /* Add poodle specific widgets */ 261 /* Add poodle specific widgets */
260 snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, 262 snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets,
261 ARRAY_SIZE(wm8731_dapm_widgets)); 263 ARRAY_SIZE(wm8731_dapm_widgets));
262 264
263 /* Set up poodle specific audio path audio_map */ 265 /* Set up poodle specific audio path audio_map */
264 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 266 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
265 267
266 snd_soc_dapm_sync(codec); 268 snd_soc_dapm_sync(dapm);
267 return 0; 269 return 0;
268} 270}
269 271
diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c
index 2cda82bc5d2e..0fd60f423036 100644
--- a/sound/soc/pxa/raumfeld.c
+++ b/sound/soc/pxa/raumfeld.c
@@ -22,7 +22,6 @@
22#include <linux/gpio.h> 22#include <linux/gpio.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26 25
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
28 27
diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c
index d63cb474b4e1..9595189fc681 100644
--- a/sound/soc/pxa/saarb.c
+++ b/sound/soc/pxa/saarb.c
@@ -18,7 +18,6 @@
18#include <sound/pcm.h> 18#include <sound/pcm.h>
19#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/jack.h> 21#include <sound/jack.h>
23 22
24#include <asm/mach-types.h> 23#include <asm/mach-types.h>
@@ -133,20 +132,21 @@ static struct snd_soc_card snd_soc_card_saarb = {
133static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd) 132static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd)
134{ 133{
135 struct snd_soc_codec *codec = rtd->codec; 134 struct snd_soc_codec *codec = rtd->codec;
135 struct snd_soc_dapm_context *dapm = &codec->dapm;
136 int ret; 136 int ret;
137 137
138 snd_soc_dapm_new_controls(codec, saarb_dapm_widgets, 138 snd_soc_dapm_new_controls(dapm, saarb_dapm_widgets,
139 ARRAY_SIZE(saarb_dapm_widgets)); 139 ARRAY_SIZE(saarb_dapm_widgets));
140 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 140 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
141 141
142 /* connected pins */ 142 /* connected pins */
143 snd_soc_dapm_enable_pin(codec, "Ext Speaker"); 143 snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
144 snd_soc_dapm_enable_pin(codec, "Ext Mic 1"); 144 snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
145 snd_soc_dapm_enable_pin(codec, "Ext Mic 3"); 145 snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
146 snd_soc_dapm_disable_pin(codec, "Headset Mic 2"); 146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
147 snd_soc_dapm_disable_pin(codec, "Headset Stereophone"); 147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
148 148
149 ret = snd_soc_dapm_sync(codec); 149 ret = snd_soc_dapm_sync(dapm);
150 if (ret) 150 if (ret)
151 return ret; 151 return ret;
152 152
diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c
index 0b30d7de24ec..c2acb69b957a 100644
--- a/sound/soc/pxa/spitz.c
+++ b/sound/soc/pxa/spitz.c
@@ -23,7 +23,6 @@
23#include <sound/core.h> 23#include <sound/core.h>
24#include <sound/pcm.h> 24#include <sound/pcm.h>
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27 26
28#include <asm/mach-types.h> 27#include <asm/mach-types.h>
29#include <mach/spitz.h> 28#include <mach/spitz.h>
@@ -46,61 +45,63 @@ static int spitz_spk_func;
46 45
47static void spitz_ext_control(struct snd_soc_codec *codec) 46static void spitz_ext_control(struct snd_soc_codec *codec)
48{ 47{
48 struct snd_soc_dapm_context *dapm = &codec->dapm;
49
49 if (spitz_spk_func == SPITZ_SPK_ON) 50 if (spitz_spk_func == SPITZ_SPK_ON)
50 snd_soc_dapm_enable_pin(codec, "Ext Spk"); 51 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
51 else 52 else
52 snd_soc_dapm_disable_pin(codec, "Ext Spk"); 53 snd_soc_dapm_disable_pin(dapm, "Ext Spk");
53 54
54 /* set up jack connection */ 55 /* set up jack connection */
55 switch (spitz_jack_func) { 56 switch (spitz_jack_func) {
56 case SPITZ_HP: 57 case SPITZ_HP:
57 /* enable and unmute hp jack, disable mic bias */ 58 /* enable and unmute hp jack, disable mic bias */
58 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 59 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
59 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 60 snd_soc_dapm_disable_pin(dapm, "Mic Jack");
60 snd_soc_dapm_disable_pin(codec, "Line Jack"); 61 snd_soc_dapm_disable_pin(dapm, "Line Jack");
61 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 62 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
62 gpio_set_value(SPITZ_GPIO_MUTE_L, 1); 63 gpio_set_value(SPITZ_GPIO_MUTE_L, 1);
63 gpio_set_value(SPITZ_GPIO_MUTE_R, 1); 64 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
64 break; 65 break;
65 case SPITZ_MIC: 66 case SPITZ_MIC:
66 /* enable mic jack and bias, mute hp */ 67 /* enable mic jack and bias, mute hp */
67 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 68 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
68 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 69 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
69 snd_soc_dapm_disable_pin(codec, "Line Jack"); 70 snd_soc_dapm_disable_pin(dapm, "Line Jack");
70 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 71 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
71 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 72 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
72 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 73 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
73 break; 74 break;
74 case SPITZ_LINE: 75 case SPITZ_LINE:
75 /* enable line jack, disable mic bias and mute hp */ 76 /* enable line jack, disable mic bias and mute hp */
76 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 77 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
77 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 78 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
78 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 79 snd_soc_dapm_disable_pin(dapm, "Mic Jack");
79 snd_soc_dapm_enable_pin(codec, "Line Jack"); 80 snd_soc_dapm_enable_pin(dapm, "Line Jack");
80 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 81 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
81 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 82 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
82 break; 83 break;
83 case SPITZ_HEADSET: 84 case SPITZ_HEADSET:
84 /* enable and unmute headset jack enable mic bias, mute L hp */ 85 /* enable and unmute headset jack enable mic bias, mute L hp */
85 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 86 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
86 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 87 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
87 snd_soc_dapm_disable_pin(codec, "Line Jack"); 88 snd_soc_dapm_disable_pin(dapm, "Line Jack");
88 snd_soc_dapm_enable_pin(codec, "Headset Jack"); 89 snd_soc_dapm_enable_pin(dapm, "Headset Jack");
89 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 90 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
90 gpio_set_value(SPITZ_GPIO_MUTE_R, 1); 91 gpio_set_value(SPITZ_GPIO_MUTE_R, 1);
91 break; 92 break;
92 case SPITZ_HP_OFF: 93 case SPITZ_HP_OFF:
93 94
94 /* jack removed, everything off */ 95 /* jack removed, everything off */
95 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 96 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
96 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 97 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
97 snd_soc_dapm_disable_pin(codec, "Mic Jack"); 98 snd_soc_dapm_disable_pin(dapm, "Mic Jack");
98 snd_soc_dapm_disable_pin(codec, "Line Jack"); 99 snd_soc_dapm_disable_pin(dapm, "Line Jack");
99 gpio_set_value(SPITZ_GPIO_MUTE_L, 0); 100 gpio_set_value(SPITZ_GPIO_MUTE_L, 0);
100 gpio_set_value(SPITZ_GPIO_MUTE_R, 0); 101 gpio_set_value(SPITZ_GPIO_MUTE_R, 0);
101 break; 102 break;
102 } 103 }
103 snd_soc_dapm_sync(codec); 104 snd_soc_dapm_sync(dapm);
104} 105}
105 106
106static int spitz_startup(struct snd_pcm_substream *substream) 107static int spitz_startup(struct snd_pcm_substream *substream)
@@ -281,16 +282,17 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = {
281static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) 282static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
282{ 283{
283 struct snd_soc_codec *codec = rtd->codec; 284 struct snd_soc_codec *codec = rtd->codec;
285 struct snd_soc_dapm_context *dapm = &codec->dapm;
284 int err; 286 int err;
285 287
286 /* NC codec pins */ 288 /* NC codec pins */
287 snd_soc_dapm_nc_pin(codec, "RINPUT1"); 289 snd_soc_dapm_nc_pin(dapm, "RINPUT1");
288 snd_soc_dapm_nc_pin(codec, "LINPUT2"); 290 snd_soc_dapm_nc_pin(dapm, "LINPUT2");
289 snd_soc_dapm_nc_pin(codec, "RINPUT2"); 291 snd_soc_dapm_nc_pin(dapm, "RINPUT2");
290 snd_soc_dapm_nc_pin(codec, "LINPUT3"); 292 snd_soc_dapm_nc_pin(dapm, "LINPUT3");
291 snd_soc_dapm_nc_pin(codec, "RINPUT3"); 293 snd_soc_dapm_nc_pin(dapm, "RINPUT3");
292 snd_soc_dapm_nc_pin(codec, "OUT3"); 294 snd_soc_dapm_nc_pin(dapm, "OUT3");
293 snd_soc_dapm_nc_pin(codec, "MONO1"); 295 snd_soc_dapm_nc_pin(dapm, "MONO1");
294 296
295 /* Add spitz specific controls */ 297 /* Add spitz specific controls */
296 err = snd_soc_add_controls(codec, wm8750_spitz_controls, 298 err = snd_soc_add_controls(codec, wm8750_spitz_controls,
@@ -299,13 +301,13 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd)
299 return err; 301 return err;
300 302
301 /* Add spitz specific widgets */ 303 /* Add spitz specific widgets */
302 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, 304 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
303 ARRAY_SIZE(wm8750_dapm_widgets)); 305 ARRAY_SIZE(wm8750_dapm_widgets));
304 306
305 /* Set up spitz specific audio paths */ 307 /* Set up spitz specific audio paths */
306 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 308 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
307 309
308 snd_soc_dapm_sync(codec); 310 snd_soc_dapm_sync(dapm);
309 return 0; 311 return 0;
310} 312}
311 313
diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c
index 248c283fc4df..f881f65ec172 100644
--- a/sound/soc/pxa/tavorevb3.c
+++ b/sound/soc/pxa/tavorevb3.c
@@ -18,7 +18,6 @@
18#include <sound/pcm.h> 18#include <sound/pcm.h>
19#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/jack.h> 21#include <sound/jack.h>
23 22
24#include <asm/mach-types.h> 23#include <asm/mach-types.h>
@@ -133,20 +132,21 @@ static struct snd_soc_card snd_soc_card_evb3 = {
133static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd) 132static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd)
134{ 133{
135 struct snd_soc_codec *codec = rtd->codec; 134 struct snd_soc_codec *codec = rtd->codec;
135 struct snd_soc_dapm_context *dapm = &codec->dapm;
136 int ret; 136 int ret;
137 137
138 snd_soc_dapm_new_controls(codec, evb3_dapm_widgets, 138 snd_soc_dapm_new_controls(dapm, evb3_dapm_widgets,
139 ARRAY_SIZE(evb3_dapm_widgets)); 139 ARRAY_SIZE(evb3_dapm_widgets));
140 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 140 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
141 141
142 /* connected pins */ 142 /* connected pins */
143 snd_soc_dapm_enable_pin(codec, "Ext Speaker"); 143 snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
144 snd_soc_dapm_enable_pin(codec, "Ext Mic 1"); 144 snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
145 snd_soc_dapm_enable_pin(codec, "Ext Mic 3"); 145 snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
146 snd_soc_dapm_disable_pin(codec, "Headset Mic 2"); 146 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
147 snd_soc_dapm_disable_pin(codec, "Headset Stereophone"); 147 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
148 148
149 ret = snd_soc_dapm_sync(codec); 149 ret = snd_soc_dapm_sync(dapm);
150 if (ret) 150 if (ret)
151 return ret; 151 return ret;
152 152
diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c
index 7b983f935454..f75804ef0897 100644
--- a/sound/soc/pxa/tosa.c
+++ b/sound/soc/pxa/tosa.c
@@ -26,7 +26,6 @@
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/pcm.h> 27#include <sound/pcm.h>
28#include <sound/soc.h> 28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30 29
31#include <asm/mach-types.h> 30#include <asm/mach-types.h>
32#include <mach/tosa.h> 31#include <mach/tosa.h>
@@ -49,31 +48,33 @@ static int tosa_spk_func;
49 48
50static void tosa_ext_control(struct snd_soc_codec *codec) 49static void tosa_ext_control(struct snd_soc_codec *codec)
51{ 50{
51 struct snd_soc_dapm_context *dapm = &codec->dapm;
52
52 /* set up jack connection */ 53 /* set up jack connection */
53 switch (tosa_jack_func) { 54 switch (tosa_jack_func) {
54 case TOSA_HP: 55 case TOSA_HP:
55 snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); 56 snd_soc_dapm_disable_pin(dapm, "Mic (Internal)");
56 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 57 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
57 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 58 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
58 break; 59 break;
59 case TOSA_MIC_INT: 60 case TOSA_MIC_INT:
60 snd_soc_dapm_enable_pin(codec, "Mic (Internal)"); 61 snd_soc_dapm_enable_pin(dapm, "Mic (Internal)");
61 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 62 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
62 snd_soc_dapm_disable_pin(codec, "Headset Jack"); 63 snd_soc_dapm_disable_pin(dapm, "Headset Jack");
63 break; 64 break;
64 case TOSA_HEADSET: 65 case TOSA_HEADSET:
65 snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); 66 snd_soc_dapm_disable_pin(dapm, "Mic (Internal)");
66 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 67 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
67 snd_soc_dapm_enable_pin(codec, "Headset Jack"); 68 snd_soc_dapm_enable_pin(dapm, "Headset Jack");
68 break; 69 break;
69 } 70 }
70 71
71 if (tosa_spk_func == TOSA_SPK_ON) 72 if (tosa_spk_func == TOSA_SPK_ON)
72 snd_soc_dapm_enable_pin(codec, "Speaker"); 73 snd_soc_dapm_enable_pin(dapm, "Speaker");
73 else 74 else
74 snd_soc_dapm_disable_pin(codec, "Speaker"); 75 snd_soc_dapm_disable_pin(dapm, "Speaker");
75 76
76 snd_soc_dapm_sync(codec); 77 snd_soc_dapm_sync(dapm);
77} 78}
78 79
79static int tosa_startup(struct snd_pcm_substream *substream) 80static int tosa_startup(struct snd_pcm_substream *substream)
@@ -191,10 +192,11 @@ static const struct snd_kcontrol_new tosa_controls[] = {
191static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd) 192static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
192{ 193{
193 struct snd_soc_codec *codec = rtd->codec; 194 struct snd_soc_codec *codec = rtd->codec;
195 struct snd_soc_dapm_context *dapm = &codec->dapm;
194 int err; 196 int err;
195 197
196 snd_soc_dapm_nc_pin(codec, "OUT3"); 198 snd_soc_dapm_nc_pin(dapm, "OUT3");
197 snd_soc_dapm_nc_pin(codec, "MONOOUT"); 199 snd_soc_dapm_nc_pin(dapm, "MONOOUT");
198 200
199 /* add tosa specific controls */ 201 /* add tosa specific controls */
200 err = snd_soc_add_controls(codec, tosa_controls, 202 err = snd_soc_add_controls(codec, tosa_controls,
@@ -203,13 +205,13 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd)
203 return err; 205 return err;
204 206
205 /* add tosa specific widgets */ 207 /* add tosa specific widgets */
206 snd_soc_dapm_new_controls(codec, tosa_dapm_widgets, 208 snd_soc_dapm_new_controls(dapm, tosa_dapm_widgets,
207 ARRAY_SIZE(tosa_dapm_widgets)); 209 ARRAY_SIZE(tosa_dapm_widgets));
208 210
209 /* set up tosa specific audio path audio_map */ 211 /* set up tosa specific audio path audio_map */
210 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 212 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
211 213
212 snd_soc_dapm_sync(codec); 214 snd_soc_dapm_sync(dapm);
213 return 0; 215 return 0;
214} 216}
215 217
diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c
index 4cc841b44182..2d4f896d7fec 100644
--- a/sound/soc/pxa/z2.c
+++ b/sound/soc/pxa/z2.c
@@ -21,7 +21,6 @@
21#include <sound/core.h> 21#include <sound/core.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25#include <sound/jack.h> 24#include <sound/jack.h>
26 25
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
@@ -140,22 +139,23 @@ static const struct snd_soc_dapm_route audio_map[] = {
140static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd) 139static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd)
141{ 140{
142 struct snd_soc_codec *codec = rtd->codec; 141 struct snd_soc_codec *codec = rtd->codec;
142 struct snd_soc_dapm_context *dapm = &codec->dapm;
143 int ret; 143 int ret;
144 144
145 /* NC codec pins */ 145 /* NC codec pins */
146 snd_soc_dapm_disable_pin(codec, "LINPUT3"); 146 snd_soc_dapm_disable_pin(dapm, "LINPUT3");
147 snd_soc_dapm_disable_pin(codec, "RINPUT3"); 147 snd_soc_dapm_disable_pin(dapm, "RINPUT3");
148 snd_soc_dapm_disable_pin(codec, "OUT3"); 148 snd_soc_dapm_disable_pin(dapm, "OUT3");
149 snd_soc_dapm_disable_pin(codec, "MONO"); 149 snd_soc_dapm_disable_pin(dapm, "MONO");
150 150
151 /* Add z2 specific widgets */ 151 /* Add z2 specific widgets */
152 snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, 152 snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
153 ARRAY_SIZE(wm8750_dapm_widgets)); 153 ARRAY_SIZE(wm8750_dapm_widgets));
154 154
155 /* Set up z2 specific audio paths */ 155 /* Set up z2 specific audio paths */
156 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 156 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
157 157
158 ret = snd_soc_dapm_sync(codec); 158 ret = snd_soc_dapm_sync(dapm);
159 if (ret) 159 if (ret)
160 goto err; 160 goto err;
161 161
diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c
index d27e05af7759..b222a7d72027 100644
--- a/sound/soc/pxa/zylonite.c
+++ b/sound/soc/pxa/zylonite.c
@@ -20,7 +20,6 @@
20#include <sound/pcm.h> 20#include <sound/pcm.h>
21#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24 23
25#include "../codecs/wm9713.h" 24#include "../codecs/wm9713.h"
26#include "pxa2xx-ac97.h" 25#include "pxa2xx-ac97.h"
@@ -73,21 +72,22 @@ static const struct snd_soc_dapm_route audio_map[] = {
73static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd) 72static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd)
74{ 73{
75 struct snd_soc_codec *codec = rtd->codec; 74 struct snd_soc_codec *codec = rtd->codec;
75 struct snd_soc_dapm_context *dapm = &codec->dapm;
76 76
77 if (clk_pout) 77 if (clk_pout)
78 snd_soc_dai_set_pll(rtd->codec_dai, 0, 0, 78 snd_soc_dai_set_pll(rtd->codec_dai, 0, 0,
79 clk_get_rate(pout), 0); 79 clk_get_rate(pout), 0);
80 80
81 snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, 81 snd_soc_dapm_new_controls(dapm, zylonite_dapm_widgets,
82 ARRAY_SIZE(zylonite_dapm_widgets)); 82 ARRAY_SIZE(zylonite_dapm_widgets));
83 83
84 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 84 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
85 85
86 /* Static setup for now */ 86 /* Static setup for now */
87 snd_soc_dapm_enable_pin(codec, "Headphone"); 87 snd_soc_dapm_enable_pin(dapm, "Headphone");
88 snd_soc_dapm_enable_pin(codec, "Headset Earpiece"); 88 snd_soc_dapm_enable_pin(dapm, "Headset Earpiece");
89 89
90 snd_soc_dapm_sync(codec); 90 snd_soc_dapm_sync(dapm);
91 return 0; 91 return 0;
92} 92}
93 93
diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig
deleted file mode 100644
index d85bf8a0abb2..000000000000
--- a/sound/soc/s3c24xx/Kconfig
+++ /dev/null
@@ -1,171 +0,0 @@
1config SND_S3C24XX_SOC
2 tristate "SoC Audio for the Samsung S3CXXXX chips"
3 depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210
4 select S3C64XX_DMA if ARCH_S3C64XX
5 select S3C2410_DMA if ARCH_S3C2410
6 help
7 Say Y or M if you want to add support for codecs attached to
8 the S3C24XX AC97 or I2S interfaces. You will also need to
9 select the audio interfaces to support below.
10
11config SND_S3C24XX_SOC_I2S
12 tristate
13 select S3C2410_DMA
14
15config SND_S3C_I2SV2_SOC
16 tristate
17
18config SND_S3C2412_SOC_I2S
19 tristate
20 select SND_S3C_I2SV2_SOC
21 select S3C2410_DMA
22
23config SND_S3C64XX_SOC_I2S
24 tristate
25 select SND_S3C_I2SV2_SOC
26 select S3C64XX_DMA
27
28config SND_S3C64XX_SOC_I2S_V4
29 tristate
30 select SND_S3C_I2SV2_SOC
31 select S3C64XX_DMA
32
33config SND_S3C_SOC_PCM
34 tristate
35
36config SND_S3C_SOC_AC97
37 tristate
38 select SND_SOC_AC97_BUS
39
40config SND_S5P_SOC_SPDIF
41 tristate
42 select SND_SOC_SPDIF
43
44config SND_S3C24XX_SOC_NEO1973_WM8753
45 tristate "SoC I2S Audio support for NEO1973 - WM8753"
46 depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01
47 select SND_S3C24XX_SOC_I2S
48 select SND_SOC_WM8753
49 help
50 Say Y if you want to add support for SoC audio on smdk2440
51 with the WM8753.
52
53config SND_S3C24XX_SOC_NEO1973_GTA02_WM8753
54 tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)"
55 depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA02
56 select SND_S3C24XX_SOC_I2S
57 select SND_SOC_WM8753
58 help
59 This driver provides audio support for the Openmoko Neo FreeRunner
60 smartphone.
61
62config SND_S3C24XX_SOC_JIVE_WM8750
63 tristate "SoC I2S Audio support for Jive"
64 depends on SND_S3C24XX_SOC && MACH_JIVE
65 select SND_SOC_WM8750
66 select SND_S3C2412_SOC_I2S
67 help
68 Sat Y if you want to add support for SoC audio on the Jive.
69
70config SND_S3C64XX_SOC_WM8580
71 tristate "SoC I2S Audio support for WM8580 on SMDK64XX"
72 depends on SND_S3C24XX_SOC && MACH_SMDK6410
73 select SND_SOC_WM8580
74 select SND_S3C64XX_SOC_I2S_V4
75 help
76 Say Y if you want to add support for SoC audio on the SMDK6410.
77
78config SND_S3C24XX_SOC_SMDK2443_WM9710
79 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
80 depends on SND_S3C24XX_SOC && MACH_SMDK2443
81 select S3C2410_DMA
82 select AC97_BUS
83 select SND_SOC_AC97_CODEC
84 select SND_S3C_SOC_AC97
85 help
86 Say Y if you want to add support for SoC audio on smdk2443
87 with the WM9710.
88
89config SND_S3C24XX_SOC_LN2440SBC_ALC650
90 tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
91 depends on SND_S3C24XX_SOC && ARCH_S3C2410
92 select S3C2410_DMA
93 select AC97_BUS
94 select SND_SOC_AC97_CODEC
95 select SND_S3C_SOC_AC97
96 help
97 Say Y if you want to add support for SoC audio on ln2440sbc
98 with the ALC650.
99
100config SND_S3C24XX_SOC_S3C24XX_UDA134X
101 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
102 depends on SND_S3C24XX_SOC && ARCH_S3C2410
103 select SND_S3C24XX_SOC_I2S
104 select SND_SOC_L3
105 select SND_SOC_UDA134X
106
107config SND_S3C24XX_SOC_SIMTEC
108 tristate
109 help
110 Internal node for common S3C24XX/Simtec suppor
111
112config SND_S3C24XX_SOC_SIMTEC_TLV320AIC23
113 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
114 depends on SND_S3C24XX_SOC && ARCH_S3C2410
115 select SND_S3C24XX_SOC_I2S
116 select SND_SOC_TLV320AIC23
117 select SND_S3C24XX_SOC_SIMTEC
118
119config SND_S3C24XX_SOC_SIMTEC_HERMES
120 tristate "SoC I2S Audio support for Simtec Hermes board"
121 depends on SND_S3C24XX_SOC && ARCH_S3C2410
122 select SND_S3C24XX_SOC_I2S
123 select SND_SOC_TLV320AIC3X
124 select SND_S3C24XX_SOC_SIMTEC
125
126config SND_S3C24XX_SOC_RX1950_UDA1380
127 tristate "Audio support for the HP iPAQ RX1950"
128 depends on SND_S3C24XX_SOC && MACH_RX1950
129 select SND_S3C24XX_SOC_I2S
130 select SND_SOC_UDA1380
131 help
132 This driver provides audio support for HP iPAQ RX1950 PDA.
133
134config SND_SOC_SMDK_WM9713
135 tristate "SoC AC97 Audio support for SMDK with WM9713"
136 depends on SND_S3C24XX_SOC && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110)
137 select SND_SOC_WM9713
138 select SND_S3C_SOC_AC97
139 help
140 Sat Y if you want to add support for SoC audio on the SMDK.
141
142config SND_S3C64XX_SOC_SMARTQ
143 tristate "SoC I2S Audio support for SmartQ board"
144 depends on SND_S3C24XX_SOC && MACH_SMARTQ
145 select SND_S3C64XX_SOC_I2S
146 select SND_SOC_WM8750
147
148config SND_S5PC110_SOC_AQUILA_WM8994
149 tristate "SoC I2S Audio support for AQUILA - WM8994"
150 depends on SND_S3C24XX_SOC && MACH_AQUILA
151 select SND_S3C64XX_SOC_I2S_V4
152 select SND_SOC_WM8994
153 help
154 Say Y if you want to add support for SoC audio on aquila
155 with the WM8994.
156
157config SND_S5PV210_SOC_GONI_WM8994
158 tristate "SoC I2S Audio support for GONI - WM8994"
159 depends on SND_S3C24XX_SOC && MACH_GONI
160 select SND_S3C64XX_SOC_I2S_V4
161 select SND_SOC_WM8994
162 help
163 Say Y if you want to add support for SoC audio on goni
164 with the WM8994.
165
166config SND_SOC_SMDK_SPDIF
167 tristate "SoC S/PDIF Audio support for SMDK"
168 depends on SND_S3C24XX_SOC && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210)
169 select SND_S5P_SOC_SPDIF
170 help
171 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile
deleted file mode 100644
index ee8f41d6df99..000000000000
--- a/sound/soc/s3c24xx/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
1# S3c24XX Platform Support
2snd-soc-s3c24xx-objs := s3c-dma.o
3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
5snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o
6snd-soc-s3c-ac97-objs := s3c-ac97.o
7snd-soc-s3c64xx-i2s-v4-objs := s3c64xx-i2s-v4.o
8snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
9snd-soc-s3c-pcm-objs := s3c-pcm.o
10snd-soc-samsung-spdif-objs := spdif.o
11
12obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o
13obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o
14obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o
15obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
16obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o
17obj-$(CONFIG_SND_S3C64XX_SOC_I2S_V4) += snd-soc-s3c64xx-i2s-v4.o
18obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
19obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o
20obj-$(CONFIG_SND_S5P_SOC_SPDIF) += snd-soc-samsung-spdif.o
21
22# S3C24XX Machine Support
23snd-soc-jive-wm8750-objs := jive_wm8750.o
24snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
25snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
26snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
27snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
28snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
29snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
30snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
31snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
32snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o
33snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o
34snd-soc-smdk-wm9713-objs := smdk_wm9713.o
35snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
36snd-soc-aquila-wm8994-objs := aquila_wm8994.o
37snd-soc-goni-wm8994-objs := goni_wm8994.o
38snd-soc-smdk-spdif-objs := smdk_spdif.o
39
40obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o
41obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
42obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
43obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
44obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
45obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
46obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o
47obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
48obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
49obj-$(CONFIG_SND_S3C24XX_SOC_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o
50obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o
51obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o
52obj-$(CONFIG_SND_S3C64XX_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
53obj-$(CONFIG_SND_S5PC110_SOC_AQUILA_WM8994) += snd-soc-aquila-wm8994.o
54obj-$(CONFIG_SND_S5PV210_SOC_GONI_WM8994) += snd-soc-goni-wm8994.o
55obj-$(CONFIG_SND_SOC_SMDK_SPDIF) += snd-soc-smdk-spdif.o
diff --git a/sound/soc/s3c24xx/aquila_wm8994.c b/sound/soc/s3c24xx/aquila_wm8994.c
deleted file mode 100644
index 235d1973f7d0..000000000000
--- a/sound/soc/s3c24xx/aquila_wm8994.c
+++ /dev/null
@@ -1,295 +0,0 @@
1/*
2 * aquila_wm8994.c
3 *
4 * Copyright (C) 2010 Samsung Electronics Co.Ltd
5 * Author: Chanwoo Choi <cw00.choi@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/io.h>
17#include <linux/platform_device.h>
18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20#include <sound/jack.h>
21#include <asm/mach-types.h>
22#include <mach/gpio.h>
23#include <mach/regs-clock.h>
24
25#include <linux/mfd/wm8994/core.h>
26#include <linux/mfd/wm8994/registers.h>
27#include "../codecs/wm8994.h"
28#include "s3c-dma.h"
29#include "s3c64xx-i2s.h"
30
31static struct snd_soc_card aquila;
32static struct platform_device *aquila_snd_device;
33
34/* 3.5 pie jack */
35static struct snd_soc_jack jack;
36
37/* 3.5 pie jack detection DAPM pins */
38static struct snd_soc_jack_pin jack_pins[] = {
39 {
40 .pin = "Headset Mic",
41 .mask = SND_JACK_MICROPHONE,
42 }, {
43 .pin = "Headset Stereophone",
44 .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL |
45 SND_JACK_AVOUT,
46 },
47};
48
49/* 3.5 pie jack detection gpios */
50static struct snd_soc_jack_gpio jack_gpios[] = {
51 {
52 .gpio = S5PV210_GPH0(6),
53 .name = "DET_3.5",
54 .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL |
55 SND_JACK_AVOUT,
56 .debounce_time = 200,
57 },
58};
59
60static const struct snd_soc_dapm_widget aquila_dapm_widgets[] = {
61 SND_SOC_DAPM_SPK("Ext Spk", NULL),
62 SND_SOC_DAPM_SPK("Ext Rcv", NULL),
63 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
64 SND_SOC_DAPM_MIC("Headset Mic", NULL),
65 SND_SOC_DAPM_MIC("Main Mic", NULL),
66 SND_SOC_DAPM_MIC("2nd Mic", NULL),
67 SND_SOC_DAPM_LINE("Radio In", NULL),
68};
69
70static const struct snd_soc_dapm_route aquila_dapm_routes[] = {
71 {"Ext Spk", NULL, "SPKOUTLP"},
72 {"Ext Spk", NULL, "SPKOUTLN"},
73
74 {"Ext Rcv", NULL, "HPOUT2N"},
75 {"Ext Rcv", NULL, "HPOUT2P"},
76
77 {"Headset Stereophone", NULL, "HPOUT1L"},
78 {"Headset Stereophone", NULL, "HPOUT1R"},
79
80 {"IN1RN", NULL, "Headset Mic"},
81 {"IN1RP", NULL, "Headset Mic"},
82
83 {"IN1RN", NULL, "2nd Mic"},
84 {"IN1RP", NULL, "2nd Mic"},
85
86 {"IN1LN", NULL, "Main Mic"},
87 {"IN1LP", NULL, "Main Mic"},
88
89 {"IN2LN", NULL, "Radio In"},
90 {"IN2RN", NULL, "Radio In"},
91};
92
93static int aquila_wm8994_init(struct snd_soc_pcm_runtime *rtd)
94{
95 struct snd_soc_codec *codec = rtd->codec;
96 int ret;
97
98 /* add aquila specific widgets */
99 snd_soc_dapm_new_controls(codec, aquila_dapm_widgets,
100 ARRAY_SIZE(aquila_dapm_widgets));
101
102 /* set up aquila specific audio routes */
103 snd_soc_dapm_add_routes(codec, aquila_dapm_routes,
104 ARRAY_SIZE(aquila_dapm_routes));
105
106 /* set endpoints to not connected */
107 snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN");
108 snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP");
109 snd_soc_dapm_nc_pin(codec, "LINEOUT1N");
110 snd_soc_dapm_nc_pin(codec, "LINEOUT1P");
111 snd_soc_dapm_nc_pin(codec, "LINEOUT2N");
112 snd_soc_dapm_nc_pin(codec, "LINEOUT2P");
113 snd_soc_dapm_nc_pin(codec, "SPKOUTRN");
114 snd_soc_dapm_nc_pin(codec, "SPKOUTRP");
115
116 snd_soc_dapm_sync(codec);
117
118 /* Headset jack detection */
119 ret = snd_soc_jack_new(&aquila, "Headset Jack",
120 SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
121 &jack);
122 if (ret)
123 return ret;
124
125 ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins);
126 if (ret)
127 return ret;
128
129 ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios);
130 if (ret)
131 return ret;
132
133 return 0;
134}
135
136static int aquila_hifi_hw_params(struct snd_pcm_substream *substream,
137 struct snd_pcm_hw_params *params)
138{
139 struct snd_soc_pcm_runtime *rtd = substream->private_data;
140 struct snd_soc_dai *codec_dai = rtd->codec_dai;
141 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
142 unsigned int pll_out = 24000000;
143 int ret = 0;
144
145 /* set the cpu DAI configuration */
146 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
147 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
148 if (ret < 0)
149 return ret;
150
151 /* set the cpu system clock */
152 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
153 0, SND_SOC_CLOCK_IN);
154 if (ret < 0)
155 return ret;
156
157 /* set codec DAI configuration */
158 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
159 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
160 if (ret < 0)
161 return ret;
162
163 /* set the codec FLL */
164 ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out,
165 params_rate(params) * 256);
166 if (ret < 0)
167 return ret;
168
169 /* set the codec system clock */
170 ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
171 params_rate(params) * 256, SND_SOC_CLOCK_IN);
172 if (ret < 0)
173 return ret;
174
175 return 0;
176}
177
178static struct snd_soc_ops aquila_hifi_ops = {
179 .hw_params = aquila_hifi_hw_params,
180};
181
182static int aquila_voice_hw_params(struct snd_pcm_substream *substream,
183 struct snd_pcm_hw_params *params)
184{
185 struct snd_soc_pcm_runtime *rtd = substream->private_data;
186 struct snd_soc_dai *codec_dai = rtd->codec_dai;
187 unsigned int pll_out = 24000000;
188 int ret = 0;
189
190 if (params_rate(params) != 8000)
191 return -EINVAL;
192
193 /* set codec DAI configuration */
194 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J |
195 SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM);
196 if (ret < 0)
197 return ret;
198
199 /* set the codec FLL */
200 ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out,
201 params_rate(params) * 256);
202 if (ret < 0)
203 return ret;
204
205 /* set the codec system clock */
206 ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2,
207 params_rate(params) * 256, SND_SOC_CLOCK_IN);
208 if (ret < 0)
209 return ret;
210
211 return 0;
212}
213
214static struct snd_soc_dai_driver voice_dai = {
215 .name = "aquila-voice-dai",
216 .playback = {
217 .channels_min = 1,
218 .channels_max = 2,
219 .rates = SNDRV_PCM_RATE_8000,
220 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
221 .capture = {
222 .channels_min = 1,
223 .channels_max = 2,
224 .rates = SNDRV_PCM_RATE_8000,
225 .formats = SNDRV_PCM_FMTBIT_S16_LE,},
226};
227
228static struct snd_soc_ops aquila_voice_ops = {
229 .hw_params = aquila_voice_hw_params,
230};
231
232static struct snd_soc_dai_link aquila_dai[] = {
233{
234 .name = "WM8994",
235 .stream_name = "WM8994 HiFi",
236 .cpu_dai_name = "s3c64xx-i2s-v4",
237 .codec_dai_name = "wm8994-hifi",
238 .platform_name = "s3c24xx-pcm-audio",
239 .codec_name = "wm8994-codec.0-0x1a",
240 .init = aquila_wm8994_init,
241 .ops = &aquila_hifi_ops,
242}, {
243 .name = "WM8994 Voice",
244 .stream_name = "Voice",
245 .cpu_dai_name = "aquila-voice-dai",
246 .codec_dai_name = "wm8994-voice",
247 .platform_name = "s3c24xx-pcm-audio",
248 .codec_name = "wm8994-codec.0-0x1a",
249 .ops = &aquila_voice_ops,
250},
251};
252
253static struct snd_soc_card aquila = {
254 .name = "aquila",
255 .dai_link = aquila_dai,
256 .num_links = ARRAY_SIZE(aquila_dai),
257};
258
259static int __init aquila_init(void)
260{
261 int ret;
262
263 if (!machine_is_aquila())
264 return -ENODEV;
265
266 aquila_snd_device = platform_device_alloc("soc-audio", -1);
267 if (!aquila_snd_device)
268 return -ENOMEM;
269
270 /* register voice DAI here */
271 ret = snd_soc_register_dai(&aquila_snd_device->dev, &voice_dai);
272 if (ret)
273 return ret;
274
275 platform_set_drvdata(aquila_snd_device, &aquila);
276 ret = platform_device_add(aquila_snd_device);
277
278 if (ret)
279 platform_device_put(aquila_snd_device);
280
281 return ret;
282}
283
284static void __exit aquila_exit(void)
285{
286 platform_device_unregister(aquila_snd_device);
287}
288
289module_init(aquila_init);
290module_exit(aquila_exit);
291
292/* Module information */
293MODULE_DESCRIPTION("ALSA SoC WM8994 Aquila(S5PC110)");
294MODULE_AUTHOR("Chanwoo Choi <cw00.choi@samsung.com>");
295MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
deleted file mode 100644
index a9628472ebfe..000000000000
--- a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c
+++ /dev/null
@@ -1,230 +0,0 @@
1/* sound/soc/s3c24xx/s3c64xx-i2s-v4.c
2 *
3 * ALSA SoC Audio Layer - S3C64XX I2Sv4 driver
4 * Copyright (c) 2010 Samsung Electronics Co. Ltd
5 * Author: Jaswinder Singh <jassi.brar@samsung.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/clk.h>
13#include <linux/gpio.h>
14#include <linux/io.h>
15
16#include <sound/soc.h>
17#include <sound/pcm_params.h>
18
19#include <plat/audio.h>
20
21#include <mach/map.h>
22#include <mach/dma.h>
23
24#include "s3c-dma.h"
25#include "regs-i2s-v2.h"
26#include "s3c64xx-i2s.h"
27
28static struct s3c2410_dma_client s3c64xx_dma_client_out = {
29 .name = "I2Sv4 PCM Stereo out"
30};
31
32static struct s3c2410_dma_client s3c64xx_dma_client_in = {
33 .name = "I2Sv4 PCM Stereo in"
34};
35
36static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_out;
37static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_in;
38static struct s3c_i2sv2_info s3c64xx_i2sv4;
39
40static int s3c64xx_i2sv4_probe(struct snd_soc_dai *dai)
41{
42 struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4;
43 int ret = 0;
44
45 snd_soc_dai_set_drvdata(dai, i2s);
46
47 ret = s3c_i2sv2_probe(dai, i2s, i2s->base);
48
49 return ret;
50}
51
52static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream,
53 struct snd_pcm_hw_params *params,
54 struct snd_soc_dai *cpu_dai)
55{
56 struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
57 struct s3c_dma_params *dma_data;
58 u32 iismod;
59
60 dev_dbg(cpu_dai->dev, "Entered %s\n", __func__);
61
62 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
63 dma_data = i2s->dma_playback;
64 else
65 dma_data = i2s->dma_capture;
66
67 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
68
69 iismod = readl(i2s->regs + S3C2412_IISMOD);
70 dev_dbg(cpu_dai->dev, "%s: r: IISMOD: %x\n", __func__, iismod);
71
72 iismod &= ~S3C64XX_IISMOD_BLC_MASK;
73 switch (params_format(params)) {
74 case SNDRV_PCM_FORMAT_S8:
75 iismod |= S3C64XX_IISMOD_BLC_8BIT;
76 break;
77 case SNDRV_PCM_FORMAT_S16_LE:
78 break;
79 case SNDRV_PCM_FORMAT_S24_LE:
80 iismod |= S3C64XX_IISMOD_BLC_24BIT;
81 break;
82 }
83
84 writel(iismod, i2s->regs + S3C2412_IISMOD);
85 dev_dbg(cpu_dai->dev, "%s: w: IISMOD: %x\n", __func__, iismod);
86
87 return 0;
88}
89
90static struct snd_soc_dai_ops s3c64xx_i2sv4_dai_ops = {
91 .hw_params = s3c_i2sv4_hw_params,
92};
93
94static struct snd_soc_dai_driver s3c64xx_i2s_v4_dai = {
95 .symmetric_rates = 1,
96 .playback = {
97 .channels_min = 2,
98 .channels_max = 2,
99 .rates = S3C64XX_I2S_RATES,
100 .formats = S3C64XX_I2S_FMTS,
101 },
102 .capture = {
103 .channels_min = 2,
104 .channels_max = 2,
105 .rates = S3C64XX_I2S_RATES,
106 .formats = S3C64XX_I2S_FMTS,
107 },
108 .probe = s3c64xx_i2sv4_probe,
109 .ops = &s3c64xx_i2sv4_dai_ops,
110};
111
112static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev)
113{
114 struct s3c_audio_pdata *i2s_pdata;
115 struct s3c_i2sv2_info *i2s;
116 struct resource *res;
117 int ret;
118
119 i2s = &s3c64xx_i2sv4;
120
121 i2s->feature |= S3C_FEATURE_CDCLKCON;
122
123 i2s->dma_capture = &s3c64xx_i2sv4_pcm_stereo_in;
124 i2s->dma_playback = &s3c64xx_i2sv4_pcm_stereo_out;
125
126 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
127 if (!res) {
128 dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
129 return -ENXIO;
130 }
131 i2s->dma_playback->channel = res->start;
132
133 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
134 if (!res) {
135 dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
136 return -ENXIO;
137 }
138 i2s->dma_capture->channel = res->start;
139
140 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
141 if (!res) {
142 dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
143 return -ENXIO;
144 }
145
146 if (!request_mem_region(res->start, resource_size(res),
147 "s3c64xx-i2s-v4")) {
148 dev_err(&pdev->dev, "Unable to request SFR region\n");
149 return -EBUSY;
150 }
151 i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD;
152 i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD;
153
154 i2s->dma_capture->client = &s3c64xx_dma_client_in;
155 i2s->dma_capture->dma_size = 4;
156 i2s->dma_playback->client = &s3c64xx_dma_client_out;
157 i2s->dma_playback->dma_size = 4;
158
159 i2s->base = res->start;
160
161 i2s_pdata = pdev->dev.platform_data;
162 if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
163 dev_err(&pdev->dev, "Unable to configure gpio\n");
164 return -EINVAL;
165 }
166
167 i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus");
168 if (IS_ERR(i2s->iis_cclk)) {
169 dev_err(&pdev->dev, "failed to get audio-bus\n");
170 ret = PTR_ERR(i2s->iis_cclk);
171 goto err;
172 }
173
174 clk_enable(i2s->iis_cclk);
175
176 ret = s3c_i2sv2_register_dai(&pdev->dev, pdev->id, &s3c64xx_i2s_v4_dai);
177 if (ret != 0)
178 goto err_i2sv2;
179
180 return 0;
181
182err_i2sv2:
183 clk_put(i2s->iis_cclk);
184err:
185 return ret;
186}
187
188static __devexit int s3c64xx_i2sv4_dev_remove(struct platform_device *pdev)
189{
190 struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4;
191 struct resource *res;
192
193 snd_soc_unregister_dai(&pdev->dev);
194 clk_put(i2s->iis_cclk);
195
196 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
197 if (res)
198 release_mem_region(res->start, resource_size(res));
199 else
200 dev_warn(&pdev->dev, "Unable to get I2S SFR address\n");
201
202 return 0;
203}
204
205static struct platform_driver s3c64xx_i2sv4_driver = {
206 .probe = s3c64xx_i2sv4_dev_probe,
207 .remove = s3c64xx_i2sv4_dev_remove,
208 .driver = {
209 .name = "s3c64xx-iis-v4",
210 .owner = THIS_MODULE,
211 },
212};
213
214static int __init s3c64xx_i2sv4_init(void)
215{
216 return platform_driver_register(&s3c64xx_i2sv4_driver);
217}
218module_init(s3c64xx_i2sv4_init);
219
220static void __exit s3c64xx_i2sv4_exit(void)
221{
222 platform_driver_unregister(&s3c64xx_i2sv4_driver);
223}
224module_exit(s3c64xx_i2sv4_exit);
225
226/* Module information */
227MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
228MODULE_DESCRIPTION("S3C64XX I2Sv4 SoC Interface");
229MODULE_LICENSE("GPL");
230MODULE_ALIAS("platform:s3c64xx-iis-v4");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c
deleted file mode 100644
index ae7acb6c4f1d..000000000000
--- a/sound/soc/s3c24xx/s3c64xx-i2s.c
+++ /dev/null
@@ -1,242 +0,0 @@
1/* sound/soc/s3c24xx/s3c64xx-i2s.c
2 *
3 * ALSA SoC Audio Layer - S3C64XX I2S driver
4 *
5 * Copyright 2008 Openmoko, Inc.
6 * Copyright 2008 Simtec Electronics
7 * Ben Dooks <ben@simtec.co.uk>
8 * http://armlinux.simtec.co.uk/
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/clk.h>
17#include <linux/gpio.h>
18#include <linux/io.h>
19#include <linux/slab.h>
20
21#include <sound/soc.h>
22
23#include <plat/audio.h>
24
25#include <mach/map.h>
26#include <mach/dma.h>
27
28#include "s3c-dma.h"
29#include "regs-i2s-v2.h"
30#include "s3c64xx-i2s.h"
31
32/* The value should be set to maximum of the total number
33 * of I2Sv3 controllers that any supported SoC has.
34 */
35#define MAX_I2SV3 2
36
37static struct s3c2410_dma_client s3c64xx_dma_client_out = {
38 .name = "I2S PCM Stereo out"
39};
40
41static struct s3c2410_dma_client s3c64xx_dma_client_in = {
42 .name = "I2S PCM Stereo in"
43};
44
45static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3];
46static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3];
47static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3];
48
49struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai)
50{
51 struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai);
52 u32 iismod = readl(i2s->regs + S3C2412_IISMOD);
53
54 if (iismod & S3C2412_IISMOD_IMS_SYSMUX)
55 return i2s->iis_cclk;
56 else
57 return i2s->iis_pclk;
58}
59EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock);
60
61static int s3c64xx_i2s_probe(struct snd_soc_dai *dai)
62{
63 struct s3c_i2sv2_info *i2s;
64 int ret;
65
66 if (dai->id >= MAX_I2SV3) {
67 dev_err(dai->dev, "id %d out of range\n", dai->id);
68 return -EINVAL;
69 }
70
71 i2s = &s3c64xx_i2s[dai->id];
72 snd_soc_dai_set_drvdata(dai, i2s);
73
74 i2s->iis_cclk = clk_get(dai->dev, "audio-bus");
75 if (IS_ERR(i2s->iis_cclk)) {
76 dev_err(dai->dev, "failed to get audio-bus\n");
77 ret = PTR_ERR(i2s->iis_cclk);
78 goto err;
79 }
80
81 clk_enable(i2s->iis_cclk);
82
83 ret = s3c_i2sv2_probe(dai, i2s, i2s->base);
84 if (ret)
85 goto err_clk;
86
87 return 0;
88
89err_clk:
90 clk_disable(i2s->iis_cclk);
91 clk_put(i2s->iis_cclk);
92err:
93 kfree(i2s);
94 return ret;
95}
96
97static int s3c64xx_i2s_remove(struct snd_soc_dai *dai)
98{
99 struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai);
100
101 clk_disable(i2s->iis_cclk);
102 clk_put(i2s->iis_cclk);
103 kfree(i2s);
104 return 0;
105}
106
107static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops;
108
109static struct snd_soc_dai_driver s3c64xx_i2s_dai[MAX_I2SV3] = {
110{
111 .name = "s3c64xx-i2s-0",
112 .probe = s3c64xx_i2s_probe,
113 .remove = s3c64xx_i2s_remove,
114 .playback = {
115 .channels_min = 2,
116 .channels_max = 2,
117 .rates = S3C64XX_I2S_RATES,
118 .formats = S3C64XX_I2S_FMTS,},
119 .capture = {
120 .channels_min = 2,
121 .channels_max = 2,
122 .rates = S3C64XX_I2S_RATES,
123 .formats = S3C64XX_I2S_FMTS,},
124 .ops = &s3c64xx_i2s_dai_ops,
125 .symmetric_rates = 1,
126}, {
127 .name = "s3c64xx-i2s-1",
128 .probe = s3c64xx_i2s_probe,
129 .remove = s3c64xx_i2s_remove,
130 .playback = {
131 .channels_min = 2,
132 .channels_max = 2,
133 .rates = S3C64XX_I2S_RATES,
134 .formats = S3C64XX_I2S_FMTS,},
135 .capture = {
136 .channels_min = 2,
137 .channels_max = 2,
138 .rates = S3C64XX_I2S_RATES,
139 .formats = S3C64XX_I2S_FMTS,},
140 .ops = &s3c64xx_i2s_dai_ops,
141 .symmetric_rates = 1,
142},};
143
144static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev)
145{
146 struct s3c_audio_pdata *i2s_pdata;
147 struct s3c_i2sv2_info *i2s;
148 struct resource *res;
149 int i, ret;
150
151 if (pdev->id >= MAX_I2SV3) {
152 dev_err(&pdev->dev, "id %d out of range\n", pdev->id);
153 return -EINVAL;
154 }
155
156 i2s = &s3c64xx_i2s[pdev->id];
157
158 i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id];
159 i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id];
160
161 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
162 if (!res) {
163 dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
164 return -ENXIO;
165 }
166 i2s->dma_playback->channel = res->start;
167
168 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
169 if (!res) {
170 dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
171 return -ENXIO;
172 }
173 i2s->dma_capture->channel = res->start;
174
175 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
176 if (!res) {
177 dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
178 return -ENXIO;
179 }
180
181 if (!request_mem_region(res->start, resource_size(res),
182 "s3c64xx-i2s")) {
183 dev_err(&pdev->dev, "Unable to request SFR region\n");
184 return -EBUSY;
185 }
186 i2s->base = res->start;
187
188 i2s_pdata = pdev->dev.platform_data;
189 if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
190 dev_err(&pdev->dev, "Unable to configure gpio\n");
191 return -EINVAL;
192 }
193 i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD;
194 i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD;
195
196 i2s->dma_capture->client = &s3c64xx_dma_client_in;
197 i2s->dma_capture->dma_size = 4;
198 i2s->dma_playback->client = &s3c64xx_dma_client_out;
199 i2s->dma_playback->dma_size = 4;
200
201 for (i = 0; i < ARRAY_SIZE(s3c64xx_i2s_dai); i++) {
202 ret = s3c_i2sv2_register_dai(&pdev->dev, i,
203 &s3c64xx_i2s_dai[i]);
204 if (ret != 0)
205 return ret;
206 }
207
208 return 0;
209}
210
211static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev)
212{
213 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c64xx_i2s_dai));
214 return 0;
215}
216
217static struct platform_driver s3c64xx_iis_driver = {
218 .probe = s3c64xx_iis_dev_probe,
219 .remove = s3c64xx_iis_dev_remove,
220 .driver = {
221 .name = "s3c64xx-iis",
222 .owner = THIS_MODULE,
223 },
224};
225
226static int __init s3c64xx_i2s_init(void)
227{
228 return platform_driver_register(&s3c64xx_iis_driver);
229}
230module_init(s3c64xx_i2s_init);
231
232static void __exit s3c64xx_i2s_exit(void)
233{
234 platform_driver_unregister(&s3c64xx_iis_driver);
235}
236module_exit(s3c64xx_i2s_exit);
237
238/* Module information */
239MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
240MODULE_DESCRIPTION("S3C64XX I2S SoC Interface");
241MODULE_LICENSE("GPL");
242MODULE_ALIAS("platform:s3c64xx-iis");
diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h
deleted file mode 100644
index de4075d26f0c..000000000000
--- a/sound/soc/s3c24xx/s3c64xx-i2s.h
+++ /dev/null
@@ -1,41 +0,0 @@
1/* sound/soc/s3c24xx/s3c64xx-i2s.h
2 *
3 * ALSA SoC Audio Layer - S3C64XX I2S driver
4 *
5 * Copyright 2008 Openmoko, Inc.
6 * Copyright 2008 Simtec Electronics
7 * Ben Dooks <ben@simtec.co.uk>
8 * http://armlinux.simtec.co.uk/
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H
16#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__
17
18struct clk;
19
20#include "s3c-i2s-v2.h"
21
22#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK
23#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK
24#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER
25
26#define S3C64XX_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK
27#define S3C64XX_CLKSRC_MUX S3C_I2SV2_CLKSRC_AUDIOBUS
28#define S3C64XX_CLKSRC_CDCLK S3C_I2SV2_CLKSRC_CDCLK
29
30#define S3C64XX_I2S_RATES \
31 (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \
32 SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
33 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
34
35#define S3C64XX_I2S_FMTS \
36 (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\
37 SNDRV_PCM_FMTBIT_S24_LE)
38
39struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai);
40
41#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */
diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c
index c1244c5bc730..5890e431852f 100644
--- a/sound/soc/s6000/s6105-ipcam.c
+++ b/sound/soc/s6000/s6105-ipcam.c
@@ -18,11 +18,9 @@
18#include <sound/core.h> 18#include <sound/core.h>
19#include <sound/pcm.h> 19#include <sound/pcm.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22 21
23#include <variant/dmac.h> 22#include <variant/dmac.h>
24 23
25#include "../codecs/tlv320aic3x.h"
26#include "s6000-pcm.h" 24#include "s6000-pcm.h"
27#include "s6000-i2s.h" 25#include "s6000-i2s.h"
28 26
@@ -107,6 +105,7 @@ static int output_type_put(struct snd_kcontrol *kcontrol,
107 struct snd_ctl_elem_value *ucontrol) 105 struct snd_ctl_elem_value *ucontrol)
108{ 106{
109 struct snd_soc_codec *codec = kcontrol->private_data; 107 struct snd_soc_codec *codec = kcontrol->private_data;
108 struct snd_soc_dapm_context *dapm = &codec->dapm;
110 unsigned int val = (ucontrol->value.enumerated.item[0] != 0); 109 unsigned int val = (ucontrol->value.enumerated.item[0] != 0);
111 char *differential = "Audio Out Differential"; 110 char *differential = "Audio Out Differential";
112 char *stereo = "Audio Out Stereo"; 111 char *stereo = "Audio Out Stereo";
@@ -114,10 +113,10 @@ static int output_type_put(struct snd_kcontrol *kcontrol,
114 if (kcontrol->private_value == val) 113 if (kcontrol->private_value == val)
115 return 0; 114 return 0;
116 kcontrol->private_value = val; 115 kcontrol->private_value = val;
117 snd_soc_dapm_disable_pin(codec, val ? differential : stereo); 116 snd_soc_dapm_disable_pin(dapm, val ? differential : stereo);
118 snd_soc_dapm_sync(codec); 117 snd_soc_dapm_sync(dapm);
119 snd_soc_dapm_enable_pin(codec, val ? stereo : differential); 118 snd_soc_dapm_enable_pin(dapm, val ? stereo : differential);
120 snd_soc_dapm_sync(codec); 119 snd_soc_dapm_sync(dapm);
121 120
122 return 1; 121 return 1;
123} 122}
@@ -137,35 +136,36 @@ static const struct snd_kcontrol_new audio_out_mux = {
137static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd) 136static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
138{ 137{
139 struct snd_soc_codec *codec = rtd->codec; 138 struct snd_soc_codec *codec = rtd->codec;
139 struct snd_soc_dapm_context *dapm = &codec->dapm;
140 140
141 /* Add s6105 specific widgets */ 141 /* Add s6105 specific widgets */
142 snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, 142 snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets,
143 ARRAY_SIZE(aic3x_dapm_widgets)); 143 ARRAY_SIZE(aic3x_dapm_widgets));
144 144
145 /* Set up s6105 specific audio path audio_map */ 145 /* Set up s6105 specific audio path audio_map */
146 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 146 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
147 147
148 /* not present */ 148 /* not present */
149 snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); 149 snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
150 snd_soc_dapm_nc_pin(codec, "LINE2L"); 150 snd_soc_dapm_nc_pin(dapm, "LINE2L");
151 snd_soc_dapm_nc_pin(codec, "LINE2R"); 151 snd_soc_dapm_nc_pin(dapm, "LINE2R");
152 152
153 /* not connected */ 153 /* not connected */
154 snd_soc_dapm_nc_pin(codec, "MIC3L"); /* LINE2L on this chip */ 154 snd_soc_dapm_nc_pin(dapm, "MIC3L"); /* LINE2L on this chip */
155 snd_soc_dapm_nc_pin(codec, "MIC3R"); /* LINE2R on this chip */ 155 snd_soc_dapm_nc_pin(dapm, "MIC3R"); /* LINE2R on this chip */
156 snd_soc_dapm_nc_pin(codec, "LLOUT"); 156 snd_soc_dapm_nc_pin(dapm, "LLOUT");
157 snd_soc_dapm_nc_pin(codec, "RLOUT"); 157 snd_soc_dapm_nc_pin(dapm, "RLOUT");
158 snd_soc_dapm_nc_pin(codec, "HPRCOM"); 158 snd_soc_dapm_nc_pin(dapm, "HPRCOM");
159 159
160 /* always connected */ 160 /* always connected */
161 snd_soc_dapm_enable_pin(codec, "Audio In"); 161 snd_soc_dapm_enable_pin(dapm, "Audio In");
162 162
163 /* must correspond to audio_out_mux.private_value initializer */ 163 /* must correspond to audio_out_mux.private_value initializer */
164 snd_soc_dapm_disable_pin(codec, "Audio Out Differential"); 164 snd_soc_dapm_disable_pin(dapm, "Audio Out Differential");
165 snd_soc_dapm_sync(codec); 165 snd_soc_dapm_sync(dapm);
166 snd_soc_dapm_enable_pin(codec, "Audio Out Stereo"); 166 snd_soc_dapm_enable_pin(dapm, "Audio Out Stereo");
167 167
168 snd_soc_dapm_sync(codec); 168 snd_soc_dapm_sync(dapm);
169 169
170 snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec)); 170 snd_ctl_add(codec->card->snd_card, snd_ctl_new1(&audio_out_mux, codec));
171 171
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig
new file mode 100644
index 000000000000..a6a6b5fa2f2f
--- /dev/null
+++ b/sound/soc/samsung/Kconfig
@@ -0,0 +1,171 @@
1config SND_SOC_SAMSUNG
2 tristate "ASoC support for Samsung"
3 depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_S5PV310
4 select S3C64XX_DMA if ARCH_S3C64XX
5 select S3C2410_DMA if ARCH_S3C2410
6 help
7 Say Y or M if you want to add support for codecs attached to
8 the Samsung SoCs' Audio interfaces. You will also need to
9 select the audio interfaces to support below.
10
11config SND_S3C24XX_I2S
12 tristate
13 select S3C2410_DMA
14
15config SND_S3C_I2SV2_SOC
16 tristate
17
18config SND_S3C2412_SOC_I2S
19 tristate
20 select SND_S3C_I2SV2_SOC
21 select S3C2410_DMA
22
23config SND_SAMSUNG_PCM
24 tristate
25
26config SND_SAMSUNG_AC97
27 tristate
28 select SND_SOC_AC97_BUS
29
30config SND_SAMSUNG_SPDIF
31 tristate
32 select SND_SOC_SPDIF
33
34config SND_SAMSUNG_I2S
35 tristate
36
37config SND_SOC_SAMSUNG_NEO1973_WM8753
38 tristate "SoC I2S Audio support for NEO1973 - WM8753"
39 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA01
40 select SND_S3C24XX_I2S
41 select SND_SOC_WM8753
42 help
43 Say Y if you want to add support for SoC audio on smdk2440
44 with the WM8753.
45
46config SND_SOC_SAMSUNG_NEO1973_GTA02_WM8753
47 tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)"
48 depends on SND_SOC_SAMSUNG && MACH_NEO1973_GTA02
49 select SND_S3C24XX_I2S
50 select SND_SOC_WM8753
51 help
52 This driver provides audio support for the Openmoko Neo FreeRunner
53 smartphone.
54
55config SND_SOC_SAMSUNG_JIVE_WM8750
56 tristate "SoC I2S Audio support for Jive"
57 depends on SND_SOC_SAMSUNG && MACH_JIVE
58 select SND_SOC_WM8750
59 select SND_S3C2412_SOC_I2S
60 help
61 Sat Y if you want to add support for SoC audio on the Jive.
62
63config SND_SOC_SAMSUNG_SMDK_WM8580
64 tristate "SoC I2S Audio support for WM8580 on SMDK"
65 depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDK6442 || MACH_SMDKV210 || MACH_SMDKC110)
66 select SND_SOC_WM8580
67 select SND_SAMSUNG_I2S
68 help
69 Say Y if you want to add support for SoC audio on the SMDKs.
70
71config SND_SOC_SAMSUNG_SMDK_WM8994
72 tristate "SoC I2S Audio support for WM8994 on SMDK"
73 depends on SND_SOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210)
74 select SND_SOC_WM8994
75 select SND_SAMSUNG_I2S
76 help
77 Say Y if you want to add support for SoC audio on the SMDKs.
78
79config SND_SOC_SAMSUNG_SMDK2443_WM9710
80 tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
81 depends on SND_SOC_SAMSUNG && MACH_SMDK2443
82 select S3C2410_DMA
83 select AC97_BUS
84 select SND_SOC_AC97_CODEC
85 select SND_SAMSUNG_AC97
86 help
87 Say Y if you want to add support for SoC audio on smdk2443
88 with the WM9710.
89
90config SND_SOC_SAMSUNG_LN2440SBC_ALC650
91 tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
92 depends on SND_SOC_SAMSUNG && ARCH_S3C2410
93 select S3C2410_DMA
94 select AC97_BUS
95 select SND_SOC_AC97_CODEC
96 select SND_SAMSUNG_AC97
97 help
98 Say Y if you want to add support for SoC audio on ln2440sbc
99 with the ALC650.
100
101config SND_SOC_SAMSUNG_S3C24XX_UDA134X
102 tristate "SoC I2S Audio support UDA134X wired to a S3C24XX"
103 depends on SND_SOC_SAMSUNG && ARCH_S3C2410
104 select SND_S3C24XX_I2S
105 select SND_SOC_L3
106 select SND_SOC_UDA134X
107
108config SND_SOC_SAMSUNG_SIMTEC
109 tristate
110 help
111 Internal node for common S3C24XX/Simtec suppor
112
113config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23
114 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
115 depends on SND_SOC_SAMSUNG && ARCH_S3C2410
116 select SND_S3C24XX_I2S
117 select SND_SOC_TLV320AIC23
118 select SND_SOC_SAMSUNG_SIMTEC
119
120config SND_SOC_SAMSUNG_SIMTEC_HERMES
121 tristate "SoC I2S Audio support for Simtec Hermes board"
122 depends on SND_SOC_SAMSUNG && ARCH_S3C2410
123 select SND_S3C24XX_I2S
124 select SND_SOC_TLV320AIC3X
125 select SND_SOC_SAMSUNG_SIMTEC
126
127config SND_SOC_SAMSUNG_H1940_UDA1380
128 tristate "Audio support for the HP iPAQ H1940"
129 depends on SND_SOC_SAMSUNG && ARCH_H1940
130 select SND_S3C24XX_I2S
131 select SND_SOC_UDA1380
132 help
133 This driver provides audio support for HP iPAQ h1940 PDA.
134
135config SND_SOC_SAMSUNG_RX1950_UDA1380
136 tristate "Audio support for the HP iPAQ RX1950"
137 depends on SND_SOC_SAMSUNG && MACH_RX1950
138 select SND_S3C24XX_I2S
139 select SND_SOC_UDA1380
140 help
141 This driver provides audio support for HP iPAQ RX1950 PDA.
142
143config SND_SOC_SAMSUNG_SMDK_WM9713
144 tristate "SoC AC97 Audio support for SMDK with WM9713"
145 depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 || MACH_SMDKV310 || MACH_SMDKC210)
146 select SND_SOC_WM9713
147 select SND_SAMSUNG_AC97
148 help
149 Sat Y if you want to add support for SoC audio on the SMDK.
150
151config SND_SOC_SMARTQ
152 tristate "SoC I2S Audio support for SmartQ board"
153 depends on SND_SOC_SAMSUNG && MACH_SMARTQ
154 select SND_SAMSUNG_I2S
155 select SND_SOC_WM8750
156
157config SND_SOC_GONI_AQUILA_WM8994
158 tristate "SoC I2S Audio support for AQUILA/GONI - WM8994"
159 depends on SND_SOC_SAMSUNG && (MACH_GONI || MACH_AQUILA)
160 select SND_SAMSUNG_I2S
161 select SND_SOC_WM8994
162 help
163 Say Y if you want to add support for SoC audio on goni or aquila
164 with the WM8994.
165
166config SND_SOC_SAMSUNG_SMDK_SPDIF
167 tristate "SoC S/PDIF Audio support for SMDK"
168 depends on SND_SOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210)
169 select SND_SAMSUNG_SPDIF
170 help
171 Say Y if you want to add support for SoC S/PDIF audio on the SMDK.
diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile
new file mode 100644
index 000000000000..705d4e8a6724
--- /dev/null
+++ b/sound/soc/samsung/Makefile
@@ -0,0 +1,55 @@
1# S3c24XX Platform Support
2snd-soc-s3c24xx-objs := dma.o
3snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
4snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
5snd-soc-ac97-objs := ac97.o
6snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o
7snd-soc-samsung-spdif-objs := spdif.o
8snd-soc-pcm-objs := pcm.o
9snd-soc-i2s-objs := i2s.o
10
11obj-$(CONFIG_SND_SOC_SAMSUNG) += snd-soc-s3c24xx.o
12obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o
13obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o
14obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
15obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o
16obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o
17obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o
18obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o
19
20# S3C24XX Machine Support
21snd-soc-jive-wm8750-objs := jive_wm8750.o
22snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o
23snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o
24snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o
25snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o
26snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o
27snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o
28snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o
29snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o
30snd-soc-h1940-uda1380-objs := h1940_uda1380.o
31snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o
32snd-soc-smdk-wm8580-objs := smdk_wm8580.o
33snd-soc-smdk-wm8994-objs := smdk_wm8994.o
34snd-soc-smdk-wm9713-objs := smdk_wm9713.o
35snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
36snd-soc-goni-wm8994-objs := goni_wm8994.o
37snd-soc-smdk-spdif-objs := smdk_spdif.o
38
39obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o
40obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
41obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o
42obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o
43obj-$(CONFIG_SND_SOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o
44obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o
45obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o
46obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o
47obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o
48obj-$(CONFIG_SND_SOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o
49obj-$(CONFIG_SND_SOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o
50obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o
51obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994) += snd-soc-smdk-wm8994.o
52obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o
53obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
54obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o
55obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/samsung/ac97.c
index f891eb79b575..4770a9550341 100644
--- a/sound/soc/s3c24xx/s3c-ac97.c
+++ b/sound/soc/samsung/ac97.c
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c-ac97.c 1/* sound/soc/samsung/ac97.c
2 * 2 *
3 * ALSA SoC Audio Layer - S3C AC97 Controller driver 3 * ALSA SoC Audio Layer - S3C AC97 Controller driver
4 * Evolved from s3c2443-ac97.c 4 * Evolved from s3c2443-ac97.c
@@ -24,8 +24,8 @@
24#include <mach/dma.h> 24#include <mach/dma.h>
25#include <plat/audio.h> 25#include <plat/audio.h>
26 26
27#include "s3c-dma.h" 27#include "dma.h"
28#include "s3c-ac97.h" 28#include "ac97.h"
29 29
30#define AC_CMD_ADDR(x) (x << 16) 30#define AC_CMD_ADDR(x) (x << 16)
31#define AC_CMD_DATA(x) (x & 0xffff) 31#define AC_CMD_DATA(x) (x & 0xffff)
@@ -122,7 +122,7 @@ static unsigned short s3c_ac97_read(struct snd_ac97 *ac97,
122 data = (stat & 0xffff); 122 data = (stat & 0xffff);
123 123
124 if (addr != reg) 124 if (addr != reg)
125 pr_err("s3c-ac97: req addr = %02x, rep addr = %02x\n", 125 pr_err("ac97: req addr = %02x, rep addr = %02x\n",
126 reg, addr); 126 reg, addr);
127 127
128 mutex_unlock(&s3c_ac97.lock); 128 mutex_unlock(&s3c_ac97.lock);
@@ -334,7 +334,7 @@ static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = {
334 334
335static struct snd_soc_dai_driver s3c_ac97_dai[] = { 335static struct snd_soc_dai_driver s3c_ac97_dai[] = {
336 [S3C_AC97_DAI_PCM] = { 336 [S3C_AC97_DAI_PCM] = {
337 .name = "s3c-ac97", 337 .name = "samsung-ac97",
338 .ac97_control = 1, 338 .ac97_control = 1,
339 .playback = { 339 .playback = {
340 .stream_name = "AC97 Playback", 340 .stream_name = "AC97 Playback",
@@ -351,7 +351,7 @@ static struct snd_soc_dai_driver s3c_ac97_dai[] = {
351 .ops = &s3c_ac97_dai_ops, 351 .ops = &s3c_ac97_dai_ops,
352 }, 352 },
353 [S3C_AC97_DAI_MIC] = { 353 [S3C_AC97_DAI_MIC] = {
354 .name = "s3c-ac97-mic", 354 .name = "samsung-ac97-mic",
355 .ac97_control = 1, 355 .ac97_control = 1,
356 .capture = { 356 .capture = {
357 .stream_name = "AC97 Mic Capture", 357 .stream_name = "AC97 Mic Capture",
@@ -407,7 +407,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
407 } 407 }
408 408
409 if (!request_mem_region(mem_res->start, 409 if (!request_mem_region(mem_res->start,
410 resource_size(mem_res), "s3c-ac97")) { 410 resource_size(mem_res), "ac97")) {
411 dev_err(&pdev->dev, "Unable to request register region\n"); 411 dev_err(&pdev->dev, "Unable to request register region\n");
412 return -EBUSY; 412 return -EBUSY;
413 } 413 }
@@ -431,7 +431,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
431 431
432 s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); 432 s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97");
433 if (IS_ERR(s3c_ac97.ac97_clk)) { 433 if (IS_ERR(s3c_ac97.ac97_clk)) {
434 dev_err(&pdev->dev, "s3c-ac97 failed to get ac97_clock\n"); 434 dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n");
435 ret = -ENODEV; 435 ret = -ENODEV;
436 goto err2; 436 goto err2;
437 } 437 }
@@ -446,7 +446,7 @@ static __devinit int s3c_ac97_probe(struct platform_device *pdev)
446 ret = request_irq(irq_res->start, s3c_ac97_irq, 446 ret = request_irq(irq_res->start, s3c_ac97_irq,
447 IRQF_DISABLED, "AC97", NULL); 447 IRQF_DISABLED, "AC97", NULL);
448 if (ret < 0) { 448 if (ret < 0) {
449 dev_err(&pdev->dev, "s3c-ac97: interrupt request failed.\n"); 449 dev_err(&pdev->dev, "ac97: interrupt request failed.\n");
450 goto err4; 450 goto err4;
451 } 451 }
452 452
@@ -497,7 +497,7 @@ static struct platform_driver s3c_ac97_driver = {
497 .probe = s3c_ac97_probe, 497 .probe = s3c_ac97_probe,
498 .remove = s3c_ac97_remove, 498 .remove = s3c_ac97_remove,
499 .driver = { 499 .driver = {
500 .name = "s3c-ac97", 500 .name = "samsung-ac97",
501 .owner = THIS_MODULE, 501 .owner = THIS_MODULE,
502 }, 502 },
503}; 503};
@@ -517,4 +517,4 @@ module_exit(s3c_ac97_exit);
517MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>"); 517MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
518MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); 518MODULE_DESCRIPTION("AC97 driver for the Samsung SoC");
519MODULE_LICENSE("GPL"); 519MODULE_LICENSE("GPL");
520MODULE_ALIAS("platform:s3c-ac97"); 520MODULE_ALIAS("platform:samsung-ac97");
diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/samsung/ac97.h
index 5dcedd07fdbb..0d0e1b511457 100644
--- a/sound/soc/s3c24xx/s3c-ac97.h
+++ b/sound/soc/samsung/ac97.h
@@ -1,11 +1,11 @@
1/* sound/soc/s3c24xx/s3c-ac97.h 1/* sound/soc/samsung/ac97.h
2 * 2 *
3 * ALSA SoC Audio Layer - S3C AC97 Controller driver 3 * ALSA SoC Audio Layer - S3C AC97 Controller driver
4 * Evolved from s3c2443-ac97.h 4 * Evolved from s3c2443-ac97.h
5 * 5 *
6 * Copyright (c) 2010 Samsung Electronics Co. Ltd 6 * Copyright (c) 2010 Samsung Electronics Co. Ltd
7 * Author: Jaswinder Singh <jassi.brar@samsung.com> 7 * Author: Jaswinder Singh <jassi.brar@samsung.com>
8 * Credits: Graeme Gregory, Sean Choi 8 * Credits: Graeme Gregory, Sean Choi
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 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 11 * it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/samsung/dma.c
index 243f79bf43bb..21240198c5d6 100644
--- a/sound/soc/s3c24xx/s3c-dma.c
+++ b/sound/soc/samsung/dma.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * s3c-dma.c -- ALSA Soc Audio Layer 2 * dma.c -- ALSA Soc Audio Layer
3 * 3 *
4 * (c) 2006 Wolfson Microelectronics PLC. 4 * (c) 2006 Wolfson Microelectronics PLC.
5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com 5 * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
@@ -30,9 +30,9 @@
30#include <mach/hardware.h> 30#include <mach/hardware.h>
31#include <mach/dma.h> 31#include <mach/dma.h>
32 32
33#include "s3c-dma.h" 33#include "dma.h"
34 34
35static const struct snd_pcm_hardware s3c_dma_hardware = { 35static const struct snd_pcm_hardware dma_hardware = {
36 .info = SNDRV_PCM_INFO_INTERLEAVED | 36 .info = SNDRV_PCM_INFO_INTERLEAVED |
37 SNDRV_PCM_INFO_BLOCK_TRANSFER | 37 SNDRV_PCM_INFO_BLOCK_TRANSFER |
38 SNDRV_PCM_INFO_MMAP | 38 SNDRV_PCM_INFO_MMAP |
@@ -53,7 +53,7 @@ static const struct snd_pcm_hardware s3c_dma_hardware = {
53 .fifo_size = 32, 53 .fifo_size = 32,
54}; 54};
55 55
56struct s3c24xx_runtime_data { 56struct runtime_data {
57 spinlock_t lock; 57 spinlock_t lock;
58 int state; 58 int state;
59 unsigned int dma_loaded; 59 unsigned int dma_loaded;
@@ -65,14 +65,14 @@ struct s3c24xx_runtime_data {
65 struct s3c_dma_params *params; 65 struct s3c_dma_params *params;
66}; 66};
67 67
68/* s3c_dma_enqueue 68/* dma_enqueue
69 * 69 *
70 * place a dma buffer onto the queue for the dma system 70 * place a dma buffer onto the queue for the dma system
71 * to handle. 71 * to handle.
72*/ 72*/
73static void s3c_dma_enqueue(struct snd_pcm_substream *substream) 73static void dma_enqueue(struct snd_pcm_substream *substream)
74{ 74{
75 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 75 struct runtime_data *prtd = substream->runtime->private_data;
76 dma_addr_t pos = prtd->dma_pos; 76 dma_addr_t pos = prtd->dma_pos;
77 unsigned int limit; 77 unsigned int limit;
78 int ret; 78 int ret;
@@ -112,12 +112,12 @@ static void s3c_dma_enqueue(struct snd_pcm_substream *substream)
112 prtd->dma_pos = pos; 112 prtd->dma_pos = pos;
113} 113}
114 114
115static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, 115static void audio_buffdone(struct s3c2410_dma_chan *channel,
116 void *dev_id, int size, 116 void *dev_id, int size,
117 enum s3c2410_dma_buffresult result) 117 enum s3c2410_dma_buffresult result)
118{ 118{
119 struct snd_pcm_substream *substream = dev_id; 119 struct snd_pcm_substream *substream = dev_id;
120 struct s3c24xx_runtime_data *prtd; 120 struct runtime_data *prtd;
121 121
122 pr_debug("Entered %s\n", __func__); 122 pr_debug("Entered %s\n", __func__);
123 123
@@ -132,17 +132,17 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel,
132 spin_lock(&prtd->lock); 132 spin_lock(&prtd->lock);
133 if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { 133 if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) {
134 prtd->dma_loaded--; 134 prtd->dma_loaded--;
135 s3c_dma_enqueue(substream); 135 dma_enqueue(substream);
136 } 136 }
137 137
138 spin_unlock(&prtd->lock); 138 spin_unlock(&prtd->lock);
139} 139}
140 140
141static int s3c_dma_hw_params(struct snd_pcm_substream *substream, 141static int dma_hw_params(struct snd_pcm_substream *substream,
142 struct snd_pcm_hw_params *params) 142 struct snd_pcm_hw_params *params)
143{ 143{
144 struct snd_pcm_runtime *runtime = substream->runtime; 144 struct snd_pcm_runtime *runtime = substream->runtime;
145 struct s3c24xx_runtime_data *prtd = runtime->private_data; 145 struct runtime_data *prtd = runtime->private_data;
146 struct snd_soc_pcm_runtime *rtd = substream->private_data; 146 struct snd_soc_pcm_runtime *rtd = substream->private_data;
147 unsigned long totbytes = params_buffer_bytes(params); 147 unsigned long totbytes = params_buffer_bytes(params);
148 struct s3c_dma_params *dma = 148 struct s3c_dma_params *dma =
@@ -181,7 +181,7 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
181 } 181 }
182 182
183 s3c2410_dma_set_buffdone_fn(prtd->params->channel, 183 s3c2410_dma_set_buffdone_fn(prtd->params->channel,
184 s3c24xx_audio_buffdone); 184 audio_buffdone);
185 185
186 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 186 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
187 187
@@ -199,9 +199,9 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
199 return 0; 199 return 0;
200} 200}
201 201
202static int s3c_dma_hw_free(struct snd_pcm_substream *substream) 202static int dma_hw_free(struct snd_pcm_substream *substream)
203{ 203{
204 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 204 struct runtime_data *prtd = substream->runtime->private_data;
205 205
206 pr_debug("Entered %s\n", __func__); 206 pr_debug("Entered %s\n", __func__);
207 207
@@ -216,9 +216,9 @@ static int s3c_dma_hw_free(struct snd_pcm_substream *substream)
216 return 0; 216 return 0;
217} 217}
218 218
219static int s3c_dma_prepare(struct snd_pcm_substream *substream) 219static int dma_prepare(struct snd_pcm_substream *substream)
220{ 220{
221 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 221 struct runtime_data *prtd = substream->runtime->private_data;
222 int ret = 0; 222 int ret = 0;
223 223
224 pr_debug("Entered %s\n", __func__); 224 pr_debug("Entered %s\n", __func__);
@@ -249,14 +249,14 @@ static int s3c_dma_prepare(struct snd_pcm_substream *substream)
249 prtd->dma_pos = prtd->dma_start; 249 prtd->dma_pos = prtd->dma_start;
250 250
251 /* enqueue dma buffers */ 251 /* enqueue dma buffers */
252 s3c_dma_enqueue(substream); 252 dma_enqueue(substream);
253 253
254 return ret; 254 return ret;
255} 255}
256 256
257static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd) 257static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
258{ 258{
259 struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; 259 struct runtime_data *prtd = substream->runtime->private_data;
260 int ret = 0; 260 int ret = 0;
261 261
262 pr_debug("Entered %s\n", __func__); 262 pr_debug("Entered %s\n", __func__);
@@ -289,10 +289,10 @@ static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd)
289} 289}
290 290
291static snd_pcm_uframes_t 291static snd_pcm_uframes_t
292s3c_dma_pointer(struct snd_pcm_substream *substream) 292dma_pointer(struct snd_pcm_substream *substream)
293{ 293{
294 struct snd_pcm_runtime *runtime = substream->runtime; 294 struct snd_pcm_runtime *runtime = substream->runtime;
295 struct s3c24xx_runtime_data *prtd = runtime->private_data; 295 struct runtime_data *prtd = runtime->private_data;
296 unsigned long res; 296 unsigned long res;
297 dma_addr_t src, dst; 297 dma_addr_t src, dst;
298 298
@@ -324,17 +324,17 @@ s3c_dma_pointer(struct snd_pcm_substream *substream)
324 return bytes_to_frames(substream->runtime, res); 324 return bytes_to_frames(substream->runtime, res);
325} 325}
326 326
327static int s3c_dma_open(struct snd_pcm_substream *substream) 327static int dma_open(struct snd_pcm_substream *substream)
328{ 328{
329 struct snd_pcm_runtime *runtime = substream->runtime; 329 struct snd_pcm_runtime *runtime = substream->runtime;
330 struct s3c24xx_runtime_data *prtd; 330 struct runtime_data *prtd;
331 331
332 pr_debug("Entered %s\n", __func__); 332 pr_debug("Entered %s\n", __func__);
333 333
334 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); 334 snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
335 snd_soc_set_runtime_hwparams(substream, &s3c_dma_hardware); 335 snd_soc_set_runtime_hwparams(substream, &dma_hardware);
336 336
337 prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); 337 prtd = kzalloc(sizeof(struct runtime_data), GFP_KERNEL);
338 if (prtd == NULL) 338 if (prtd == NULL)
339 return -ENOMEM; 339 return -ENOMEM;
340 340
@@ -344,22 +344,22 @@ static int s3c_dma_open(struct snd_pcm_substream *substream)
344 return 0; 344 return 0;
345} 345}
346 346
347static int s3c_dma_close(struct snd_pcm_substream *substream) 347static int dma_close(struct snd_pcm_substream *substream)
348{ 348{
349 struct snd_pcm_runtime *runtime = substream->runtime; 349 struct snd_pcm_runtime *runtime = substream->runtime;
350 struct s3c24xx_runtime_data *prtd = runtime->private_data; 350 struct runtime_data *prtd = runtime->private_data;
351 351
352 pr_debug("Entered %s\n", __func__); 352 pr_debug("Entered %s\n", __func__);
353 353
354 if (!prtd) 354 if (!prtd)
355 pr_debug("s3c_dma_close called with prtd == NULL\n"); 355 pr_debug("dma_close called with prtd == NULL\n");
356 356
357 kfree(prtd); 357 kfree(prtd);
358 358
359 return 0; 359 return 0;
360} 360}
361 361
362static int s3c_dma_mmap(struct snd_pcm_substream *substream, 362static int dma_mmap(struct snd_pcm_substream *substream,
363 struct vm_area_struct *vma) 363 struct vm_area_struct *vma)
364{ 364{
365 struct snd_pcm_runtime *runtime = substream->runtime; 365 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -372,23 +372,23 @@ static int s3c_dma_mmap(struct snd_pcm_substream *substream,
372 runtime->dma_bytes); 372 runtime->dma_bytes);
373} 373}
374 374
375static struct snd_pcm_ops s3c_dma_ops = { 375static struct snd_pcm_ops dma_ops = {
376 .open = s3c_dma_open, 376 .open = dma_open,
377 .close = s3c_dma_close, 377 .close = dma_close,
378 .ioctl = snd_pcm_lib_ioctl, 378 .ioctl = snd_pcm_lib_ioctl,
379 .hw_params = s3c_dma_hw_params, 379 .hw_params = dma_hw_params,
380 .hw_free = s3c_dma_hw_free, 380 .hw_free = dma_hw_free,
381 .prepare = s3c_dma_prepare, 381 .prepare = dma_prepare,
382 .trigger = s3c_dma_trigger, 382 .trigger = dma_trigger,
383 .pointer = s3c_dma_pointer, 383 .pointer = dma_pointer,
384 .mmap = s3c_dma_mmap, 384 .mmap = dma_mmap,
385}; 385};
386 386
387static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 387static int preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
388{ 388{
389 struct snd_pcm_substream *substream = pcm->streams[stream].substream; 389 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
390 struct snd_dma_buffer *buf = &substream->dma_buffer; 390 struct snd_dma_buffer *buf = &substream->dma_buffer;
391 size_t size = s3c_dma_hardware.buffer_bytes_max; 391 size_t size = dma_hardware.buffer_bytes_max;
392 392
393 pr_debug("Entered %s\n", __func__); 393 pr_debug("Entered %s\n", __func__);
394 394
@@ -403,7 +403,7 @@ static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
403 return 0; 403 return 0;
404} 404}
405 405
406static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm) 406static void dma_free_dma_buffers(struct snd_pcm *pcm)
407{ 407{
408 struct snd_pcm_substream *substream; 408 struct snd_pcm_substream *substream;
409 struct snd_dma_buffer *buf; 409 struct snd_dma_buffer *buf;
@@ -426,9 +426,9 @@ static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm)
426 } 426 }
427} 427}
428 428
429static u64 s3c_dma_mask = DMA_BIT_MASK(32); 429static u64 dma_mask = DMA_BIT_MASK(32);
430 430
431static int s3c_dma_new(struct snd_card *card, 431static int dma_new(struct snd_card *card,
432 struct snd_soc_dai *dai, struct snd_pcm *pcm) 432 struct snd_soc_dai *dai, struct snd_pcm *pcm)
433{ 433{
434 int ret = 0; 434 int ret = 0;
@@ -436,67 +436,67 @@ static int s3c_dma_new(struct snd_card *card,
436 pr_debug("Entered %s\n", __func__); 436 pr_debug("Entered %s\n", __func__);
437 437
438 if (!card->dev->dma_mask) 438 if (!card->dev->dma_mask)
439 card->dev->dma_mask = &s3c_dma_mask; 439 card->dev->dma_mask = &dma_mask;
440 if (!card->dev->coherent_dma_mask) 440 if (!card->dev->coherent_dma_mask)
441 card->dev->coherent_dma_mask = 0xffffffff; 441 card->dev->coherent_dma_mask = 0xffffffff;
442 442
443 if (dai->driver->playback.channels_min) { 443 if (dai->driver->playback.channels_min) {
444 ret = s3c_preallocate_dma_buffer(pcm, 444 ret = preallocate_dma_buffer(pcm,
445 SNDRV_PCM_STREAM_PLAYBACK); 445 SNDRV_PCM_STREAM_PLAYBACK);
446 if (ret) 446 if (ret)
447 goto out; 447 goto out;
448 } 448 }
449 449
450 if (dai->driver->capture.channels_min) { 450 if (dai->driver->capture.channels_min) {
451 ret = s3c_preallocate_dma_buffer(pcm, 451 ret = preallocate_dma_buffer(pcm,
452 SNDRV_PCM_STREAM_CAPTURE); 452 SNDRV_PCM_STREAM_CAPTURE);
453 if (ret) 453 if (ret)
454 goto out; 454 goto out;
455 } 455 }
456 out: 456out:
457 return ret; 457 return ret;
458} 458}
459 459
460static struct snd_soc_platform_driver s3c24xx_soc_platform = { 460static struct snd_soc_platform_driver samsung_asoc_platform = {
461 .ops = &s3c_dma_ops, 461 .ops = &dma_ops,
462 .pcm_new = s3c_dma_new, 462 .pcm_new = dma_new,
463 .pcm_free = s3c_dma_free_dma_buffers, 463 .pcm_free = dma_free_dma_buffers,
464}; 464};
465 465
466static int __devinit s3c24xx_soc_platform_probe(struct platform_device *pdev) 466static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev)
467{ 467{
468 return snd_soc_register_platform(&pdev->dev, &s3c24xx_soc_platform); 468 return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform);
469} 469}
470 470
471static int __devexit s3c24xx_soc_platform_remove(struct platform_device *pdev) 471static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev)
472{ 472{
473 snd_soc_unregister_platform(&pdev->dev); 473 snd_soc_unregister_platform(&pdev->dev);
474 return 0; 474 return 0;
475} 475}
476 476
477static struct platform_driver s3c24xx_pcm_driver = { 477static struct platform_driver asoc_dma_driver = {
478 .driver = { 478 .driver = {
479 .name = "s3c24xx-pcm-audio", 479 .name = "samsung-audio",
480 .owner = THIS_MODULE, 480 .owner = THIS_MODULE,
481 }, 481 },
482 482
483 .probe = s3c24xx_soc_platform_probe, 483 .probe = samsung_asoc_platform_probe,
484 .remove = __devexit_p(s3c24xx_soc_platform_remove), 484 .remove = __devexit_p(samsung_asoc_platform_remove),
485}; 485};
486 486
487static int __init snd_s3c24xx_pcm_init(void) 487static int __init samsung_asoc_init(void)
488{ 488{
489 return platform_driver_register(&s3c24xx_pcm_driver); 489 return platform_driver_register(&asoc_dma_driver);
490} 490}
491module_init(snd_s3c24xx_pcm_init); 491module_init(samsung_asoc_init);
492 492
493static void __exit snd_s3c24xx_pcm_exit(void) 493static void __exit samsung_asoc_exit(void)
494{ 494{
495 platform_driver_unregister(&s3c24xx_pcm_driver); 495 platform_driver_unregister(&asoc_dma_driver);
496} 496}
497module_exit(snd_s3c24xx_pcm_exit); 497module_exit(samsung_asoc_exit);
498 498
499MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); 499MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
500MODULE_DESCRIPTION("Samsung S3C Audio DMA module"); 500MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
501MODULE_LICENSE("GPL"); 501MODULE_LICENSE("GPL");
502MODULE_ALIAS("platform:s3c24xx-pcm-audio"); 502MODULE_ALIAS("platform:samsung-audio");
diff --git a/sound/soc/s3c24xx/s3c-dma.h b/sound/soc/samsung/dma.h
index 748c07d7c075..f8cd2b4223af 100644
--- a/sound/soc/s3c24xx/s3c-dma.h
+++ b/sound/soc/samsung/dma.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * s3c-dma.h -- 2 * dma.h --
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the 5 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c
index 694f702cc8e2..34dd9ef1b9c0 100644
--- a/sound/soc/s3c24xx/goni_wm8994.c
+++ b/sound/soc/samsung/goni_wm8994.c
@@ -16,7 +16,6 @@
16#include <linux/io.h> 16#include <linux/io.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/soc-dapm.h>
20#include <sound/jack.h> 19#include <sound/jack.h>
21#include <asm/mach-types.h> 20#include <asm/mach-types.h>
22#include <mach/gpio.h> 21#include <mach/gpio.h>
@@ -25,8 +24,16 @@
25#include <linux/mfd/wm8994/core.h> 24#include <linux/mfd/wm8994/core.h>
26#include <linux/mfd/wm8994/registers.h> 25#include <linux/mfd/wm8994/registers.h>
27#include "../codecs/wm8994.h" 26#include "../codecs/wm8994.h"
28#include "s3c-dma.h" 27#include "dma.h"
29#include "s3c64xx-i2s.h" 28#include "i2s.h"
29
30#define MACHINE_NAME 0
31#define CPU_VOICE_DAI 1
32
33static const char *aquila_str[] = {
34 [MACHINE_NAME] = "aquila",
35 [CPU_VOICE_DAI] = "aquila-voice-dai",
36};
30 37
31static struct snd_soc_card goni; 38static struct snd_soc_card goni;
32static struct platform_device *goni_snd_device; 39static struct platform_device *goni_snd_device;
@@ -97,28 +104,34 @@ static const struct snd_soc_dapm_route goni_dapm_routes[] = {
97static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) 104static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd)
98{ 105{
99 struct snd_soc_codec *codec = rtd->codec; 106 struct snd_soc_codec *codec = rtd->codec;
107 struct snd_soc_dapm_context *dapm = &codec->dapm;
100 int ret; 108 int ret;
101 109
102 /* add goni specific widgets */ 110 /* add goni specific widgets */
103 snd_soc_dapm_new_controls(codec, goni_dapm_widgets, 111 snd_soc_dapm_new_controls(dapm, goni_dapm_widgets,
104 ARRAY_SIZE(goni_dapm_widgets)); 112 ARRAY_SIZE(goni_dapm_widgets));
105 113
106 /* set up goni specific audio routes */ 114 /* set up goni specific audio routes */
107 snd_soc_dapm_add_routes(codec, goni_dapm_routes, 115 snd_soc_dapm_add_routes(dapm, goni_dapm_routes,
108 ARRAY_SIZE(goni_dapm_routes)); 116 ARRAY_SIZE(goni_dapm_routes));
109 117
110 /* set endpoints to not connected */ 118 /* set endpoints to not connected */
111 snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN"); 119 snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
112 snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP"); 120 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
113 snd_soc_dapm_nc_pin(codec, "LINEOUT1N"); 121 snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
114 snd_soc_dapm_nc_pin(codec, "LINEOUT1P"); 122 snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
115 snd_soc_dapm_nc_pin(codec, "LINEOUT2N"); 123 snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
116 snd_soc_dapm_nc_pin(codec, "LINEOUT2P"); 124 snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
117 125
118 snd_soc_dapm_sync(codec); 126 if (machine_is_aquila()) {
127 snd_soc_dapm_nc_pin(dapm, "SPKOUTRN");
128 snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
129 }
130
131 snd_soc_dapm_sync(dapm);
119 132
120 /* Headset jack detection */ 133 /* Headset jack detection */
121 ret = snd_soc_jack_new(&goni, "Headset Jack", 134 ret = snd_soc_jack_new(codec, "Headset Jack",
122 SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, 135 SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT,
123 &jack); 136 &jack);
124 if (ret) 137 if (ret)
@@ -150,12 +163,6 @@ static int goni_hifi_hw_params(struct snd_pcm_substream *substream,
150 if (ret < 0) 163 if (ret < 0)
151 return ret; 164 return ret;
152 165
153 /* set the cpu system clock */
154 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
155 0, SND_SOC_CLOCK_IN);
156 if (ret < 0)
157 return ret;
158
159 /* set codec DAI configuration */ 166 /* set codec DAI configuration */
160 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | 167 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
161 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); 168 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
@@ -236,9 +243,9 @@ static struct snd_soc_dai_link goni_dai[] = {
236{ 243{
237 .name = "WM8994", 244 .name = "WM8994",
238 .stream_name = "WM8994 HiFi", 245 .stream_name = "WM8994 HiFi",
239 .cpu_dai_name = "s3c64xx-i2s-v4", 246 .cpu_dai_name = "samsung-i2s.0",
240 .codec_dai_name = "wm8994-hifi", 247 .codec_dai_name = "wm8994-hifi",
241 .platform_name = "s3c24xx-pcm-audio", 248 .platform_name = "samsung-audio",
242 .codec_name = "wm8994-codec.0-0x1a", 249 .codec_name = "wm8994-codec.0-0x1a",
243 .init = goni_wm8994_init, 250 .init = goni_wm8994_init,
244 .ops = &goni_hifi_ops, 251 .ops = &goni_hifi_ops,
@@ -247,7 +254,7 @@ static struct snd_soc_dai_link goni_dai[] = {
247 .stream_name = "Voice", 254 .stream_name = "Voice",
248 .cpu_dai_name = "goni-voice-dai", 255 .cpu_dai_name = "goni-voice-dai",
249 .codec_dai_name = "wm8994-voice", 256 .codec_dai_name = "wm8994-voice",
250 .platform_name = "s3c24xx-pcm-audio", 257 .platform_name = "samsung-audio",
251 .codec_name = "wm8994-codec.0-0x1a", 258 .codec_name = "wm8994-codec.0-0x1a",
252 .ops = &goni_voice_ops, 259 .ops = &goni_voice_ops,
253}, 260},
@@ -263,7 +270,11 @@ static int __init goni_init(void)
263{ 270{
264 int ret; 271 int ret;
265 272
266 if (!machine_is_goni()) 273 if (machine_is_aquila()) {
274 voice_dai.name = aquila_str[CPU_VOICE_DAI];
275 goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI];
276 goni.name = aquila_str[MACHINE_NAME];
277 } else if (!machine_is_goni())
267 return -ENODEV; 278 return -ENODEV;
268 279
269 goni_snd_device = platform_device_alloc("soc-audio", -1); 280 goni_snd_device = platform_device_alloc("soc-audio", -1);
@@ -272,20 +283,25 @@ static int __init goni_init(void)
272 283
273 /* register voice DAI here */ 284 /* register voice DAI here */
274 ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai); 285 ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai);
275 if (ret) 286 if (ret) {
287 platform_device_put(goni_snd_device);
276 return ret; 288 return ret;
289 }
277 290
278 platform_set_drvdata(goni_snd_device, &goni); 291 platform_set_drvdata(goni_snd_device, &goni);
279 ret = platform_device_add(goni_snd_device); 292 ret = platform_device_add(goni_snd_device);
280 293
281 if (ret) 294 if (ret) {
295 snd_soc_unregister_dai(&goni_snd_device->dev);
282 platform_device_put(goni_snd_device); 296 platform_device_put(goni_snd_device);
297 }
283 298
284 return ret; 299 return ret;
285} 300}
286 301
287static void __exit goni_exit(void) 302static void __exit goni_exit(void)
288{ 303{
304 snd_soc_unregister_dai(&goni_snd_device->dev);
289 platform_device_unregister(goni_snd_device); 305 platform_device_unregister(goni_snd_device);
290} 306}
291 307
diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c
new file mode 100644
index 000000000000..c45f7ce14d61
--- /dev/null
+++ b/sound/soc/samsung/h1940_uda1380.c
@@ -0,0 +1,296 @@
1/*
2 * h1940-uda1380.c -- ALSA Soc Audio Layer
3 *
4 * Copyright (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
5 * Copyright (c) 2010 Vasily Khoruzhick <anarsoul@gmail.com>
6 *
7 * Based on version from Arnaud Patard <arnaud.patard@rtp-net.org>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version.
13 *
14 */
15
16#include <linux/module.h>
17#include <linux/moduleparam.h>
18#include <linux/platform_device.h>
19#include <linux/i2c.h>
20#include <linux/gpio.h>
21
22#include <sound/soc.h>
23#include <sound/uda1380.h>
24#include <sound/jack.h>
25
26#include <plat/regs-iis.h>
27
28#include <mach/h1940-latch.h>
29
30#include <asm/mach-types.h>
31
32#include "dma.h"
33#include "s3c24xx-i2s.h"
34#include "../codecs/uda1380.h"
35
36static unsigned int rates[] = {
37 11025,
38 22050,
39 44100,
40};
41
42static struct snd_pcm_hw_constraint_list hw_rates = {
43 .count = ARRAY_SIZE(rates),
44 .list = rates,
45 .mask = 0,
46};
47
48static struct snd_soc_jack hp_jack;
49
50static struct snd_soc_jack_pin hp_jack_pins[] = {
51 {
52 .pin = "Headphone Jack",
53 .mask = SND_JACK_HEADPHONE,
54 },
55 {
56 .pin = "Speaker",
57 .mask = SND_JACK_HEADPHONE,
58 .invert = 1,
59 },
60};
61
62static struct snd_soc_jack_gpio hp_jack_gpios[] = {
63 {
64 .gpio = S3C2410_GPG(4),
65 .name = "hp-gpio",
66 .report = SND_JACK_HEADPHONE,
67 .invert = 1,
68 .debounce_time = 200,
69 },
70};
71
72static int h1940_startup(struct snd_pcm_substream *substream)
73{
74 struct snd_pcm_runtime *runtime = substream->runtime;
75
76 runtime->hw.rate_min = hw_rates.list[0];
77 runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1];
78 runtime->hw.rates = SNDRV_PCM_RATE_KNOT;
79
80 return snd_pcm_hw_constraint_list(runtime, 0,
81 SNDRV_PCM_HW_PARAM_RATE,
82 &hw_rates);
83}
84
85static int h1940_hw_params(struct snd_pcm_substream *substream,
86 struct snd_pcm_hw_params *params)
87{
88 struct snd_soc_pcm_runtime *rtd = substream->private_data;
89 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
90 struct snd_soc_dai *codec_dai = rtd->codec_dai;
91 int div;
92 int ret;
93 unsigned int rate = params_rate(params);
94
95 switch (rate) {
96 case 11025:
97 case 22050:
98 case 44100:
99 div = s3c24xx_i2s_get_clockrate() / (384 * rate);
100 if (s3c24xx_i2s_get_clockrate() % (384 * rate) > (192 * rate))
101 div++;
102 break;
103 default:
104 dev_err(&rtd->dev, "%s: rate %d is not supported\n",
105 __func__, rate);
106 return -EINVAL;
107 }
108
109 /* set codec DAI configuration */
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 /* set cpu DAI configuration */
116 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
117 SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
118 if (ret < 0)
119 return ret;
120
121 /* select clock source */
122 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_PCLK, rate,
123 SND_SOC_CLOCK_OUT);
124 if (ret < 0)
125 return ret;
126
127 /* set MCLK division for sample rate */
128 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK,
129 S3C2410_IISMOD_384FS);
130 if (ret < 0)
131 return ret;
132
133 /* set BCLK division for sample rate */
134 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK,
135 S3C2410_IISMOD_32FS);
136 if (ret < 0)
137 return ret;
138
139 /* set prescaler division for sample rate */
140 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER,
141 S3C24XX_PRESCALE(div, div));
142 if (ret < 0)
143 return ret;
144
145 return 0;
146}
147
148static struct snd_soc_ops h1940_ops = {
149 .startup = h1940_startup,
150 .hw_params = h1940_hw_params,
151};
152
153static int h1940_spk_power(struct snd_soc_dapm_widget *w,
154 struct snd_kcontrol *kcontrol, int event)
155{
156 if (SND_SOC_DAPM_EVENT_ON(event))
157 gpio_set_value(H1940_LATCH_AUDIO_POWER, 1);
158 else
159 gpio_set_value(H1940_LATCH_AUDIO_POWER, 0);
160
161 return 0;
162}
163
164/* h1940 machine dapm widgets */
165static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = {
166 SND_SOC_DAPM_HP("Headphone Jack", NULL),
167 SND_SOC_DAPM_MIC("Mic Jack", NULL),
168 SND_SOC_DAPM_SPK("Speaker", h1940_spk_power),
169};
170
171/* h1940 machine audio_map */
172static const struct snd_soc_dapm_route audio_map[] = {
173 /* headphone connected to VOUTLHP, VOUTRHP */
174 {"Headphone Jack", NULL, "VOUTLHP"},
175 {"Headphone Jack", NULL, "VOUTRHP"},
176
177 /* ext speaker connected to VOUTL, VOUTR */
178 {"Speaker", NULL, "VOUTL"},
179 {"Speaker", NULL, "VOUTR"},
180
181 /* mic is connected to VINM */
182 {"VINM", NULL, "Mic Jack"},
183};
184
185static struct platform_device *s3c24xx_snd_device;
186
187static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd)
188{
189 struct snd_soc_codec *codec = rtd->codec;
190 struct snd_soc_dapm_context *dapm = &codec->dapm;
191 int err;
192
193 /* Add h1940 specific widgets */
194 err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
195 ARRAY_SIZE(uda1380_dapm_widgets));
196 if (err)
197 return err;
198
199 /* Set up h1940 specific audio path audio_mapnects */
200 err = snd_soc_dapm_add_routes(dapm, audio_map,
201 ARRAY_SIZE(audio_map));
202 if (err)
203 return err;
204
205 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
206 snd_soc_dapm_enable_pin(dapm, "Speaker");
207 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
208
209 snd_soc_dapm_sync(dapm);
210
211 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
212 &hp_jack);
213
214 snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins),
215 hp_jack_pins);
216
217 snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
218 hp_jack_gpios);
219
220 return 0;
221}
222
223/* s3c24xx digital audio interface glue - connects codec <--> CPU */
224static struct snd_soc_dai_link h1940_uda1380_dai[] = {
225 {
226 .name = "uda1380",
227 .stream_name = "UDA1380 Duplex",
228 .cpu_dai_name = "s3c24xx-iis",
229 .codec_dai_name = "uda1380-hifi",
230 .init = h1940_uda1380_init,
231 .platform_name = "samsung-audio",
232 .codec_name = "uda1380-codec.0-001a",
233 .ops = &h1940_ops,
234 },
235};
236
237static struct snd_soc_card h1940_asoc = {
238 .name = "h1940",
239 .dai_link = h1940_uda1380_dai,
240 .num_links = ARRAY_SIZE(h1940_uda1380_dai),
241};
242
243static int __init h1940_init(void)
244{
245 int ret;
246
247 if (!machine_is_h1940())
248 return -ENODEV;
249
250 /* configure some gpios */
251 ret = gpio_request(H1940_LATCH_AUDIO_POWER, "speaker-power");
252 if (ret)
253 goto err_out;
254
255 ret = gpio_direction_output(H1940_LATCH_AUDIO_POWER, 0);
256 if (ret)
257 goto err_gpio;
258
259 s3c24xx_snd_device = platform_device_alloc("soc-audio", -1);
260 if (!s3c24xx_snd_device) {
261 ret = -ENOMEM;
262 goto err_gpio;
263 }
264
265 platform_set_drvdata(s3c24xx_snd_device, &h1940_asoc);
266 ret = platform_device_add(s3c24xx_snd_device);
267
268 if (ret)
269 goto err_plat;
270
271 return 0;
272
273err_plat:
274 platform_device_put(s3c24xx_snd_device);
275err_gpio:
276 gpio_free(H1940_LATCH_AUDIO_POWER);
277
278err_out:
279 return ret;
280}
281
282static void __exit h1940_exit(void)
283{
284 platform_device_unregister(s3c24xx_snd_device);
285 snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios),
286 hp_jack_gpios);
287 gpio_free(H1940_LATCH_AUDIO_POWER);
288}
289
290module_init(h1940_init);
291module_exit(h1940_exit);
292
293/* Module information */
294MODULE_AUTHOR("Arnaud Patard, Vasily Khoruzhick");
295MODULE_DESCRIPTION("ALSA SoC H1940");
296MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c
new file mode 100644
index 000000000000..d00ac3a7102c
--- /dev/null
+++ b/sound/soc/samsung/i2s.c
@@ -0,0 +1,1258 @@
1/* sound/soc/samsung/i2s.c
2 *
3 * ALSA SoC Audio Layer - Samsung I2S Controller driver
4 *
5 * Copyright (c) 2010 Samsung Electronics Co. Ltd.
6 * Jaswinder Singh <jassi.brar@samsung.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/delay.h>
14#include <linux/slab.h>
15#include <linux/clk.h>
16#include <linux/io.h>
17
18#include <sound/pcm.h>
19#include <sound/pcm_params.h>
20#include <sound/soc.h>
21
22#include <plat/audio.h>
23
24#include "dma.h"
25#include "i2s.h"
26
27#define I2SCON 0x0
28#define I2SMOD 0x4
29#define I2SFIC 0x8
30#define I2SPSR 0xc
31#define I2STXD 0x10
32#define I2SRXD 0x14
33#define I2SFICS 0x18
34#define I2STXDS 0x1c
35
36#define CON_RSTCLR (1 << 31)
37#define CON_FRXOFSTATUS (1 << 26)
38#define CON_FRXORINTEN (1 << 25)
39#define CON_FTXSURSTAT (1 << 24)
40#define CON_FTXSURINTEN (1 << 23)
41#define CON_TXSDMA_PAUSE (1 << 20)
42#define CON_TXSDMA_ACTIVE (1 << 18)
43
44#define CON_FTXURSTATUS (1 << 17)
45#define CON_FTXURINTEN (1 << 16)
46#define CON_TXFIFO2_EMPTY (1 << 15)
47#define CON_TXFIFO1_EMPTY (1 << 14)
48#define CON_TXFIFO2_FULL (1 << 13)
49#define CON_TXFIFO1_FULL (1 << 12)
50
51#define CON_LRINDEX (1 << 11)
52#define CON_TXFIFO_EMPTY (1 << 10)
53#define CON_RXFIFO_EMPTY (1 << 9)
54#define CON_TXFIFO_FULL (1 << 8)
55#define CON_RXFIFO_FULL (1 << 7)
56#define CON_TXDMA_PAUSE (1 << 6)
57#define CON_RXDMA_PAUSE (1 << 5)
58#define CON_TXCH_PAUSE (1 << 4)
59#define CON_RXCH_PAUSE (1 << 3)
60#define CON_TXDMA_ACTIVE (1 << 2)
61#define CON_RXDMA_ACTIVE (1 << 1)
62#define CON_ACTIVE (1 << 0)
63
64#define MOD_OPCLK_CDCLK_OUT (0 << 30)
65#define MOD_OPCLK_CDCLK_IN (1 << 30)
66#define MOD_OPCLK_BCLK_OUT (2 << 30)
67#define MOD_OPCLK_PCLK (3 << 30)
68#define MOD_OPCLK_MASK (3 << 30)
69#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */
70
71#define MOD_BLCS_SHIFT 26
72#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT)
73#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT)
74#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT)
75#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT)
76#define MOD_BLCP_SHIFT 24
77#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT)
78#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT)
79#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT)
80#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT)
81
82#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */
83#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */
84#define MOD_C1DD_HHALF (1 << 19)
85#define MOD_C1DD_LHALF (1 << 18)
86#define MOD_DC2_EN (1 << 17)
87#define MOD_DC1_EN (1 << 16)
88#define MOD_BLC_16BIT (0 << 13)
89#define MOD_BLC_8BIT (1 << 13)
90#define MOD_BLC_24BIT (2 << 13)
91#define MOD_BLC_MASK (3 << 13)
92
93#define MOD_IMS_SYSMUX (1 << 10)
94#define MOD_SLAVE (1 << 11)
95#define MOD_TXONLY (0 << 8)
96#define MOD_RXONLY (1 << 8)
97#define MOD_TXRX (2 << 8)
98#define MOD_MASK (3 << 8)
99#define MOD_LR_LLOW (0 << 7)
100#define MOD_LR_RLOW (1 << 7)
101#define MOD_SDF_IIS (0 << 5)
102#define MOD_SDF_MSB (1 << 5)
103#define MOD_SDF_LSB (2 << 5)
104#define MOD_SDF_MASK (3 << 5)
105#define MOD_RCLK_256FS (0 << 3)
106#define MOD_RCLK_512FS (1 << 3)
107#define MOD_RCLK_384FS (2 << 3)
108#define MOD_RCLK_768FS (3 << 3)
109#define MOD_RCLK_MASK (3 << 3)
110#define MOD_BCLK_32FS (0 << 1)
111#define MOD_BCLK_48FS (1 << 1)
112#define MOD_BCLK_16FS (2 << 1)
113#define MOD_BCLK_24FS (3 << 1)
114#define MOD_BCLK_MASK (3 << 1)
115#define MOD_8BIT (1 << 0)
116
117#define MOD_CDCLKCON (1 << 12)
118
119#define PSR_PSREN (1 << 15)
120
121#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf)
122#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf)
123
124#define FIC_TXFLUSH (1 << 15)
125#define FIC_RXFLUSH (1 << 7)
126#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf)
127#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf)
128#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f)
129
130#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
131
132struct i2s_dai {
133 /* Platform device for this DAI */
134 struct platform_device *pdev;
135 /* IOREMAP'd SFRs */
136 void __iomem *addr;
137 /* Physical base address of SFRs */
138 u32 base;
139 /* Rate of RCLK source clock */
140 unsigned long rclk_srcrate;
141 /* Frame Clock */
142 unsigned frmclk;
143 /*
144 * Specifically requested RCLK,BCLK by MACHINE Driver.
145 * 0 indicates CPU driver is free to choose any value.
146 */
147 unsigned rfs, bfs;
148 /* I2S Controller's core clock */
149 struct clk *clk;
150 /* Clock for generating I2S signals */
151 struct clk *op_clk;
152 /* Array of clock names for op_clk */
153 const char **src_clk;
154 /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */
155 struct i2s_dai *pri_dai;
156 /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */
157 struct i2s_dai *sec_dai;
158#define DAI_OPENED (1 << 0) /* Dai is opened */
159#define DAI_MANAGER (1 << 1) /* Dai is the manager */
160 unsigned mode;
161 /* Driver for this DAI */
162 struct snd_soc_dai_driver i2s_dai_drv;
163 /* DMA parameters */
164 struct s3c_dma_params dma_playback;
165 struct s3c_dma_params dma_capture;
166 u32 quirks;
167 u32 suspend_i2smod;
168 u32 suspend_i2scon;
169 u32 suspend_i2spsr;
170};
171
172/* Lock for cross i/f checks */
173static DEFINE_SPINLOCK(lock);
174
175/* If this is the 'overlay' stereo DAI */
176static inline bool is_secondary(struct i2s_dai *i2s)
177{
178 return i2s->pri_dai ? true : false;
179}
180
181/* If operating in SoC-Slave mode */
182static inline bool is_slave(struct i2s_dai *i2s)
183{
184 return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false;
185}
186
187/* If this interface of the controller is transmitting data */
188static inline bool tx_active(struct i2s_dai *i2s)
189{
190 u32 active;
191
192 if (!i2s)
193 return false;
194
195 active = readl(i2s->addr + I2SMOD);
196
197 if (is_secondary(i2s))
198 active &= CON_TXSDMA_ACTIVE;
199 else
200 active &= CON_TXDMA_ACTIVE;
201
202 return active ? true : false;
203}
204
205/* If the other interface of the controller is transmitting data */
206static inline bool other_tx_active(struct i2s_dai *i2s)
207{
208 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
209
210 return tx_active(other);
211}
212
213/* If any interface of the controller is transmitting data */
214static inline bool any_tx_active(struct i2s_dai *i2s)
215{
216 return tx_active(i2s) || other_tx_active(i2s);
217}
218
219/* If this interface of the controller is receiving data */
220static inline bool rx_active(struct i2s_dai *i2s)
221{
222 u32 active;
223
224 if (!i2s)
225 return false;
226
227 active = readl(i2s->addr + I2SMOD) & CON_RXDMA_ACTIVE;
228
229 return active ? true : false;
230}
231
232/* If the other interface of the controller is receiving data */
233static inline bool other_rx_active(struct i2s_dai *i2s)
234{
235 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
236
237 return rx_active(other);
238}
239
240/* If any interface of the controller is receiving data */
241static inline bool any_rx_active(struct i2s_dai *i2s)
242{
243 return rx_active(i2s) || other_rx_active(i2s);
244}
245
246/* If the other DAI is transmitting or receiving data */
247static inline bool other_active(struct i2s_dai *i2s)
248{
249 return other_rx_active(i2s) || other_tx_active(i2s);
250}
251
252/* If this DAI is transmitting or receiving data */
253static inline bool this_active(struct i2s_dai *i2s)
254{
255 return tx_active(i2s) || rx_active(i2s);
256}
257
258/* If the controller is active anyway */
259static inline bool any_active(struct i2s_dai *i2s)
260{
261 return this_active(i2s) || other_active(i2s);
262}
263
264static inline struct i2s_dai *to_info(struct snd_soc_dai *dai)
265{
266 return snd_soc_dai_get_drvdata(dai);
267}
268
269static inline bool is_opened(struct i2s_dai *i2s)
270{
271 if (i2s && (i2s->mode & DAI_OPENED))
272 return true;
273 else
274 return false;
275}
276
277static inline bool is_manager(struct i2s_dai *i2s)
278{
279 if (is_opened(i2s) && (i2s->mode & DAI_MANAGER))
280 return true;
281 else
282 return false;
283}
284
285/* Read RCLK of I2S (in multiples of LRCLK) */
286static inline unsigned get_rfs(struct i2s_dai *i2s)
287{
288 u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3;
289
290 switch (rfs) {
291 case 3: return 768;
292 case 2: return 384;
293 case 1: return 512;
294 default: return 256;
295 }
296}
297
298/* Write RCLK of I2S (in multiples of LRCLK) */
299static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs)
300{
301 u32 mod = readl(i2s->addr + I2SMOD);
302
303 mod &= ~MOD_RCLK_MASK;
304
305 switch (rfs) {
306 case 768:
307 mod |= MOD_RCLK_768FS;
308 break;
309 case 512:
310 mod |= MOD_RCLK_512FS;
311 break;
312 case 384:
313 mod |= MOD_RCLK_384FS;
314 break;
315 default:
316 mod |= MOD_RCLK_256FS;
317 break;
318 }
319
320 writel(mod, i2s->addr + I2SMOD);
321}
322
323/* Read Bit-Clock of I2S (in multiples of LRCLK) */
324static inline unsigned get_bfs(struct i2s_dai *i2s)
325{
326 u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3;
327
328 switch (bfs) {
329 case 3: return 24;
330 case 2: return 16;
331 case 1: return 48;
332 default: return 32;
333 }
334}
335
336/* Write Bit-Clock of I2S (in multiples of LRCLK) */
337static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs)
338{
339 u32 mod = readl(i2s->addr + I2SMOD);
340
341 mod &= ~MOD_BCLK_MASK;
342
343 switch (bfs) {
344 case 48:
345 mod |= MOD_BCLK_48FS;
346 break;
347 case 32:
348 mod |= MOD_BCLK_32FS;
349 break;
350 case 24:
351 mod |= MOD_BCLK_24FS;
352 break;
353 case 16:
354 mod |= MOD_BCLK_16FS;
355 break;
356 default:
357 dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n");
358 return;
359 }
360
361 writel(mod, i2s->addr + I2SMOD);
362}
363
364/* Sample-Size */
365static inline int get_blc(struct i2s_dai *i2s)
366{
367 int blc = readl(i2s->addr + I2SMOD);
368
369 blc = (blc >> 13) & 0x3;
370
371 switch (blc) {
372 case 2: return 24;
373 case 1: return 8;
374 default: return 16;
375 }
376}
377
378/* TX Channel Control */
379static void i2s_txctrl(struct i2s_dai *i2s, int on)
380{
381 void __iomem *addr = i2s->addr;
382 u32 con = readl(addr + I2SCON);
383 u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
384
385 if (on) {
386 con |= CON_ACTIVE;
387 con &= ~CON_TXCH_PAUSE;
388
389 if (is_secondary(i2s)) {
390 con |= CON_TXSDMA_ACTIVE;
391 con &= ~CON_TXSDMA_PAUSE;
392 } else {
393 con |= CON_TXDMA_ACTIVE;
394 con &= ~CON_TXDMA_PAUSE;
395 }
396
397 if (any_rx_active(i2s))
398 mod |= MOD_TXRX;
399 else
400 mod |= MOD_TXONLY;
401 } else {
402 if (is_secondary(i2s)) {
403 con |= CON_TXSDMA_PAUSE;
404 con &= ~CON_TXSDMA_ACTIVE;
405 } else {
406 con |= CON_TXDMA_PAUSE;
407 con &= ~CON_TXDMA_ACTIVE;
408 }
409
410 if (other_tx_active(i2s)) {
411 writel(con, addr + I2SCON);
412 return;
413 }
414
415 con |= CON_TXCH_PAUSE;
416
417 if (any_rx_active(i2s))
418 mod |= MOD_RXONLY;
419 else
420 con &= ~CON_ACTIVE;
421 }
422
423 writel(mod, addr + I2SMOD);
424 writel(con, addr + I2SCON);
425}
426
427/* RX Channel Control */
428static void i2s_rxctrl(struct i2s_dai *i2s, int on)
429{
430 void __iomem *addr = i2s->addr;
431 u32 con = readl(addr + I2SCON);
432 u32 mod = readl(addr + I2SMOD) & ~MOD_MASK;
433
434 if (on) {
435 con |= CON_RXDMA_ACTIVE | CON_ACTIVE;
436 con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE);
437
438 if (any_tx_active(i2s))
439 mod |= MOD_TXRX;
440 else
441 mod |= MOD_RXONLY;
442 } else {
443 con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE;
444 con &= ~CON_RXDMA_ACTIVE;
445
446 if (any_tx_active(i2s))
447 mod |= MOD_TXONLY;
448 else
449 con &= ~CON_ACTIVE;
450 }
451
452 writel(mod, addr + I2SMOD);
453 writel(con, addr + I2SCON);
454}
455
456/* Flush FIFO of an interface */
457static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush)
458{
459 void __iomem *fic;
460 u32 val;
461
462 if (!i2s)
463 return;
464
465 if (is_secondary(i2s))
466 fic = i2s->addr + I2SFICS;
467 else
468 fic = i2s->addr + I2SFIC;
469
470 /* Flush the FIFO */
471 writel(readl(fic) | flush, fic);
472
473 /* Be patient */
474 val = msecs_to_loops(1) / 1000; /* 1 usec */
475 while (--val)
476 cpu_relax();
477
478 writel(readl(fic) & ~flush, fic);
479}
480
481static int i2s_set_sysclk(struct snd_soc_dai *dai,
482 int clk_id, unsigned int rfs, int dir)
483{
484 struct i2s_dai *i2s = to_info(dai);
485 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
486 u32 mod = readl(i2s->addr + I2SMOD);
487
488 switch (clk_id) {
489 case SAMSUNG_I2S_CDCLK:
490 /* Shouldn't matter in GATING(CLOCK_IN) mode */
491 if (dir == SND_SOC_CLOCK_IN)
492 rfs = 0;
493
494 if ((rfs && other->rfs && (other->rfs != rfs)) ||
495 (any_active(i2s) &&
496 (((dir == SND_SOC_CLOCK_IN)
497 && !(mod & MOD_CDCLKCON)) ||
498 ((dir == SND_SOC_CLOCK_OUT)
499 && (mod & MOD_CDCLKCON))))) {
500 dev_err(&i2s->pdev->dev,
501 "%s:%d Other DAI busy\n", __func__, __LINE__);
502 return -EAGAIN;
503 }
504
505 if (dir == SND_SOC_CLOCK_IN)
506 mod |= MOD_CDCLKCON;
507 else
508 mod &= ~MOD_CDCLKCON;
509
510 i2s->rfs = rfs;
511 break;
512
513 case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */
514 case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */
515 if ((i2s->quirks & QUIRK_NO_MUXPSR)
516 || (clk_id == SAMSUNG_I2S_RCLKSRC_0))
517 clk_id = 0;
518 else
519 clk_id = 1;
520
521 if (!any_active(i2s)) {
522 if (i2s->op_clk) {
523 if ((clk_id && !(mod & MOD_IMS_SYSMUX)) ||
524 (!clk_id && (mod & MOD_IMS_SYSMUX))) {
525 clk_disable(i2s->op_clk);
526 clk_put(i2s->op_clk);
527 } else {
528 i2s->rclk_srcrate =
529 clk_get_rate(i2s->op_clk);
530 return 0;
531 }
532 }
533
534 i2s->op_clk = clk_get(&i2s->pdev->dev,
535 i2s->src_clk[clk_id]);
536 clk_enable(i2s->op_clk);
537 i2s->rclk_srcrate = clk_get_rate(i2s->op_clk);
538
539 /* Over-ride the other's */
540 if (other) {
541 other->op_clk = i2s->op_clk;
542 other->rclk_srcrate = i2s->rclk_srcrate;
543 }
544 } else if ((!clk_id && (mod & MOD_IMS_SYSMUX))
545 || (clk_id && !(mod & MOD_IMS_SYSMUX))) {
546 dev_err(&i2s->pdev->dev,
547 "%s:%d Other DAI busy\n", __func__, __LINE__);
548 return -EAGAIN;
549 } else {
550 /* Call can't be on the active DAI */
551 i2s->op_clk = other->op_clk;
552 i2s->rclk_srcrate = other->rclk_srcrate;
553 return 0;
554 }
555
556 if (clk_id == 0)
557 mod &= ~MOD_IMS_SYSMUX;
558 else
559 mod |= MOD_IMS_SYSMUX;
560 break;
561
562 default:
563 dev_err(&i2s->pdev->dev, "We don't serve that!\n");
564 return -EINVAL;
565 }
566
567 writel(mod, i2s->addr + I2SMOD);
568
569 return 0;
570}
571
572static int i2s_set_fmt(struct snd_soc_dai *dai,
573 unsigned int fmt)
574{
575 struct i2s_dai *i2s = to_info(dai);
576 u32 mod = readl(i2s->addr + I2SMOD);
577 u32 tmp = 0;
578
579 /* Format is priority */
580 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
581 case SND_SOC_DAIFMT_RIGHT_J:
582 tmp |= MOD_LR_RLOW;
583 tmp |= MOD_SDF_MSB;
584 break;
585 case SND_SOC_DAIFMT_LEFT_J:
586 tmp |= MOD_LR_RLOW;
587 tmp |= MOD_SDF_LSB;
588 break;
589 case SND_SOC_DAIFMT_I2S:
590 tmp |= MOD_SDF_IIS;
591 break;
592 default:
593 dev_err(&i2s->pdev->dev, "Format not supported\n");
594 return -EINVAL;
595 }
596
597 /*
598 * INV flag is relative to the FORMAT flag - if set it simply
599 * flips the polarity specified by the Standard
600 */
601 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
602 case SND_SOC_DAIFMT_NB_NF:
603 break;
604 case SND_SOC_DAIFMT_NB_IF:
605 if (tmp & MOD_LR_RLOW)
606 tmp &= ~MOD_LR_RLOW;
607 else
608 tmp |= MOD_LR_RLOW;
609 break;
610 default:
611 dev_err(&i2s->pdev->dev, "Polarity not supported\n");
612 return -EINVAL;
613 }
614
615 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
616 case SND_SOC_DAIFMT_CBM_CFM:
617 tmp |= MOD_SLAVE;
618 break;
619 case SND_SOC_DAIFMT_CBS_CFS:
620 /* Set default source clock in Master mode */
621 if (i2s->rclk_srcrate == 0)
622 i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0,
623 0, SND_SOC_CLOCK_IN);
624 break;
625 default:
626 dev_err(&i2s->pdev->dev, "master/slave format not supported\n");
627 return -EINVAL;
628 }
629
630 if (any_active(i2s) &&
631 ((mod & (MOD_SDF_MASK | MOD_LR_RLOW
632 | MOD_SLAVE)) != tmp)) {
633 dev_err(&i2s->pdev->dev,
634 "%s:%d Other DAI busy\n", __func__, __LINE__);
635 return -EAGAIN;
636 }
637
638 mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE);
639 mod |= tmp;
640 writel(mod, i2s->addr + I2SMOD);
641
642 return 0;
643}
644
645static int i2s_hw_params(struct snd_pcm_substream *substream,
646 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
647{
648 struct i2s_dai *i2s = to_info(dai);
649 u32 mod = readl(i2s->addr + I2SMOD);
650
651 if (!is_secondary(i2s))
652 mod &= ~(MOD_DC2_EN | MOD_DC1_EN);
653
654 switch (params_channels(params)) {
655 case 6:
656 mod |= MOD_DC2_EN;
657 case 4:
658 mod |= MOD_DC1_EN;
659 break;
660 case 2:
661 break;
662 default:
663 dev_err(&i2s->pdev->dev, "%d channels not supported\n",
664 params_channels(params));
665 return -EINVAL;
666 }
667
668 if (is_secondary(i2s))
669 mod &= ~MOD_BLCS_MASK;
670 else
671 mod &= ~MOD_BLCP_MASK;
672
673 if (is_manager(i2s))
674 mod &= ~MOD_BLC_MASK;
675
676 switch (params_format(params)) {
677 case SNDRV_PCM_FORMAT_S8:
678 if (is_secondary(i2s))
679 mod |= MOD_BLCS_8BIT;
680 else
681 mod |= MOD_BLCP_8BIT;
682 if (is_manager(i2s))
683 mod |= MOD_BLC_8BIT;
684 break;
685 case SNDRV_PCM_FORMAT_S16_LE:
686 if (is_secondary(i2s))
687 mod |= MOD_BLCS_16BIT;
688 else
689 mod |= MOD_BLCP_16BIT;
690 if (is_manager(i2s))
691 mod |= MOD_BLC_16BIT;
692 break;
693 case SNDRV_PCM_FORMAT_S24_LE:
694 if (is_secondary(i2s))
695 mod |= MOD_BLCS_24BIT;
696 else
697 mod |= MOD_BLCP_24BIT;
698 if (is_manager(i2s))
699 mod |= MOD_BLC_24BIT;
700 break;
701 default:
702 dev_err(&i2s->pdev->dev, "Format(%d) not supported\n",
703 params_format(params));
704 return -EINVAL;
705 }
706 writel(mod, i2s->addr + I2SMOD);
707
708 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
709 snd_soc_dai_set_dma_data(dai, substream,
710 (void *)&i2s->dma_playback);
711 else
712 snd_soc_dai_set_dma_data(dai, substream,
713 (void *)&i2s->dma_capture);
714
715 i2s->frmclk = params_rate(params);
716
717 return 0;
718}
719
720/* We set constraints on the substream acc to the version of I2S */
721static int i2s_startup(struct snd_pcm_substream *substream,
722 struct snd_soc_dai *dai)
723{
724 struct i2s_dai *i2s = to_info(dai);
725 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
726 unsigned long flags;
727
728 spin_lock_irqsave(&lock, flags);
729
730 i2s->mode |= DAI_OPENED;
731
732 if (is_manager(other))
733 i2s->mode &= ~DAI_MANAGER;
734 else
735 i2s->mode |= DAI_MANAGER;
736
737 /* Enforce set_sysclk in Master mode */
738 i2s->rclk_srcrate = 0;
739
740 spin_unlock_irqrestore(&lock, flags);
741
742 return 0;
743}
744
745static void i2s_shutdown(struct snd_pcm_substream *substream,
746 struct snd_soc_dai *dai)
747{
748 struct i2s_dai *i2s = to_info(dai);
749 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
750 unsigned long flags;
751
752 spin_lock_irqsave(&lock, flags);
753
754 i2s->mode &= ~DAI_OPENED;
755 i2s->mode &= ~DAI_MANAGER;
756
757 if (is_opened(other))
758 other->mode |= DAI_MANAGER;
759
760 /* Reset any constraint on RFS and BFS */
761 i2s->rfs = 0;
762 i2s->bfs = 0;
763
764 spin_unlock_irqrestore(&lock, flags);
765
766 /* Gate CDCLK by default */
767 if (!is_opened(other))
768 i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
769 0, SND_SOC_CLOCK_IN);
770}
771
772static int config_setup(struct i2s_dai *i2s)
773{
774 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
775 unsigned rfs, bfs, blc;
776 u32 psr;
777
778 blc = get_blc(i2s);
779
780 bfs = i2s->bfs;
781
782 if (!bfs && other)
783 bfs = other->bfs;
784
785 /* Select least possible multiple(2) if no constraint set */
786 if (!bfs)
787 bfs = blc * 2;
788
789 rfs = i2s->rfs;
790
791 if (!rfs && other)
792 rfs = other->rfs;
793
794 if ((rfs == 256 || rfs == 512) && (blc == 24)) {
795 dev_err(&i2s->pdev->dev,
796 "%d-RFS not supported for 24-blc\n", rfs);
797 return -EINVAL;
798 }
799
800 if (!rfs) {
801 if (bfs == 16 || bfs == 32)
802 rfs = 256;
803 else
804 rfs = 384;
805 }
806
807 /* If already setup and running */
808 if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) {
809 dev_err(&i2s->pdev->dev,
810 "%s:%d Other DAI busy\n", __func__, __LINE__);
811 return -EAGAIN;
812 }
813
814 /* Don't bother RFS, BFS & PSR in Slave mode */
815 if (is_slave(i2s))
816 return 0;
817
818 set_bfs(i2s, bfs);
819 set_rfs(i2s, rfs);
820
821 if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {
822 psr = i2s->rclk_srcrate / i2s->frmclk / rfs;
823 writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR);
824 dev_dbg(&i2s->pdev->dev,
825 "RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",
826 i2s->rclk_srcrate, psr, rfs, bfs);
827 }
828
829 return 0;
830}
831
832static int i2s_trigger(struct snd_pcm_substream *substream,
833 int cmd, struct snd_soc_dai *dai)
834{
835 int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
836 struct snd_soc_pcm_runtime *rtd = substream->private_data;
837 struct i2s_dai *i2s = to_info(rtd->cpu_dai);
838 unsigned long flags;
839
840 switch (cmd) {
841 case SNDRV_PCM_TRIGGER_START:
842 case SNDRV_PCM_TRIGGER_RESUME:
843 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
844 local_irq_save(flags);
845
846 if (config_setup(i2s)) {
847 local_irq_restore(flags);
848 return -EINVAL;
849 }
850
851 if (capture)
852 i2s_rxctrl(i2s, 1);
853 else
854 i2s_txctrl(i2s, 1);
855
856 local_irq_restore(flags);
857 break;
858 case SNDRV_PCM_TRIGGER_STOP:
859 case SNDRV_PCM_TRIGGER_SUSPEND:
860 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
861 local_irq_save(flags);
862
863 if (capture)
864 i2s_rxctrl(i2s, 0);
865 else
866 i2s_txctrl(i2s, 0);
867
868 if (capture)
869 i2s_fifo(i2s, FIC_RXFLUSH);
870 else
871 i2s_fifo(i2s, FIC_TXFLUSH);
872
873 local_irq_restore(flags);
874 break;
875 }
876
877 return 0;
878}
879
880static int i2s_set_clkdiv(struct snd_soc_dai *dai,
881 int div_id, int div)
882{
883 struct i2s_dai *i2s = to_info(dai);
884 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
885
886 switch (div_id) {
887 case SAMSUNG_I2S_DIV_BCLK:
888 if ((any_active(i2s) && div && (get_bfs(i2s) != div))
889 || (other && other->bfs && (other->bfs != div))) {
890 dev_err(&i2s->pdev->dev,
891 "%s:%d Other DAI busy\n", __func__, __LINE__);
892 return -EAGAIN;
893 }
894 i2s->bfs = div;
895 break;
896 default:
897 dev_err(&i2s->pdev->dev,
898 "Invalid clock divider(%d)\n", div_id);
899 return -EINVAL;
900 }
901
902 return 0;
903}
904
905static snd_pcm_sframes_t
906i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
907{
908 struct i2s_dai *i2s = to_info(dai);
909 u32 reg = readl(i2s->addr + I2SFIC);
910 snd_pcm_sframes_t delay;
911
912 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
913 delay = FIC_RXCOUNT(reg);
914 else if (is_secondary(i2s))
915 delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS));
916 else
917 delay = FIC_TXCOUNT(reg);
918
919 return delay;
920}
921
922#ifdef CONFIG_PM
923static int i2s_suspend(struct snd_soc_dai *dai)
924{
925 struct i2s_dai *i2s = to_info(dai);
926
927 if (dai->active) {
928 i2s->suspend_i2smod = readl(i2s->addr + I2SMOD);
929 i2s->suspend_i2scon = readl(i2s->addr + I2SCON);
930 i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR);
931 }
932
933 return 0;
934}
935
936static int i2s_resume(struct snd_soc_dai *dai)
937{
938 struct i2s_dai *i2s = to_info(dai);
939
940 if (dai->active) {
941 writel(i2s->suspend_i2scon, i2s->addr + I2SCON);
942 writel(i2s->suspend_i2smod, i2s->addr + I2SMOD);
943 writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR);
944 }
945
946 return 0;
947}
948#else
949#define i2s_suspend NULL
950#define i2s_resume NULL
951#endif
952
953static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
954{
955 struct i2s_dai *i2s = to_info(dai);
956 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
957
958 if (other && other->clk) /* If this is probe on secondary */
959 goto probe_exit;
960
961 i2s->addr = ioremap(i2s->base, 0x100);
962 if (i2s->addr == NULL) {
963 dev_err(&i2s->pdev->dev, "cannot ioremap registers\n");
964 return -ENXIO;
965 }
966
967 i2s->clk = clk_get(&i2s->pdev->dev, "iis");
968 if (IS_ERR(i2s->clk)) {
969 dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n");
970 iounmap(i2s->addr);
971 return -ENOENT;
972 }
973 clk_enable(i2s->clk);
974
975 if (other) {
976 other->addr = i2s->addr;
977 other->clk = i2s->clk;
978 }
979
980 if (i2s->quirks & QUIRK_NEED_RSTCLR)
981 writel(CON_RSTCLR, i2s->addr + I2SCON);
982
983probe_exit:
984 /* Reset any constraint on RFS and BFS */
985 i2s->rfs = 0;
986 i2s->bfs = 0;
987 i2s_txctrl(i2s, 0);
988 i2s_rxctrl(i2s, 0);
989 i2s_fifo(i2s, FIC_TXFLUSH);
990 i2s_fifo(other, FIC_TXFLUSH);
991 i2s_fifo(i2s, FIC_RXFLUSH);
992
993 /* Gate CDCLK by default */
994 if (!is_opened(other))
995 i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK,
996 0, SND_SOC_CLOCK_IN);
997
998 return 0;
999}
1000
1001static int samsung_i2s_dai_remove(struct snd_soc_dai *dai)
1002{
1003 struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai);
1004 struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai;
1005
1006 if (!other || !other->clk) {
1007
1008 if (i2s->quirks & QUIRK_NEED_RSTCLR)
1009 writel(0, i2s->addr + I2SCON);
1010
1011 clk_disable(i2s->clk);
1012 clk_put(i2s->clk);
1013
1014 iounmap(i2s->addr);
1015 }
1016
1017 i2s->clk = NULL;
1018
1019 return 0;
1020}
1021
1022static struct snd_soc_dai_ops samsung_i2s_dai_ops = {
1023 .trigger = i2s_trigger,
1024 .hw_params = i2s_hw_params,
1025 .set_fmt = i2s_set_fmt,
1026 .set_clkdiv = i2s_set_clkdiv,
1027 .set_sysclk = i2s_set_sysclk,
1028 .startup = i2s_startup,
1029 .shutdown = i2s_shutdown,
1030 .delay = i2s_delay,
1031};
1032
1033#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000
1034
1035#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \
1036 SNDRV_PCM_FMTBIT_S16_LE | \
1037 SNDRV_PCM_FMTBIT_S24_LE)
1038
1039static __devinit
1040struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec)
1041{
1042 struct i2s_dai *i2s;
1043
1044 i2s = kzalloc(sizeof(struct i2s_dai), GFP_KERNEL);
1045 if (i2s == NULL)
1046 return NULL;
1047
1048 i2s->pdev = pdev;
1049 i2s->pri_dai = NULL;
1050 i2s->sec_dai = NULL;
1051 i2s->i2s_dai_drv.symmetric_rates = 1;
1052 i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe;
1053 i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove;
1054 i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops;
1055 i2s->i2s_dai_drv.suspend = i2s_suspend;
1056 i2s->i2s_dai_drv.resume = i2s_resume;
1057 i2s->i2s_dai_drv.playback.channels_min = 2;
1058 i2s->i2s_dai_drv.playback.channels_max = 2;
1059 i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES;
1060 i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS;
1061
1062 if (!sec) {
1063 i2s->i2s_dai_drv.capture.channels_min = 2;
1064 i2s->i2s_dai_drv.capture.channels_max = 2;
1065 i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES;
1066 i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS;
1067 } else { /* Create a new platform_device for Secondary */
1068 i2s->pdev = platform_device_register_resndata(NULL,
1069 pdev->name, pdev->id + SAMSUNG_I2S_SECOFF,
1070 NULL, 0, NULL, 0);
1071 if (IS_ERR(i2s->pdev)) {
1072 kfree(i2s);
1073 return NULL;
1074 }
1075 }
1076
1077 /* Pre-assign snd_soc_dai_set_drvdata */
1078 dev_set_drvdata(&i2s->pdev->dev, i2s);
1079
1080 return i2s;
1081}
1082
1083static __devinit int samsung_i2s_probe(struct platform_device *pdev)
1084{
1085 u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan;
1086 struct i2s_dai *pri_dai, *sec_dai = NULL;
1087 struct s3c_audio_pdata *i2s_pdata;
1088 struct samsung_i2s *i2s_cfg;
1089 struct resource *res;
1090 u32 regs_base, quirks;
1091 int ret = 0;
1092
1093 /* Call during Seconday interface registration */
1094 if (pdev->id >= SAMSUNG_I2S_SECOFF) {
1095 sec_dai = dev_get_drvdata(&pdev->dev);
1096 snd_soc_register_dai(&sec_dai->pdev->dev,
1097 &sec_dai->i2s_dai_drv);
1098 return 0;
1099 }
1100
1101 i2s_pdata = pdev->dev.platform_data;
1102 if (i2s_pdata == NULL) {
1103 dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n");
1104 return -EINVAL;
1105 }
1106
1107 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
1108 if (!res) {
1109 dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n");
1110 return -ENXIO;
1111 }
1112 dma_pl_chan = res->start;
1113
1114 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
1115 if (!res) {
1116 dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n");
1117 return -ENXIO;
1118 }
1119 dma_cp_chan = res->start;
1120
1121 res = platform_get_resource(pdev, IORESOURCE_DMA, 2);
1122 if (res)
1123 dma_pl_sec_chan = res->start;
1124 else
1125 dma_pl_sec_chan = 0;
1126
1127 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1128 if (!res) {
1129 dev_err(&pdev->dev, "Unable to get I2S SFR address\n");
1130 return -ENXIO;
1131 }
1132
1133 if (!request_mem_region(res->start, resource_size(res),
1134 "samsung-i2s")) {
1135 dev_err(&pdev->dev, "Unable to request SFR region\n");
1136 return -EBUSY;
1137 }
1138 regs_base = res->start;
1139
1140 i2s_cfg = &i2s_pdata->type.i2s;
1141 quirks = i2s_cfg->quirks;
1142
1143 pri_dai = i2s_alloc_dai(pdev, false);
1144 if (!pri_dai) {
1145 dev_err(&pdev->dev, "Unable to alloc I2S_pri\n");
1146 ret = -ENOMEM;
1147 goto err1;
1148 }
1149
1150 pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
1151 pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
1152 pri_dai->dma_playback.client =
1153 (struct s3c2410_dma_client *)&pri_dai->dma_playback;
1154 pri_dai->dma_capture.client =
1155 (struct s3c2410_dma_client *)&pri_dai->dma_capture;
1156 pri_dai->dma_playback.channel = dma_pl_chan;
1157 pri_dai->dma_capture.channel = dma_cp_chan;
1158 pri_dai->src_clk = i2s_cfg->src_clk;
1159 pri_dai->dma_playback.dma_size = 4;
1160 pri_dai->dma_capture.dma_size = 4;
1161 pri_dai->base = regs_base;
1162 pri_dai->quirks = quirks;
1163
1164 if (quirks & QUIRK_PRI_6CHAN)
1165 pri_dai->i2s_dai_drv.playback.channels_max = 6;
1166
1167 if (quirks & QUIRK_SEC_DAI) {
1168 sec_dai = i2s_alloc_dai(pdev, true);
1169 if (!sec_dai) {
1170 dev_err(&pdev->dev, "Unable to alloc I2S_sec\n");
1171 ret = -ENOMEM;
1172 goto err2;
1173 }
1174 sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
1175 sec_dai->dma_playback.client =
1176 (struct s3c2410_dma_client *)&sec_dai->dma_playback;
1177 /* Use iDMA always if SysDMA not provided */
1178 sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1;
1179 sec_dai->src_clk = i2s_cfg->src_clk;
1180 sec_dai->dma_playback.dma_size = 4;
1181 sec_dai->base = regs_base;
1182 sec_dai->quirks = quirks;
1183 sec_dai->pri_dai = pri_dai;
1184 pri_dai->sec_dai = sec_dai;
1185 }
1186
1187 if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) {
1188 dev_err(&pdev->dev, "Unable to configure gpio\n");
1189 ret = -EINVAL;
1190 goto err3;
1191 }
1192
1193 snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv);
1194
1195 return 0;
1196err3:
1197 kfree(sec_dai);
1198err2:
1199 kfree(pri_dai);
1200err1:
1201 release_mem_region(regs_base, resource_size(res));
1202
1203 return ret;
1204}
1205
1206static __devexit int samsung_i2s_remove(struct platform_device *pdev)
1207{
1208 struct i2s_dai *i2s, *other;
1209
1210 i2s = dev_get_drvdata(&pdev->dev);
1211 other = i2s->pri_dai ? : i2s->sec_dai;
1212
1213 if (other) {
1214 other->pri_dai = NULL;
1215 other->sec_dai = NULL;
1216 } else {
1217 struct resource *res;
1218 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1219 if (res)
1220 release_mem_region(res->start, resource_size(res));
1221 }
1222
1223 i2s->pri_dai = NULL;
1224 i2s->sec_dai = NULL;
1225
1226 kfree(i2s);
1227
1228 snd_soc_unregister_dai(&pdev->dev);
1229
1230 return 0;
1231}
1232
1233static struct platform_driver samsung_i2s_driver = {
1234 .probe = samsung_i2s_probe,
1235 .remove = samsung_i2s_remove,
1236 .driver = {
1237 .name = "samsung-i2s",
1238 .owner = THIS_MODULE,
1239 },
1240};
1241
1242static int __init samsung_i2s_init(void)
1243{
1244 return platform_driver_register(&samsung_i2s_driver);
1245}
1246module_init(samsung_i2s_init);
1247
1248static void __exit samsung_i2s_exit(void)
1249{
1250 platform_driver_unregister(&samsung_i2s_driver);
1251}
1252module_exit(samsung_i2s_exit);
1253
1254/* Module information */
1255MODULE_AUTHOR("Jaswinder Singh, <jassi.brar@samsung.com>");
1256MODULE_DESCRIPTION("Samsung I2S Interface");
1257MODULE_ALIAS("platform:samsung-i2s");
1258MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h
new file mode 100644
index 000000000000..8e15f6a616d1
--- /dev/null
+++ b/sound/soc/samsung/i2s.h
@@ -0,0 +1,29 @@
1/* sound/soc/samsung/i2s.h
2 *
3 * ALSA SoC Audio Layer - Samsung I2S Controller driver
4 *
5 * Copyright (c) 2010 Samsung Electronics Co. Ltd.
6 * Jaswinder Singh <jassi.brar@samsung.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 __SND_SOC_SAMSUNG_I2S_H
14#define __SND_SOC_SAMSUNG_I2S_H
15
16/*
17 * Maximum number of I2S blocks that any SoC can have.
18 * The secondary interface of a CPU dai(if there exists any),
19 * is indexed at [cpu-dai's ID + SAMSUNG_I2S_SECOFF]
20 */
21#define SAMSUNG_I2S_SECOFF 4
22
23#define SAMSUNG_I2S_DIV_BCLK 1
24
25#define SAMSUNG_I2S_RCLKSRC_0 0
26#define SAMSUNG_I2S_RCLKSRC_1 1
27#define SAMSUNG_I2S_CDCLK 2
28
29#endif /* __SND_SOC_SAMSUNG_I2S_H */
diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c
index 49605cd83947..08802520e014 100644
--- a/sound/soc/s3c24xx/jive_wm8750.c
+++ b/sound/soc/samsung/jive_wm8750.c
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/jive_wm8750.c 1/* sound/soc/samsung/jive_wm8750.c
2 * 2 *
3 * Copyright 2007,2008 Simtec Electronics 3 * Copyright 2007,2008 Simtec Electronics
4 * 4 *
@@ -21,11 +21,10 @@
21#include <sound/core.h> 21#include <sound/core.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25 24
26#include <asm/mach-types.h> 25#include <asm/mach-types.h>
27 26
28#include "s3c-dma.h" 27#include "dma.h"
29#include "s3c2412-i2s.h" 28#include "s3c2412-i2s.h"
30 29
31#include "../codecs/wm8750.h" 30#include "../codecs/wm8750.h"
@@ -111,18 +110,19 @@ static struct snd_soc_ops jive_ops = {
111static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) 110static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
112{ 111{
113 struct snd_soc_codec *codec = rtd->codec; 112 struct snd_soc_codec *codec = rtd->codec;
113 struct snd_soc_dapm_context *dapm = &codec->dapm;
114 int err; 114 int err;
115 115
116 /* These endpoints are not being used. */ 116 /* These endpoints are not being used. */
117 snd_soc_dapm_nc_pin(codec, "LINPUT2"); 117 snd_soc_dapm_nc_pin(dapm, "LINPUT2");
118 snd_soc_dapm_nc_pin(codec, "RINPUT2"); 118 snd_soc_dapm_nc_pin(dapm, "RINPUT2");
119 snd_soc_dapm_nc_pin(codec, "LINPUT3"); 119 snd_soc_dapm_nc_pin(dapm, "LINPUT3");
120 snd_soc_dapm_nc_pin(codec, "RINPUT3"); 120 snd_soc_dapm_nc_pin(dapm, "RINPUT3");
121 snd_soc_dapm_nc_pin(codec, "OUT3"); 121 snd_soc_dapm_nc_pin(dapm, "OUT3");
122 snd_soc_dapm_nc_pin(codec, "MONO"); 122 snd_soc_dapm_nc_pin(dapm, "MONO");
123 123
124 /* Add jive specific widgets */ 124 /* Add jive specific widgets */
125 err = snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, 125 err = snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets,
126 ARRAY_SIZE(wm8750_dapm_widgets)); 126 ARRAY_SIZE(wm8750_dapm_widgets));
127 if (err) { 127 if (err) {
128 printk(KERN_ERR "%s: failed to add widgets (%d)\n", 128 printk(KERN_ERR "%s: failed to add widgets (%d)\n",
@@ -130,8 +130,8 @@ static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd)
130 return err; 130 return err;
131 } 131 }
132 132
133 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 133 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
134 snd_soc_dapm_sync(codec); 134 snd_soc_dapm_sync(dapm);
135 135
136 return 0; 136 return 0;
137} 137}
@@ -141,7 +141,7 @@ static struct snd_soc_dai_link jive_dai = {
141 .stream_name = "WM8750", 141 .stream_name = "WM8750",
142 .cpu_dai_name = "s3c2412-i2s", 142 .cpu_dai_name = "s3c2412-i2s",
143 .codec_dai_name = "wm8750-hifi", 143 .codec_dai_name = "wm8750-hifi",
144 .platform_name = "s3c24xx-pcm-audio", 144 .platform_name = "samsung-audio",
145 .codec_name = "wm8750-codec.0-0x1a", 145 .codec_name = "wm8750-codec.0-0x1a",
146 .init = jive_wm8750_init, 146 .init = jive_wm8750_init,
147 .ops = &jive_ops, 147 .ops = &jive_ops,
diff --git a/sound/soc/s3c24xx/lm4857.h b/sound/soc/samsung/lm4857.h
index 0cf5b7011d6f..0cf5b7011d6f 100644
--- a/sound/soc/s3c24xx/lm4857.h
+++ b/sound/soc/samsung/lm4857.h
diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c
index abe64abe8c84..a2bb34def740 100644
--- a/sound/soc/s3c24xx/ln2440sbc_alc650.c
+++ b/sound/soc/samsung/ln2440sbc_alc650.c
@@ -21,10 +21,9 @@
21#include <sound/core.h> 21#include <sound/core.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25 24
26#include "s3c-dma.h" 25#include "dma.h"
27#include "s3c-ac97.h" 26#include "ac97.h"
28 27
29static struct snd_soc_card ln2440sbc; 28static struct snd_soc_card ln2440sbc;
30 29
@@ -32,10 +31,10 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = {
32{ 31{
33 .name = "AC97", 32 .name = "AC97",
34 .stream_name = "AC97 HiFi", 33 .stream_name = "AC97 HiFi",
35 .cpu_dai_name = "s3c-ac97", 34 .cpu_dai_name = "samsung-ac97",
36 .codec_dai_name = "ac97-hifi", 35 .codec_dai_name = "ac97-hifi",
37 .codec_name = "ac97-codec", 36 .codec_name = "ac97-codec",
38 .platform_name = "s3c24xx-pcm-audio", 37 .platform_name = "samsung-audio",
39}, 38},
40}; 39};
41 40
diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c
index e97bdf150a03..3eec610c10f9 100644
--- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c
+++ b/sound/soc/samsung/neo1973_gta02_wm8753.c
@@ -22,7 +22,6 @@
22#include <sound/core.h> 22#include <sound/core.h>
23#include <sound/pcm.h> 23#include <sound/pcm.h>
24#include <sound/soc.h> 24#include <sound/soc.h>
25#include <sound/soc-dapm.h>
26 25
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
28 27
@@ -32,7 +31,7 @@
32#include <asm/io.h> 31#include <asm/io.h>
33#include <mach/gta02.h> 32#include <mach/gta02.h>
34#include "../codecs/wm8753.h" 33#include "../codecs/wm8753.h"
35#include "s3c-dma.h" 34#include "dma.h"
36#include "s3c24xx-i2s.h" 35#include "s3c24xx-i2s.h"
37 36
38static struct snd_soc_card neo1973_gta02; 37static struct snd_soc_card neo1973_gta02;
@@ -333,16 +332,17 @@ static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = {
333static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd) 332static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd)
334{ 333{
335 struct snd_soc_codec *codec = rtd->codec; 334 struct snd_soc_codec *codec = rtd->codec;
335 struct snd_soc_dapm_context *dapm = &codec->dapm;
336 int err; 336 int err;
337 337
338 /* set up NC codec pins */ 338 /* set up NC codec pins */
339 snd_soc_dapm_nc_pin(codec, "OUT3"); 339 snd_soc_dapm_nc_pin(dapm, "OUT3");
340 snd_soc_dapm_nc_pin(codec, "OUT4"); 340 snd_soc_dapm_nc_pin(dapm, "OUT4");
341 snd_soc_dapm_nc_pin(codec, "LINE1"); 341 snd_soc_dapm_nc_pin(dapm, "LINE1");
342 snd_soc_dapm_nc_pin(codec, "LINE2"); 342 snd_soc_dapm_nc_pin(dapm, "LINE2");
343 343
344 /* Add neo1973 gta02 specific widgets */ 344 /* Add neo1973 gta02 specific widgets */
345 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, 345 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
346 ARRAY_SIZE(wm8753_dapm_widgets)); 346 ARRAY_SIZE(wm8753_dapm_widgets));
347 347
348 /* add neo1973 gta02 specific controls */ 348 /* add neo1973 gta02 specific controls */
@@ -353,25 +353,25 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd)
353 return err; 353 return err;
354 354
355 /* set up neo1973 gta02 specific audio path audio_map */ 355 /* set up neo1973 gta02 specific audio path audio_map */
356 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 356 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
357 357
358 /* set endpoints to default off mode */ 358 /* set endpoints to default off mode */
359 snd_soc_dapm_disable_pin(codec, "Stereo Out"); 359 snd_soc_dapm_disable_pin(dapm, "Stereo Out");
360 snd_soc_dapm_disable_pin(codec, "GSM Line Out"); 360 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
361 snd_soc_dapm_disable_pin(codec, "GSM Line In"); 361 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
362 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 362 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
363 snd_soc_dapm_disable_pin(codec, "Handset Mic"); 363 snd_soc_dapm_disable_pin(dapm, "Handset Mic");
364 snd_soc_dapm_disable_pin(codec, "Handset Spk"); 364 snd_soc_dapm_disable_pin(dapm, "Handset Spk");
365 365
366 /* allow audio paths from the GSM modem to run during suspend */ 366 /* allow audio paths from the GSM modem to run during suspend */
367 snd_soc_dapm_ignore_suspend(codec, "Stereo Out"); 367 snd_soc_dapm_ignore_suspend(dapm, "Stereo Out");
368 snd_soc_dapm_ignore_suspend(codec, "GSM Line Out"); 368 snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out");
369 snd_soc_dapm_ignore_suspend(codec, "GSM Line In"); 369 snd_soc_dapm_ignore_suspend(dapm, "GSM Line In");
370 snd_soc_dapm_ignore_suspend(codec, "Headset Mic"); 370 snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
371 snd_soc_dapm_ignore_suspend(codec, "Handset Mic"); 371 snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
372 snd_soc_dapm_ignore_suspend(codec, "Handset Spk"); 372 snd_soc_dapm_ignore_suspend(dapm, "Handset Spk");
373 373
374 snd_soc_dapm_sync(codec); 374 snd_soc_dapm_sync(dapm);
375 375
376 return 0; 376 return 0;
377} 377}
@@ -400,7 +400,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
400 .cpu_dai_name = "s3c24xx-i2s", 400 .cpu_dai_name = "s3c24xx-i2s",
401 .codec_dai_name = "wm8753-hifi", 401 .codec_dai_name = "wm8753-hifi",
402 .init = neo1973_gta02_wm8753_init, 402 .init = neo1973_gta02_wm8753_init,
403 .platform_name = "s3c24xx-pcm-audio", 403 .platform_name = "samsung-audio",
404 .codec_name = "wm8753-codec.0-0x1a", 404 .codec_name = "wm8753-codec.0-0x1a",
405 .ops = &neo1973_gta02_hifi_ops, 405 .ops = &neo1973_gta02_hifi_ops,
406}, 406},
@@ -411,7 +411,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = {
411 .codec_dai_name = "wm8753-voice", 411 .codec_dai_name = "wm8753-voice",
412 .ops = &neo1973_gta02_voice_ops, 412 .ops = &neo1973_gta02_voice_ops,
413 .codec_name = "wm8753-codec.0-0x1a", 413 .codec_name = "wm8753-codec.0-0x1a",
414 .platform_name = "s3c24xx-pcm-audio", 414 .platform_name = "samsung-audio",
415}, 415},
416}; 416};
417 417
@@ -438,25 +438,21 @@ static int __init neo1973_gta02_init(void)
438 return -ENOMEM; 438 return -ENOMEM;
439 439
440 /* register bluetooth DAI here */ 440 /* register bluetooth DAI here */
441 ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, -1, &bt_dai); 441 ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, &bt_dai);
442 if (ret) { 442 if (ret)
443 platform_device_put(neo1973_gta02_snd_device); 443 goto err_put_device;
444 return ret;
445 }
446 444
447 platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02); 445 platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02);
448 ret = platform_device_add(neo1973_gta02_snd_device); 446 ret = platform_device_add(neo1973_gta02_snd_device);
449 447
450 if (ret) { 448 if (ret)
451 platform_device_put(neo1973_gta02_snd_device); 449 goto err_unregister_dai;
452 return ret;
453 }
454 450
455 /* Initialise GPIOs used by amp */ 451 /* Initialise GPIOs used by amp */
456 ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN"); 452 ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN");
457 if (ret) { 453 if (ret) {
458 pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN); 454 pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN);
459 goto err_unregister_device; 455 goto err_del_device;
460 } 456 }
461 457
462 ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1); 458 ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1);
@@ -483,15 +479,19 @@ err_free_gpio_amp_shut:
483 gpio_free(GTA02_GPIO_AMP_SHUT); 479 gpio_free(GTA02_GPIO_AMP_SHUT);
484err_free_gpio_hp_in: 480err_free_gpio_hp_in:
485 gpio_free(GTA02_GPIO_HP_IN); 481 gpio_free(GTA02_GPIO_HP_IN);
486err_unregister_device: 482err_del_device:
487 platform_device_unregister(neo1973_gta02_snd_device); 483 platform_device_del(neo1973_gta02_snd_device);
484err_unregister_dai:
485 snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
486err_put_device:
487 platform_device_put(neo1973_gta02_snd_device);
488 return ret; 488 return ret;
489} 489}
490module_init(neo1973_gta02_init); 490module_init(neo1973_gta02_init);
491 491
492static void __exit neo1973_gta02_exit(void) 492static void __exit neo1973_gta02_exit(void)
493{ 493{
494 snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev, -1); 494 snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev);
495 platform_device_unregister(neo1973_gta02_snd_device); 495 platform_device_unregister(neo1973_gta02_snd_device);
496 gpio_free(GTA02_GPIO_HP_IN); 496 gpio_free(GTA02_GPIO_HP_IN);
497 gpio_free(GTA02_GPIO_AMP_SHUT); 497 gpio_free(GTA02_GPIO_AMP_SHUT);
diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c
index f4f2ee731f01..c7a24514beb5 100644
--- a/sound/soc/s3c24xx/neo1973_wm8753.c
+++ b/sound/soc/samsung/neo1973_wm8753.c
@@ -21,7 +21,6 @@
21#include <sound/core.h> 21#include <sound/core.h>
22#include <sound/pcm.h> 22#include <sound/pcm.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/soc-dapm.h>
25#include <sound/tlv.h> 24#include <sound/tlv.h>
26 25
27#include <asm/mach-types.h> 26#include <asm/mach-types.h>
@@ -36,7 +35,7 @@
36 35
37#include "../codecs/wm8753.h" 36#include "../codecs/wm8753.h"
38#include "lm4857.h" 37#include "lm4857.h"
39#include "s3c-dma.h" 38#include "dma.h"
40#include "s3c24xx-i2s.h" 39#include "s3c24xx-i2s.h"
41 40
42/* define the scenarios */ 41/* define the scenarios */
@@ -237,81 +236,83 @@ static int neo1973_get_scenario(struct snd_kcontrol *kcontrol,
237 236
238static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) 237static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario)
239{ 238{
239 struct snd_soc_dapm_context *dapm = &codec->dapm;
240
240 pr_debug("Entered %s\n", __func__); 241 pr_debug("Entered %s\n", __func__);
241 242
242 switch (neo1973_scenario) { 243 switch (neo1973_scenario) {
243 case NEO_AUDIO_OFF: 244 case NEO_AUDIO_OFF:
244 snd_soc_dapm_disable_pin(codec, "Audio Out"); 245 snd_soc_dapm_disable_pin(dapm, "Audio Out");
245 snd_soc_dapm_disable_pin(codec, "GSM Line Out"); 246 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
246 snd_soc_dapm_disable_pin(codec, "GSM Line In"); 247 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
247 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 248 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
248 snd_soc_dapm_disable_pin(codec, "Call Mic"); 249 snd_soc_dapm_disable_pin(dapm, "Call Mic");
249 break; 250 break;
250 case NEO_GSM_CALL_AUDIO_HANDSET: 251 case NEO_GSM_CALL_AUDIO_HANDSET:
251 snd_soc_dapm_enable_pin(codec, "Audio Out"); 252 snd_soc_dapm_enable_pin(dapm, "Audio Out");
252 snd_soc_dapm_enable_pin(codec, "GSM Line Out"); 253 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
253 snd_soc_dapm_enable_pin(codec, "GSM Line In"); 254 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
254 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 255 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
255 snd_soc_dapm_enable_pin(codec, "Call Mic"); 256 snd_soc_dapm_enable_pin(dapm, "Call Mic");
256 break; 257 break;
257 case NEO_GSM_CALL_AUDIO_HEADSET: 258 case NEO_GSM_CALL_AUDIO_HEADSET:
258 snd_soc_dapm_enable_pin(codec, "Audio Out"); 259 snd_soc_dapm_enable_pin(dapm, "Audio Out");
259 snd_soc_dapm_enable_pin(codec, "GSM Line Out"); 260 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
260 snd_soc_dapm_enable_pin(codec, "GSM Line In"); 261 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
261 snd_soc_dapm_enable_pin(codec, "Headset Mic"); 262 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
262 snd_soc_dapm_disable_pin(codec, "Call Mic"); 263 snd_soc_dapm_disable_pin(dapm, "Call Mic");
263 break; 264 break;
264 case NEO_GSM_CALL_AUDIO_BLUETOOTH: 265 case NEO_GSM_CALL_AUDIO_BLUETOOTH:
265 snd_soc_dapm_disable_pin(codec, "Audio Out"); 266 snd_soc_dapm_disable_pin(dapm, "Audio Out");
266 snd_soc_dapm_enable_pin(codec, "GSM Line Out"); 267 snd_soc_dapm_enable_pin(dapm, "GSM Line Out");
267 snd_soc_dapm_enable_pin(codec, "GSM Line In"); 268 snd_soc_dapm_enable_pin(dapm, "GSM Line In");
268 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 269 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
269 snd_soc_dapm_disable_pin(codec, "Call Mic"); 270 snd_soc_dapm_disable_pin(dapm, "Call Mic");
270 break; 271 break;
271 case NEO_STEREO_TO_SPEAKERS: 272 case NEO_STEREO_TO_SPEAKERS:
272 snd_soc_dapm_enable_pin(codec, "Audio Out"); 273 snd_soc_dapm_enable_pin(dapm, "Audio Out");
273 snd_soc_dapm_disable_pin(codec, "GSM Line Out"); 274 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
274 snd_soc_dapm_disable_pin(codec, "GSM Line In"); 275 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
275 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 276 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
276 snd_soc_dapm_disable_pin(codec, "Call Mic"); 277 snd_soc_dapm_disable_pin(dapm, "Call Mic");
277 break; 278 break;
278 case NEO_STEREO_TO_HEADPHONES: 279 case NEO_STEREO_TO_HEADPHONES:
279 snd_soc_dapm_enable_pin(codec, "Audio Out"); 280 snd_soc_dapm_enable_pin(dapm, "Audio Out");
280 snd_soc_dapm_disable_pin(codec, "GSM Line Out"); 281 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
281 snd_soc_dapm_disable_pin(codec, "GSM Line In"); 282 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
282 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 283 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
283 snd_soc_dapm_disable_pin(codec, "Call Mic"); 284 snd_soc_dapm_disable_pin(dapm, "Call Mic");
284 break; 285 break;
285 case NEO_CAPTURE_HANDSET: 286 case NEO_CAPTURE_HANDSET:
286 snd_soc_dapm_disable_pin(codec, "Audio Out"); 287 snd_soc_dapm_disable_pin(dapm, "Audio Out");
287 snd_soc_dapm_disable_pin(codec, "GSM Line Out"); 288 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
288 snd_soc_dapm_disable_pin(codec, "GSM Line In"); 289 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
289 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 290 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
290 snd_soc_dapm_enable_pin(codec, "Call Mic"); 291 snd_soc_dapm_enable_pin(dapm, "Call Mic");
291 break; 292 break;
292 case NEO_CAPTURE_HEADSET: 293 case NEO_CAPTURE_HEADSET:
293 snd_soc_dapm_disable_pin(codec, "Audio Out"); 294 snd_soc_dapm_disable_pin(dapm, "Audio Out");
294 snd_soc_dapm_disable_pin(codec, "GSM Line Out"); 295 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
295 snd_soc_dapm_disable_pin(codec, "GSM Line In"); 296 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
296 snd_soc_dapm_enable_pin(codec, "Headset Mic"); 297 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
297 snd_soc_dapm_disable_pin(codec, "Call Mic"); 298 snd_soc_dapm_disable_pin(dapm, "Call Mic");
298 break; 299 break;
299 case NEO_CAPTURE_BLUETOOTH: 300 case NEO_CAPTURE_BLUETOOTH:
300 snd_soc_dapm_disable_pin(codec, "Audio Out"); 301 snd_soc_dapm_disable_pin(dapm, "Audio Out");
301 snd_soc_dapm_disable_pin(codec, "GSM Line Out"); 302 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
302 snd_soc_dapm_disable_pin(codec, "GSM Line In"); 303 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
303 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 304 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
304 snd_soc_dapm_disable_pin(codec, "Call Mic"); 305 snd_soc_dapm_disable_pin(dapm, "Call Mic");
305 break; 306 break;
306 default: 307 default:
307 snd_soc_dapm_disable_pin(codec, "Audio Out"); 308 snd_soc_dapm_disable_pin(dapm, "Audio Out");
308 snd_soc_dapm_disable_pin(codec, "GSM Line Out"); 309 snd_soc_dapm_disable_pin(dapm, "GSM Line Out");
309 snd_soc_dapm_disable_pin(codec, "GSM Line In"); 310 snd_soc_dapm_disable_pin(dapm, "GSM Line In");
310 snd_soc_dapm_disable_pin(codec, "Headset Mic"); 311 snd_soc_dapm_disable_pin(dapm, "Headset Mic");
311 snd_soc_dapm_disable_pin(codec, "Call Mic"); 312 snd_soc_dapm_disable_pin(dapm, "Call Mic");
312 } 313 }
313 314
314 snd_soc_dapm_sync(codec); 315 snd_soc_dapm_sync(dapm);
315 316
316 return 0; 317 return 0;
317} 318}
@@ -502,20 +503,21 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = {
502static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) 503static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
503{ 504{
504 struct snd_soc_codec *codec = rtd->codec; 505 struct snd_soc_codec *codec = rtd->codec;
506 struct snd_soc_dapm_context *dapm = &codec->dapm;
505 int err; 507 int err;
506 508
507 pr_debug("Entered %s\n", __func__); 509 pr_debug("Entered %s\n", __func__);
508 510
509 /* set up NC codec pins */ 511 /* set up NC codec pins */
510 snd_soc_dapm_nc_pin(codec, "LOUT2"); 512 snd_soc_dapm_nc_pin(dapm, "LOUT2");
511 snd_soc_dapm_nc_pin(codec, "ROUT2"); 513 snd_soc_dapm_nc_pin(dapm, "ROUT2");
512 snd_soc_dapm_nc_pin(codec, "OUT3"); 514 snd_soc_dapm_nc_pin(dapm, "OUT3");
513 snd_soc_dapm_nc_pin(codec, "OUT4"); 515 snd_soc_dapm_nc_pin(dapm, "OUT4");
514 snd_soc_dapm_nc_pin(codec, "LINE1"); 516 snd_soc_dapm_nc_pin(dapm, "LINE1");
515 snd_soc_dapm_nc_pin(codec, "LINE2"); 517 snd_soc_dapm_nc_pin(dapm, "LINE2");
516 518
517 /* Add neo1973 specific widgets */ 519 /* Add neo1973 specific widgets */
518 snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, 520 snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets,
519 ARRAY_SIZE(wm8753_dapm_widgets)); 521 ARRAY_SIZE(wm8753_dapm_widgets));
520 522
521 /* set endpoints to default mode */ 523 /* set endpoints to default mode */
@@ -528,10 +530,10 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
528 return err; 530 return err;
529 531
530 /* set up neo1973 specific audio routes */ 532 /* set up neo1973 specific audio routes */
531 err = snd_soc_dapm_add_routes(codec, dapm_routes, 533 err = snd_soc_dapm_add_routes(dapm, dapm_routes,
532 ARRAY_SIZE(dapm_routes)); 534 ARRAY_SIZE(dapm_routes));
533 535
534 snd_soc_dapm_sync(codec); 536 snd_soc_dapm_sync(dapm);
535 return 0; 537 return 0;
536} 538}
537 539
@@ -556,7 +558,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
556{ /* Hifi Playback - for similatious use with voice below */ 558{ /* Hifi Playback - for similatious use with voice below */
557 .name = "WM8753", 559 .name = "WM8753",
558 .stream_name = "WM8753 HiFi", 560 .stream_name = "WM8753 HiFi",
559 .platform_name = "s3c24xx-pcm-audio", 561 .platform_name = "samsung-audio",
560 .cpu_dai_name = "s3c24xx-i2s", 562 .cpu_dai_name = "s3c24xx-i2s",
561 .codec_dai_name = "wm8753-hifi", 563 .codec_dai_name = "wm8753-hifi",
562 .codec_name = "wm8753-codec.0-0x1a", 564 .codec_name = "wm8753-codec.0-0x1a",
@@ -566,7 +568,7 @@ static struct snd_soc_dai_link neo1973_dai[] = {
566{ /* Voice via BT */ 568{ /* Voice via BT */
567 .name = "Bluetooth", 569 .name = "Bluetooth",
568 .stream_name = "Voice", 570 .stream_name = "Voice",
569 .platform_name = "s3c24xx-pcm-audio", 571 .platform_name = "samsung-audio",
570 .cpu_dai_name = "bluetooth-dai", 572 .cpu_dai_name = "bluetooth-dai",
571 .codec_dai_name = "wm8753-voice", 573 .codec_dai_name = "wm8753-voice",
572 .codec_name = "wm8753-codec.0-0x1a", 574 .codec_name = "wm8753-codec.0-0x1a",
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/samsung/pcm.c
index 2e020e1b4eab..48d0b750406b 100644
--- a/sound/soc/s3c24xx/s3c-pcm.c
+++ b/sound/soc/samsung/pcm.c
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c-pcm.c 1/* sound/soc/samsung/pcm.c
2 * 2 *
3 * ALSA SoC Audio Layer - S3C PCM-Controller driver 3 * ALSA SoC Audio Layer - S3C PCM-Controller driver
4 * 4 *
@@ -29,8 +29,8 @@
29#include <plat/audio.h> 29#include <plat/audio.h>
30#include <plat/dma.h> 30#include <plat/dma.h>
31 31
32#include "s3c-dma.h" 32#include "dma.h"
33#include "s3c-pcm.h" 33#include "pcm.h"
34 34
35static struct s3c2410_dma_client s3c_pcm_dma_client_out = { 35static struct s3c2410_dma_client s3c_pcm_dma_client_out = {
36 .name = "PCM Stereo out" 36 .name = "PCM Stereo out"
diff --git a/sound/soc/s3c24xx/s3c-pcm.h b/sound/soc/samsung/pcm.h
index f60baa19387d..03393dcf852d 100644
--- a/sound/soc/s3c24xx/s3c-pcm.h
+++ b/sound/soc/samsung/pcm.h
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c-pcm.h 1/* sound/soc/samsung/pcm.h
2 * 2 *
3 * This program is free software; you can redistribute it and/or modify 3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as 4 * it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/s3c24xx/regs-i2s-v2.h b/sound/soc/samsung/regs-i2s-v2.h
index 5e5e5680580b..5e5e5680580b 100644
--- a/sound/soc/s3c24xx/regs-i2s-v2.h
+++ b/sound/soc/samsung/regs-i2s-v2.h
diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c
index 468cc11fdf47..f40027445dda 100644
--- a/sound/soc/s3c24xx/rx1950_uda1380.c
+++ b/sound/soc/samsung/rx1950_uda1380.c
@@ -25,7 +25,6 @@
25#include <linux/clk.h> 25#include <linux/clk.h>
26 26
27#include <sound/soc.h> 27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/uda1380.h> 28#include <sound/uda1380.h>
30#include <sound/jack.h> 29#include <sound/jack.h>
31 30
@@ -35,7 +34,7 @@
35 34
36#include <asm/mach-types.h> 35#include <asm/mach-types.h>
37 36
38#include "s3c-dma.h" 37#include "dma.h"
39#include "s3c24xx-i2s.h" 38#include "s3c24xx-i2s.h"
40#include "../codecs/uda1380.h" 39#include "../codecs/uda1380.h"
41 40
@@ -95,7 +94,7 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = {
95 .cpu_dai_name = "s3c24xx-iis", 94 .cpu_dai_name = "s3c24xx-iis",
96 .codec_dai_name = "uda1380-hifi", 95 .codec_dai_name = "uda1380-hifi",
97 .init = rx1950_uda1380_init, 96 .init = rx1950_uda1380_init,
98 .platform_name = "s3c24xx-pcm-audio", 97 .platform_name = "samsung-audio",
99 .codec_name = "uda1380-codec.0-001a", 98 .codec_name = "uda1380-codec.0-001a",
100 .ops = &rx1950_ops, 99 .ops = &rx1950_ops,
101 }, 100 },
@@ -228,26 +227,28 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream,
228static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) 227static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd)
229{ 228{
230 struct snd_soc_codec *codec = rtd->codec; 229 struct snd_soc_codec *codec = rtd->codec;
230 struct snd_soc_dapm_context *dapm = &codec->dapm;
231 int err; 231 int err;
232 232
233 /* Add rx1950 specific widgets */ 233 /* Add rx1950 specific widgets */
234 err = snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, 234 err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets,
235 ARRAY_SIZE(uda1380_dapm_widgets)); 235 ARRAY_SIZE(uda1380_dapm_widgets));
236 236
237 if (err) 237 if (err)
238 return err; 238 return err;
239 239
240 /* Set up rx1950 specific audio path audio_mapnects */ 240 /* Set up rx1950 specific audio path audio_mapnects */
241 err = snd_soc_dapm_add_routes(codec, audio_map, 241 err = snd_soc_dapm_add_routes(dapm, audio_map,
242 ARRAY_SIZE(audio_map)); 242 ARRAY_SIZE(audio_map));
243 243
244 if (err) 244 if (err)
245 return err; 245 return err;
246 246
247 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 247 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
248 snd_soc_dapm_enable_pin(codec, "Speaker"); 248 snd_soc_dapm_enable_pin(dapm, "Speaker");
249 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
249 250
250 snd_soc_dapm_sync(codec); 251 snd_soc_dapm_sync(dapm);
251 252
252 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, 253 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
253 &hp_jack); 254 &hp_jack);
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c
index b3866d5b19e9..094f36e41e83 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.c
+++ b/sound/soc/samsung/s3c-i2s-v2.c
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c-i2c-v2.c 1/* sound/soc/samsung/s3c-i2c-v2.c
2 * 2 *
3 * ALSA Soc Audio Layer - I2S core for newer Samsung SoCs. 3 * ALSA Soc Audio Layer - I2S core for newer Samsung SoCs.
4 * 4 *
@@ -28,7 +28,7 @@
28 28
29#include "regs-i2s-v2.h" 29#include "regs-i2s-v2.h"
30#include "s3c-i2s-v2.h" 30#include "s3c-i2s-v2.h"
31#include "s3c-dma.h" 31#include "dma.h"
32 32
33#undef S3C_IIS_V2_SUPPORTED 33#undef S3C_IIS_V2_SUPPORTED
34 34
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h
index d45830151484..f8297d9bb8a3 100644
--- a/sound/soc/s3c24xx/s3c-i2s-v2.h
+++ b/sound/soc/samsung/s3c-i2s-v2.h
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c-i2s-v2.h 1/* sound/soc/samsung/s3c-i2s-v2.h
2 * 2 *
3 * ALSA Soc Audio Layer - S3C_I2SV2 I2S driver 3 * ALSA Soc Audio Layer - S3C_I2SV2 I2S driver
4 * 4 *
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 4a861cfa52c5..7ea837867124 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c2412-i2s.c 1/* sound/soc/samsung/s3c2412-i2s.c
2 * 2 *
3 * ALSA Soc Audio Layer - S3C2412 I2S driver 3 * ALSA Soc Audio Layer - S3C2412 I2S driver
4 * 4 *
@@ -35,7 +35,7 @@
35#include <mach/regs-gpio.h> 35#include <mach/regs-gpio.h>
36#include <mach/dma.h> 36#include <mach/dma.h>
37 37
38#include "s3c-dma.h" 38#include "dma.h"
39#include "regs-i2s-v2.h" 39#include "regs-i2s-v2.h"
40#include "s3c2412-i2s.h" 40#include "s3c2412-i2s.h"
41 41
diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/samsung/s3c2412-i2s.h
index 01a0471ac65c..02ad5794c0a9 100644
--- a/sound/soc/s3c24xx/s3c2412-i2s.h
+++ b/sound/soc/samsung/s3c2412-i2s.h
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c2412-i2s.c 1/* sound/soc/samsung/s3c2412-i2s.c
2 * 2 *
3 * ALSA Soc Audio Layer - S3C2412 I2S driver 3 * ALSA Soc Audio Layer - S3C2412 I2S driver
4 * 4 *
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index e060daaa458f..13e41ed8e22b 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -38,7 +38,7 @@
38 38
39#include <plat/regs-iis.h> 39#include <plat/regs-iis.h>
40 40
41#include "s3c-dma.h" 41#include "dma.h"
42#include "s3c24xx-i2s.h" 42#include "s3c24xx-i2s.h"
43 43
44static struct s3c2410_dma_client s3c24xx_dma_client_out = { 44static struct s3c2410_dma_client s3c24xx_dma_client_out = {
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/samsung/s3c24xx-i2s.h
index f9ca04edacb7..f9ca04edacb7 100644
--- a/sound/soc/s3c24xx/s3c24xx-i2s.h
+++ b/sound/soc/samsung/s3c24xx-i2s.h
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c
index c4c111442010..a434032d1832 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.c
+++ b/sound/soc/samsung/s3c24xx_simtec.c
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec.c 1/* sound/soc/samsung/s3c24xx_simtec.c
2 * 2 *
3 * Copyright 2009 Simtec Electronics 3 * Copyright 2009 Simtec Electronics
4 * 4 *
@@ -17,11 +17,10 @@
17#include <sound/core.h> 17#include <sound/core.h>
18#include <sound/pcm.h> 18#include <sound/pcm.h>
19#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21 20
22#include <plat/audio-simtec.h> 21#include <plat/audio-simtec.h>
23 22
24#include "s3c-dma.h" 23#include "dma.h"
25#include "s3c24xx-i2s.h" 24#include "s3c24xx-i2s.h"
26#include "s3c24xx_simtec.h" 25#include "s3c24xx_simtec.h"
27 26
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/samsung/s3c24xx_simtec.h
index e63d5ff9c41f..8270748a2c41 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec.h
+++ b/sound/soc/samsung/s3c24xx_simtec.h
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec.h 1/* sound/soc/samsung/s3c24xx_simtec.h
2 * 2 *
3 * Copyright 2009 Simtec Electronics 3 * Copyright 2009 Simtec Electronics
4 * 4 *
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c
index f88453735ae2..bb4292e3596c 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c
+++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec_hermes.c 1/* sound/soc/samsung/s3c24xx_simtec_hermes.c
2 * 2 *
3 * Copyright 2009 Simtec Electronics 3 * Copyright 2009 Simtec Electronics
4 * 4 *
@@ -14,16 +14,13 @@
14#include <sound/core.h> 14#include <sound/core.h>
15#include <sound/pcm.h> 15#include <sound/pcm.h>
16#include <sound/soc.h> 16#include <sound/soc.h>
17#include <sound/soc-dapm.h>
18 17
19#include <plat/audio-simtec.h> 18#include <plat/audio-simtec.h>
20 19
21#include "s3c-dma.h" 20#include "dma.h"
22#include "s3c24xx-i2s.h" 21#include "s3c24xx-i2s.h"
23#include "s3c24xx_simtec.h" 22#include "s3c24xx_simtec.h"
24 23
25#include "../codecs/tlv320aic3x.h"
26
27static const struct snd_soc_dapm_widget dapm_widgets[] = { 24static const struct snd_soc_dapm_widget dapm_widgets[] = {
28 SND_SOC_DAPM_LINE("GSM Out", NULL), 25 SND_SOC_DAPM_LINE("GSM Out", NULL),
29 SND_SOC_DAPM_LINE("GSM In", NULL), 26 SND_SOC_DAPM_LINE("GSM In", NULL),
@@ -76,19 +73,20 @@ static const struct snd_soc_dapm_route base_map[] = {
76static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd) 73static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd)
77{ 74{
78 struct snd_soc_codec *codec = rtd->codec; 75 struct snd_soc_codec *codec = rtd->codec;
76 struct snd_soc_dapm_context *dapm = &codec->dapm;
79 77
80 snd_soc_dapm_new_controls(codec, dapm_widgets, 78 snd_soc_dapm_new_controls(dapm, dapm_widgets,
81 ARRAY_SIZE(dapm_widgets)); 79 ARRAY_SIZE(dapm_widgets));
82 80
83 snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map)); 81 snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map));
84 82
85 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 83 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
86 snd_soc_dapm_enable_pin(codec, "Line In"); 84 snd_soc_dapm_enable_pin(dapm, "Line In");
87 snd_soc_dapm_enable_pin(codec, "Line Out"); 85 snd_soc_dapm_enable_pin(dapm, "Line Out");
88 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 86 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
89 87
90 simtec_audio_init(rtd); 88 simtec_audio_init(rtd);
91 snd_soc_dapm_sync(codec); 89 snd_soc_dapm_sync(dapm);
92 90
93 return 0; 91 return 0;
94} 92}
@@ -99,7 +97,7 @@ static struct snd_soc_dai_link simtec_dai_aic33 = {
99 .codec_name = "tlv320aic3x-codec.0-0x1a", 97 .codec_name = "tlv320aic3x-codec.0-0x1a",
100 .cpu_dai_name = "s3c24xx-i2s", 98 .cpu_dai_name = "s3c24xx-i2s",
101 .codec_dai_name = "tlv320aic3x-hifi", 99 .codec_dai_name = "tlv320aic3x-hifi",
102 .platform_name = "s3c24xx-pcm-audio", 100 .platform_name = "samsung-audio",
103 .init = simtec_hermes_init, 101 .init = simtec_hermes_init,
104}; 102};
105 103
diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
index c0967593510d..fbba4e367729 100644
--- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c
+++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c 1/* sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c
2 * 2 *
3 * Copyright 2009 Simtec Electronics 3 * Copyright 2009 Simtec Electronics
4 * 4 *
@@ -14,11 +14,10 @@
14#include <sound/core.h> 14#include <sound/core.h>
15#include <sound/pcm.h> 15#include <sound/pcm.h>
16#include <sound/soc.h> 16#include <sound/soc.h>
17#include <sound/soc-dapm.h>
18 17
19#include <plat/audio-simtec.h> 18#include <plat/audio-simtec.h>
20 19
21#include "s3c-dma.h" 20#include "dma.h"
22#include "s3c24xx-i2s.h" 21#include "s3c24xx-i2s.h"
23#include "s3c24xx_simtec.h" 22#include "s3c24xx_simtec.h"
24 23
@@ -65,19 +64,20 @@ static const struct snd_soc_dapm_route base_map[] = {
65static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) 64static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd)
66{ 65{
67 struct snd_soc_codec *codec = rtd->codec; 66 struct snd_soc_codec *codec = rtd->codec;
67 struct snd_soc_dapm_context *dapm = &codec->dapm;
68 68
69 snd_soc_dapm_new_controls(codec, dapm_widgets, 69 snd_soc_dapm_new_controls(dapm, dapm_widgets,
70 ARRAY_SIZE(dapm_widgets)); 70 ARRAY_SIZE(dapm_widgets));
71 71
72 snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map)); 72 snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map));
73 73
74 snd_soc_dapm_enable_pin(codec, "Headphone Jack"); 74 snd_soc_dapm_enable_pin(dapm, "Headphone Jack");
75 snd_soc_dapm_enable_pin(codec, "Line In"); 75 snd_soc_dapm_enable_pin(dapm, "Line In");
76 snd_soc_dapm_enable_pin(codec, "Line Out"); 76 snd_soc_dapm_enable_pin(dapm, "Line Out");
77 snd_soc_dapm_enable_pin(codec, "Mic Jack"); 77 snd_soc_dapm_enable_pin(dapm, "Mic Jack");
78 78
79 simtec_audio_init(rtd); 79 simtec_audio_init(rtd);
80 snd_soc_dapm_sync(codec); 80 snd_soc_dapm_sync(dapm);
81 81
82 return 0; 82 return 0;
83} 83}
@@ -88,7 +88,7 @@ static struct snd_soc_dai_link simtec_dai_aic23 = {
88 .codec_name = "tlv320aic3x-codec.0-0x1a", 88 .codec_name = "tlv320aic3x-codec.0-0x1a",
89 .cpu_dai_name = "s3c24xx-i2s", 89 .cpu_dai_name = "s3c24xx-i2s",
90 .codec_dai_name = "tlv320aic3x-hifi", 90 .codec_dai_name = "tlv320aic3x-hifi",
91 .platform_name = "s3c24xx-pcm-audio", 91 .platform_name = "samsung-audio",
92 .init = simtec_tlv320aic23_init, 92 .init = simtec_tlv320aic23_init,
93}; 93};
94 94
diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c
index bd48ffbde880..cdc8ecbcb8ef 100644
--- a/sound/soc/s3c24xx/s3c24xx_uda134x.c
+++ b/sound/soc/samsung/s3c24xx_uda134x.c
@@ -18,13 +18,12 @@
18#include <sound/pcm.h> 18#include <sound/pcm.h>
19#include <sound/pcm_params.h> 19#include <sound/pcm_params.h>
20#include <sound/soc.h> 20#include <sound/soc.h>
21#include <sound/soc-dapm.h>
22#include <sound/s3c24xx_uda134x.h> 21#include <sound/s3c24xx_uda134x.h>
23#include <sound/uda134x.h> 22#include <sound/uda134x.h>
24 23
25#include <plat/regs-iis.h> 24#include <plat/regs-iis.h>
26 25
27#include "s3c-dma.h" 26#include "dma.h"
28#include "s3c24xx-i2s.h" 27#include "s3c24xx-i2s.h"
29#include "../codecs/uda134x.h" 28#include "../codecs/uda134x.h"
30 29
@@ -231,7 +230,7 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = {
231 .codec_dai_name = "uda134x-hifi", 230 .codec_dai_name = "uda134x-hifi",
232 .cpu_dai_name = "s3c24xx-i2s", 231 .cpu_dai_name = "s3c24xx-i2s",
233 .ops = &s3c24xx_uda134x_ops, 232 .ops = &s3c24xx_uda134x_ops,
234 .platform_name = "s3c24xx-pcm-audio", 233 .platform_name = "samsung-audio",
235}; 234};
236 235
237static struct snd_soc_card snd_soc_s3c24xx_uda134x = { 236static struct snd_soc_card snd_soc_s3c24xx_uda134x = {
diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c
index dd20ca7f4681..61e2b5219d42 100644
--- a/sound/soc/s3c24xx/smartq_wm8987.c
+++ b/sound/soc/samsung/smartq_wm8987.c
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/smartq_wm8987.c 1/* sound/soc/samsung/smartq_wm8987.c
2 * 2 *
3 * Copyright 2010 Maurus Cuelenaere <mcuelenaere@gmail.com> 3 * Copyright 2010 Maurus Cuelenaere <mcuelenaere@gmail.com>
4 * 4 *
@@ -19,13 +19,13 @@
19 19
20#include <sound/pcm.h> 20#include <sound/pcm.h>
21#include <sound/pcm_params.h> 21#include <sound/pcm_params.h>
22#include <sound/soc-dapm.h> 22#include <sound/soc.h>
23#include <sound/jack.h> 23#include <sound/jack.h>
24 24
25#include <asm/mach-types.h> 25#include <asm/mach-types.h>
26 26
27#include "s3c-dma.h" 27#include "dma.h"
28#include "s3c64xx-i2s.h" 28#include "i2s.h"
29 29
30#include "../codecs/wm8750.h" 30#include "../codecs/wm8750.h"
31 31
@@ -39,15 +39,11 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream,
39 struct snd_pcm_hw_params *params) 39 struct snd_pcm_hw_params *params)
40{ 40{
41 struct snd_soc_pcm_runtime *rtd = substream->private_data; 41 struct snd_soc_pcm_runtime *rtd = substream->private_data;
42 struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; 42 struct snd_soc_dai *codec_dai = rtd->codec_dai;
43 struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; 43 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
44 struct s3c_i2sv2_rate_calc div;
45 unsigned int clk = 0; 44 unsigned int clk = 0;
46 int ret; 45 int ret;
47 46
48 s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params),
49 s3c_i2sv2_get_clock(cpu_dai));
50
51 switch (params_rate(params)) { 47 switch (params_rate(params)) {
52 case 8000: 48 case 8000:
53 case 16000: 49 case 16000:
@@ -78,20 +74,21 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream,
78 if (ret < 0) 74 if (ret < 0)
79 return ret; 75 return ret;
80 76
81 /* set the codec system clock for DAC and ADC */ 77 /* Use PCLK for I2S signal generation */
82 ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, 78 ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0,
83 SND_SOC_CLOCK_IN); 79 0, SND_SOC_CLOCK_IN);
84 if (ret < 0) 80 if (ret < 0)
85 return ret; 81 return ret;
86 82
87 /* set MCLK division for sample rate */ 83 /* Gate the RCLK output on PAD */
88 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, div.fs_div); 84 ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK,
85 0, SND_SOC_CLOCK_IN);
89 if (ret < 0) 86 if (ret < 0)
90 return ret; 87 return ret;
91 88
92 /* set prescaler division for sample rate */ 89 /* set the codec system clock for DAC and ADC */
93 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_PRESCALER, 90 ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk,
94 div.clk_div - 1); 91 SND_SOC_CLOCK_IN);
95 if (ret < 0) 92 if (ret < 0)
96 return ret; 93 return ret;
97 94
@@ -156,12 +153,14 @@ static const struct snd_soc_dapm_route audio_map[] = {
156 {"LINPUT2", NULL, "Mic Bias"}, 153 {"LINPUT2", NULL, "Mic Bias"},
157}; 154};
158 155
159static int smartq_wm8987_init(struct snd_soc_codec *codec) 156static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd)
160{ 157{
158 struct snd_soc_codec *codec = rtd->codec;
159 struct snd_soc_dapm_context *dapm = &codec->dapm;
161 int err = 0; 160 int err = 0;
162 161
163 /* Add SmartQ specific widgets */ 162 /* Add SmartQ specific widgets */
164 snd_soc_dapm_new_controls(codec, wm8987_dapm_widgets, 163 snd_soc_dapm_new_controls(dapm, wm8987_dapm_widgets,
165 ARRAY_SIZE(wm8987_dapm_widgets)); 164 ARRAY_SIZE(wm8987_dapm_widgets));
166 165
167 /* add SmartQ specific controls */ 166 /* add SmartQ specific controls */
@@ -172,25 +171,25 @@ static int smartq_wm8987_init(struct snd_soc_codec *codec)
172 return err; 171 return err;
173 172
174 /* setup SmartQ specific audio path */ 173 /* setup SmartQ specific audio path */
175 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 174 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
176 175
177 /* set endpoints to not connected */ 176 /* set endpoints to not connected */
178 snd_soc_dapm_nc_pin(codec, "LINPUT1"); 177 snd_soc_dapm_nc_pin(dapm, "LINPUT1");
179 snd_soc_dapm_nc_pin(codec, "RINPUT1"); 178 snd_soc_dapm_nc_pin(dapm, "RINPUT1");
180 snd_soc_dapm_nc_pin(codec, "OUT3"); 179 snd_soc_dapm_nc_pin(dapm, "OUT3");
181 snd_soc_dapm_nc_pin(codec, "ROUT1"); 180 snd_soc_dapm_nc_pin(dapm, "ROUT1");
182 181
183 /* set endpoints to default off mode */ 182 /* set endpoints to default off mode */
184 snd_soc_dapm_enable_pin(codec, "Internal Speaker"); 183 snd_soc_dapm_enable_pin(dapm, "Internal Speaker");
185 snd_soc_dapm_enable_pin(codec, "Internal Mic"); 184 snd_soc_dapm_enable_pin(dapm, "Internal Mic");
186 snd_soc_dapm_disable_pin(codec, "Headphone Jack"); 185 snd_soc_dapm_disable_pin(dapm, "Headphone Jack");
187 186
188 err = snd_soc_dapm_sync(codec); 187 err = snd_soc_dapm_sync(dapm);
189 if (err) 188 if (err)
190 return err; 189 return err;
191 190
192 /* Headphone jack detection */ 191 /* Headphone jack detection */
193 err = snd_soc_jack_new(&snd_soc_smartq, "Headphone Jack", 192 err = snd_soc_jack_new(codec, "Headphone Jack",
194 SND_JACK_HEADPHONE, &smartq_jack); 193 SND_JACK_HEADPHONE, &smartq_jack);
195 if (err) 194 if (err)
196 return err; 195 return err;
@@ -211,9 +210,9 @@ static struct snd_soc_dai_link smartq_dai[] = {
211 { 210 {
212 .name = "wm8987", 211 .name = "wm8987",
213 .stream_name = "SmartQ Hi-Fi", 212 .stream_name = "SmartQ Hi-Fi",
214 .cpu_dai_name = "s3c64xx-i2s.0", 213 .cpu_dai_name = "samsung-i2s.0",
215 .codec_dai_name = "wm8750-hifi", 214 .codec_dai_name = "wm8750-hifi",
216 .platform_name = "s3c24xx-pcm-audio", 215 .platform_name = "samsung-audio",
217 .codec_name = "wm8750-codec.0-0x1a", 216 .codec_name = "wm8750-codec.0-0x1a",
218 .init = smartq_wm8987_init, 217 .init = smartq_wm8987_init,
219 .ops = &smartq_hifi_ops, 218 .ops = &smartq_hifi_ops,
@@ -275,6 +274,7 @@ err_unregister_device:
275 274
276static void __exit smartq_exit(void) 275static void __exit smartq_exit(void)
277{ 276{
277 gpio_free(S3C64XX_GPK(12));
278 snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios), 278 snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios),
279 smartq_jack_gpios); 279 smartq_jack_gpios);
280 280
diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c
index 4613288c2772..3be7e7e92d6e 100644
--- a/sound/soc/s3c24xx/smdk2443_wm9710.c
+++ b/sound/soc/samsung/smdk2443_wm9710.c
@@ -17,10 +17,9 @@
17#include <sound/core.h> 17#include <sound/core.h>
18#include <sound/pcm.h> 18#include <sound/pcm.h>
19#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/soc-dapm.h>
21 20
22#include "s3c-dma.h" 21#include "dma.h"
23#include "s3c-ac97.h" 22#include "ac97.h"
24 23
25static struct snd_soc_card smdk2443; 24static struct snd_soc_card smdk2443;
26 25
@@ -28,10 +27,10 @@ static struct snd_soc_dai_link smdk2443_dai[] = {
28{ 27{
29 .name = "AC97", 28 .name = "AC97",
30 .stream_name = "AC97 HiFi", 29 .stream_name = "AC97 HiFi",
31 .cpu_dai_name = "s3c-ac97", 30 .cpu_dai_name = "samsung-ac97",
32 .codec_dai_name = "ac97-hifi", 31 .codec_dai_name = "ac97-hifi",
33 .codec_name = "ac97-codec", 32 .codec_name = "ac97-codec",
34 .platform_name = "s3c24xx-pcm-audio", 33 .platform_name = "samsung-audio",
35}, 34},
36}; 35};
37 36
diff --git a/sound/soc/s3c24xx/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c
index 761e02b4a6e0..b5c3fad01bb8 100644
--- a/sound/soc/s3c24xx/smdk_spdif.c
+++ b/sound/soc/samsung/smdk_spdif.c
@@ -18,7 +18,7 @@
18 18
19#include <sound/soc.h> 19#include <sound/soc.h>
20 20
21#include "s3c-dma.h" 21#include "dma.h"
22#include "spdif.h" 22#include "spdif.h"
23 23
24/* Audio clock settings are belonged to board specific part. Every 24/* Audio clock settings are belonged to board specific part. Every
@@ -28,7 +28,7 @@
28static int set_audio_clock_heirachy(struct platform_device *pdev) 28static int set_audio_clock_heirachy(struct platform_device *pdev)
29{ 29{
30 struct clk *fout_epll, *mout_epll, *sclk_audio0, *sclk_spdif; 30 struct clk *fout_epll, *mout_epll, *sclk_audio0, *sclk_spdif;
31 int ret; 31 int ret = 0;
32 32
33 fout_epll = clk_get(NULL, "fout_epll"); 33 fout_epll = clk_get(NULL, "fout_epll");
34 if (IS_ERR(fout_epll)) { 34 if (IS_ERR(fout_epll)) {
@@ -152,12 +152,10 @@ static struct snd_soc_ops smdk_spdif_ops = {
152 .hw_params = smdk_hw_params, 152 .hw_params = smdk_hw_params,
153}; 153};
154 154
155static struct snd_soc_card smdk;
156
157static struct snd_soc_dai_link smdk_dai = { 155static struct snd_soc_dai_link smdk_dai = {
158 .name = "S/PDIF", 156 .name = "S/PDIF",
159 .stream_name = "S/PDIF PCM Playback", 157 .stream_name = "S/PDIF PCM Playback",
160 .platform_name = "s3c24xx-pcm-audio", 158 .platform_name = "samsung-audio",
161 .cpu_dai_name = "samsung-spdif", 159 .cpu_dai_name = "samsung-spdif",
162 .codec_dai_name = "dit-hifi", 160 .codec_dai_name = "dit-hifi",
163 .codec_name = "spdif-dit", 161 .codec_name = "spdif-dit",
@@ -183,7 +181,7 @@ static int __init smdk_init(void)
183 181
184 ret = platform_device_add(smdk_snd_spdif_dit_device); 182 ret = platform_device_add(smdk_snd_spdif_dit_device);
185 if (ret) 183 if (ret)
186 goto err2; 184 goto err1;
187 185
188 smdk_snd_spdif_device = platform_device_alloc("soc-audio", -1); 186 smdk_snd_spdif_device = platform_device_alloc("soc-audio", -1);
189 if (!smdk_snd_spdif_device) { 187 if (!smdk_snd_spdif_device) {
@@ -195,17 +193,21 @@ static int __init smdk_init(void)
195 193
196 ret = platform_device_add(smdk_snd_spdif_device); 194 ret = platform_device_add(smdk_snd_spdif_device);
197 if (ret) 195 if (ret)
198 goto err1; 196 goto err3;
199 197
200 /* Set audio clock hierarchy manually */ 198 /* Set audio clock hierarchy manually */
201 ret = set_audio_clock_heirachy(smdk_snd_spdif_device); 199 ret = set_audio_clock_heirachy(smdk_snd_spdif_device);
202 if (ret) 200 if (ret)
203 goto err1; 201 goto err4;
204 202
205 return 0; 203 return 0;
206err1: 204err4:
205 platform_device_del(smdk_snd_spdif_device);
206err3:
207 platform_device_put(smdk_snd_spdif_device); 207 platform_device_put(smdk_snd_spdif_device);
208err2: 208err2:
209 platform_device_del(smdk_snd_spdif_dit_device);
210err1:
209 platform_device_put(smdk_snd_spdif_dit_device); 211 platform_device_put(smdk_snd_spdif_dit_device);
210 return ret; 212 return ret;
211} 213}
@@ -213,6 +215,7 @@ err2:
213static void __exit smdk_exit(void) 215static void __exit smdk_exit(void)
214{ 216{
215 platform_device_unregister(smdk_snd_spdif_device); 217 platform_device_unregister(smdk_snd_spdif_device);
218 platform_device_unregister(smdk_snd_spdif_dit_device);
216} 219}
217 220
218module_init(smdk_init); 221module_init(smdk_init);
diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/samsung/smdk_wm8580.c
index 052e499b68d1..b2cff1a44aed 100644
--- a/sound/soc/s3c24xx/smdk64xx_wm8580.c
+++ b/sound/soc/samsung/smdk_wm8580.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * smdk64xx_wm8580.c 2 * smdk_wm8580.c
3 * 3 *
4 * Copyright (c) 2009 Samsung Electronics Co. Ltd 4 * Copyright (c) 2009 Samsung Electronics Co. Ltd
5 * Author: Jaswinder Singh <jassi.brar@samsung.com> 5 * Author: Jaswinder Singh <jassi.brar@samsung.com>
@@ -16,11 +16,12 @@
16#include <sound/pcm.h> 16#include <sound/pcm.h>
17#include <sound/pcm_params.h> 17#include <sound/pcm_params.h>
18#include <sound/soc.h> 18#include <sound/soc.h>
19#include <sound/soc-dapm.h> 19
20#include <asm/mach-types.h>
20 21
21#include "../codecs/wm8580.h" 22#include "../codecs/wm8580.h"
22#include "s3c-dma.h" 23#include "dma.h"
23#include "s3c64xx-i2s.h" 24#include "i2s.h"
24 25
25/* 26/*
26 * Default CFG switch settings to use this driver: 27 * Default CFG switch settings to use this driver:
@@ -28,10 +29,10 @@
28 * SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On 29 * SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On
29 */ 30 */
30 31
31/* SMDK64XX has a 12MHZ crystal attached to WM8580 */ 32/* SMDK has a 12MHZ crystal attached to WM8580 */
32#define SMDK64XX_WM8580_FREQ 12000000 33#define SMDK_WM8580_FREQ 12000000
33 34
34static int smdk64xx_hw_params(struct snd_pcm_substream *substream, 35static int smdk_hw_params(struct snd_pcm_substream *substream,
35 struct snd_pcm_hw_params *params) 36 struct snd_pcm_hw_params *params)
36{ 37{
37 struct snd_soc_pcm_runtime *rtd = substream->private_data; 38 struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -96,17 +97,6 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
96 if (ret < 0) 97 if (ret < 0)
97 return ret; 98 return ret;
98 99
99 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK,
100 0, SND_SOC_CLOCK_IN);
101 if (ret < 0)
102 return ret;
103
104 /* We use PCLK for basic ops in SoC-Slave mode */
105 ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK,
106 0, SND_SOC_CLOCK_IN);
107 if (ret < 0)
108 return ret;
109
110 /* Set WM8580 to drive MCLK from its PLLA */ 100 /* Set WM8580 to drive MCLK from its PLLA */
111 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, 101 ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK,
112 WM8580_CLKSRC_PLLA); 102 WM8580_CLKSRC_PLLA);
@@ -114,7 +104,7 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
114 return ret; 104 return ret;
115 105
116 ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0, 106 ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0,
117 SMDK64XX_WM8580_FREQ, pll_out); 107 SMDK_WM8580_FREQ, pll_out);
118 if (ret < 0) 108 if (ret < 0)
119 return ret; 109 return ret;
120 110
@@ -123,32 +113,24 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream,
123 if (ret < 0) 113 if (ret < 0)
124 return ret; 114 return ret;
125 115
126 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs);
127 if (ret < 0)
128 return ret;
129
130 ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs);
131 if (ret < 0)
132 return ret;
133
134 return 0; 116 return 0;
135} 117}
136 118
137/* 119/*
138 * SMDK64XX WM8580 DAI operations. 120 * SMDK WM8580 DAI operations.
139 */ 121 */
140static struct snd_soc_ops smdk64xx_ops = { 122static struct snd_soc_ops smdk_ops = {
141 .hw_params = smdk64xx_hw_params, 123 .hw_params = smdk_hw_params,
142}; 124};
143 125
144/* SMDK64xx Playback widgets */ 126/* SMDK Playback widgets */
145static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = { 127static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = {
146 SND_SOC_DAPM_HP("Front", NULL), 128 SND_SOC_DAPM_HP("Front", NULL),
147 SND_SOC_DAPM_HP("Center+Sub", NULL), 129 SND_SOC_DAPM_HP("Center+Sub", NULL),
148 SND_SOC_DAPM_HP("Rear", NULL), 130 SND_SOC_DAPM_HP("Rear", NULL),
149}; 131};
150 132
151/* SMDK64xx Capture widgets */ 133/* SMDK Capture widgets */
152static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = { 134static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = {
153 SND_SOC_DAPM_MIC("MicIn", NULL), 135 SND_SOC_DAPM_MIC("MicIn", NULL),
154 SND_SOC_DAPM_LINE("LineIn", NULL), 136 SND_SOC_DAPM_LINE("LineIn", NULL),
@@ -179,94 +161,132 @@ static const struct snd_soc_dapm_route audio_map_rx[] = {
179 {"Rear", NULL, "VOUT3R"}, 161 {"Rear", NULL, "VOUT3R"},
180}; 162};
181 163
182static int smdk64xx_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) 164static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd)
183{ 165{
184 struct snd_soc_codec *codec = rtd->codec; 166 struct snd_soc_codec *codec = rtd->codec;
167 struct snd_soc_dapm_context *dapm = &codec->dapm;
185 168
186 /* Add smdk64xx specific Capture widgets */ 169 /* Add smdk specific Capture widgets */
187 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt, 170 snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt,
188 ARRAY_SIZE(wm8580_dapm_widgets_cpt)); 171 ARRAY_SIZE(wm8580_dapm_widgets_cpt));
189 172
190 /* Set up PAIFTX audio path */ 173 /* Set up PAIFTX audio path */
191 snd_soc_dapm_add_routes(codec, audio_map_tx, ARRAY_SIZE(audio_map_tx)); 174 snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx));
192 175
193 /* Enabling the microphone requires the fitting of a 0R 176 /* Enabling the microphone requires the fitting of a 0R
194 * resistor to connect the line from the microphone jack. 177 * resistor to connect the line from the microphone jack.
195 */ 178 */
196 snd_soc_dapm_disable_pin(codec, "MicIn"); 179 snd_soc_dapm_disable_pin(dapm, "MicIn");
197 180
198 /* signal a DAPM event */ 181 /* signal a DAPM event */
199 snd_soc_dapm_sync(codec); 182 snd_soc_dapm_sync(dapm);
200 183
201 return 0; 184 return 0;
202} 185}
203 186
204static int smdk64xx_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) 187static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd)
205{ 188{
206 struct snd_soc_codec *codec = rtd->codec; 189 struct snd_soc_codec *codec = rtd->codec;
190 struct snd_soc_dapm_context *dapm = &codec->dapm;
207 191
208 /* Add smdk64xx specific Playback widgets */ 192 /* Add smdk specific Playback widgets */
209 snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk, 193 snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk,
210 ARRAY_SIZE(wm8580_dapm_widgets_pbk)); 194 ARRAY_SIZE(wm8580_dapm_widgets_pbk));
211 195
212 /* Set up PAIFRX audio path */ 196 /* Set up PAIFRX audio path */
213 snd_soc_dapm_add_routes(codec, audio_map_rx, ARRAY_SIZE(audio_map_rx)); 197 snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx));
214 198
215 /* signal a DAPM event */ 199 /* signal a DAPM event */
216 snd_soc_dapm_sync(codec); 200 snd_soc_dapm_sync(dapm);
217 201
218 return 0; 202 return 0;
219} 203}
220 204
221static struct snd_soc_dai_link smdk64xx_dai[] = { 205enum {
222{ /* Primary Playback i/f */ 206 PRI_PLAYBACK = 0,
223 .name = "WM8580 PAIF RX", 207 PRI_CAPTURE,
224 .stream_name = "Playback", 208 SEC_PLAYBACK,
225 .cpu_dai_name = "s3c64xx-iis-v4", 209};
226 .codec_dai_name = "wm8580-hifi-playback", 210
227 .platform_name = "s3c24xx-pcm-audio", 211static struct snd_soc_dai_link smdk_dai[] = {
228 .codec_name = "wm8580-codec.0-001b", 212 [PRI_PLAYBACK] = { /* Primary Playback i/f */
229 .init = smdk64xx_wm8580_init_paifrx, 213 .name = "WM8580 PAIF RX",
230 .ops = &smdk64xx_ops, 214 .stream_name = "Playback",
231}, 215 .cpu_dai_name = "samsung-i2s.0",
232{ /* Primary Capture i/f */ 216 .codec_dai_name = "wm8580-hifi-playback",
233 .name = "WM8580 PAIF TX", 217 .platform_name = "samsung-audio",
234 .stream_name = "Capture", 218 .codec_name = "wm8580-codec.0-001b",
235 .cpu_dai_name = "s3c64xx-iis-v4", 219 .init = smdk_wm8580_init_paifrx,
236 .codec_dai_name = "wm8580-hifi-capture", 220 .ops = &smdk_ops,
237 .platform_name = "s3c24xx-pcm-audio", 221 },
238 .codec_name = "wm8580-codec.0-001b", 222 [PRI_CAPTURE] = { /* Primary Capture i/f */
239 .init = smdk64xx_wm8580_init_paiftx, 223 .name = "WM8580 PAIF TX",
240 .ops = &smdk64xx_ops, 224 .stream_name = "Capture",
241}, 225 .cpu_dai_name = "samsung-i2s.0",
226 .codec_dai_name = "wm8580-hifi-capture",
227 .platform_name = "samsung-audio",
228 .codec_name = "wm8580-codec.0-001b",
229 .init = smdk_wm8580_init_paiftx,
230 .ops = &smdk_ops,
231 },
232 [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */
233 .name = "Sec_FIFO TX",
234 .stream_name = "Playback",
235 .cpu_dai_name = "samsung-i2s.x",
236 .codec_dai_name = "wm8580-hifi-playback",
237 .platform_name = "samsung-audio",
238 .codec_name = "wm8580-codec.0-001b",
239 .init = smdk_wm8580_init_paifrx,
240 .ops = &smdk_ops,
241 },
242}; 242};
243 243
244static struct snd_soc_card smdk64xx = { 244static struct snd_soc_card smdk = {
245 .name = "SMDK64xx 5.1", 245 .name = "SMDK-I2S",
246 .dai_link = smdk64xx_dai, 246 .dai_link = smdk_dai,
247 .num_links = ARRAY_SIZE(smdk64xx_dai), 247 .num_links = 2,
248}; 248};
249 249
250static struct platform_device *smdk64xx_snd_device; 250static struct platform_device *smdk_snd_device;
251 251
252static int __init smdk64xx_audio_init(void) 252static int __init smdk_audio_init(void)
253{ 253{
254 int ret; 254 int ret;
255 char *str;
256
257 if (machine_is_smdkc100() || machine_is_smdk6442()
258 || machine_is_smdkv210() || machine_is_smdkc110()) {
259 smdk.num_links = 3;
260 /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */
261 str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name;
262 str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF;
263 } else if (machine_is_smdk6410()) {
264 str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name;
265 str[strlen(str) - 1] = '2';
266 str = (char *)smdk_dai[PRI_CAPTURE].cpu_dai_name;
267 str[strlen(str) - 1] = '2';
268 }
255 269
256 smdk64xx_snd_device = platform_device_alloc("soc-audio", -1); 270 smdk_snd_device = platform_device_alloc("soc-audio", -1);
257 if (!smdk64xx_snd_device) 271 if (!smdk_snd_device)
258 return -ENOMEM; 272 return -ENOMEM;
259 273
260 platform_set_drvdata(smdk64xx_snd_device, &smdk64xx); 274 platform_set_drvdata(smdk_snd_device, &smdk);
261 ret = platform_device_add(smdk64xx_snd_device); 275 ret = platform_device_add(smdk_snd_device);
262 276
263 if (ret) 277 if (ret)
264 platform_device_put(smdk64xx_snd_device); 278 platform_device_put(smdk_snd_device);
265 279
266 return ret; 280 return ret;
267} 281}
268module_init(smdk64xx_audio_init); 282module_init(smdk_audio_init);
283
284static void __exit smdk_audio_exit(void)
285{
286 platform_device_unregister(smdk_snd_device);
287}
288module_exit(smdk_audio_exit);
269 289
270MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com"); 290MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com");
271MODULE_DESCRIPTION("ALSA SoC SMDK64XX WM8580"); 291MODULE_DESCRIPTION("ALSA SoC SMDK WM8580");
272MODULE_LICENSE("GPL"); 292MODULE_LICENSE("GPL");
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
new file mode 100644
index 000000000000..e7c1009a1e1d
--- /dev/null
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -0,0 +1,176 @@
1/*
2 * smdk_wm8994.c
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
9
10#include "../codecs/wm8994.h"
11
12 /*
13 * Default CFG switch settings to use this driver:
14 * SMDKV310: CFG5-1000, CFG7-111111
15 */
16
17 /*
18 * Configure audio route as :-
19 * $ amixer sset 'DAC1' on,on
20 * $ amixer sset 'Right Headphone Mux' 'DAC'
21 * $ amixer sset 'Left Headphone Mux' 'DAC'
22 * $ amixer sset 'DAC1R Mixer AIF1.1' on
23 * $ amixer sset 'DAC1L Mixer AIF1.1' on
24 * $ amixer sset 'IN2L' on
25 * $ amixer sset 'IN2L PGA IN2LN' on
26 * $ amixer sset 'MIXINL IN2L' on
27 * $ amixer sset 'AIF1ADC1L Mixer ADC/DMIC' on
28 * $ amixer sset 'IN2R' on
29 * $ amixer sset 'IN2R PGA IN2RN' on
30 * $ amixer sset 'MIXINR IN2R' on
31 * $ amixer sset 'AIF1ADC1R Mixer ADC/DMIC' on
32 */
33
34/* SMDK has a 16.934MHZ crystal attached to WM8994 */
35#define SMDK_WM8994_FREQ 16934000
36
37static int smdk_hw_params(struct snd_pcm_substream *substream,
38 struct snd_pcm_hw_params *params)
39{
40 struct snd_soc_pcm_runtime *rtd = substream->private_data;
41 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
42 struct snd_soc_dai *codec_dai = rtd->codec_dai;
43 unsigned int pll_out;
44 int ret;
45
46 /* AIF1CLK should be >=3MHz for optimal performance */
47 if (params_rate(params) == 8000 || params_rate(params) == 11025)
48 pll_out = params_rate(params) * 512;
49 else
50 pll_out = params_rate(params) * 256;
51
52 ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S
53 | SND_SOC_DAIFMT_NB_NF
54 | SND_SOC_DAIFMT_CBM_CFM);
55 if (ret < 0)
56 return ret;
57
58 ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S
59 | SND_SOC_DAIFMT_NB_NF
60 | SND_SOC_DAIFMT_CBM_CFM);
61 if (ret < 0)
62 return ret;
63
64 ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1,
65 SMDK_WM8994_FREQ, pll_out);
66 if (ret < 0)
67 return ret;
68
69 ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1,
70 pll_out, SND_SOC_CLOCK_IN);
71 if (ret < 0)
72 return ret;
73
74 return 0;
75}
76
77/*
78 * SMDK WM8994 DAI operations.
79 */
80static struct snd_soc_ops smdk_ops = {
81 .hw_params = smdk_hw_params,
82};
83
84static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd)
85{
86 struct snd_soc_codec *codec = rtd->codec;
87 struct snd_soc_dapm_context *dapm = &codec->dapm;
88
89 /* HeadPhone */
90 snd_soc_dapm_enable_pin(dapm, "HPOUT1R");
91 snd_soc_dapm_enable_pin(dapm, "HPOUT1L");
92
93 /* MicIn */
94 snd_soc_dapm_enable_pin(dapm, "IN1LN");
95 snd_soc_dapm_enable_pin(dapm, "IN1RN");
96
97 /* LineIn */
98 snd_soc_dapm_enable_pin(dapm, "IN2LN");
99 snd_soc_dapm_enable_pin(dapm, "IN2RN");
100
101 /* Other pins NC */
102 snd_soc_dapm_nc_pin(dapm, "HPOUT2P");
103 snd_soc_dapm_nc_pin(dapm, "HPOUT2N");
104 snd_soc_dapm_nc_pin(dapm, "SPKOUTLN");
105 snd_soc_dapm_nc_pin(dapm, "SPKOUTLP");
106 snd_soc_dapm_nc_pin(dapm, "SPKOUTRP");
107 snd_soc_dapm_nc_pin(dapm, "SPKOUTRN");
108 snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
109 snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
110 snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
111 snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
112 snd_soc_dapm_nc_pin(dapm, "IN1LP");
113 snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
114 snd_soc_dapm_nc_pin(dapm, "IN1RP");
115 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
116
117 snd_soc_dapm_sync(dapm);
118
119 return 0;
120}
121
122static struct snd_soc_dai_link smdk_dai[] = {
123 { /* Primary DAI i/f */
124 .name = "WM8994 AIF1",
125 .stream_name = "Pri_Dai",
126 .cpu_dai_name = "samsung-i2s.0",
127 .codec_dai_name = "wm8994-aif1",
128 .platform_name = "samsung-audio",
129 .codec_name = "wm8994-codec",
130 .init = smdk_wm8994_init_paiftx,
131 .ops = &smdk_ops,
132 }, { /* Sec_Fifo Playback i/f */
133 .name = "Sec_FIFO TX",
134 .stream_name = "Sec_Dai",
135 .cpu_dai_name = "samsung-i2s.4",
136 .codec_dai_name = "wm8994-aif1",
137 .platform_name = "samsung-audio",
138 .codec_name = "wm8994-codec",
139 .ops = &smdk_ops,
140 },
141};
142
143static struct snd_soc_card smdk = {
144 .name = "SMDK-I2S",
145 .dai_link = smdk_dai,
146 .num_links = ARRAY_SIZE(smdk_dai),
147};
148
149static struct platform_device *smdk_snd_device;
150
151static int __init smdk_audio_init(void)
152{
153 int ret;
154
155 smdk_snd_device = platform_device_alloc("soc-audio", -1);
156 if (!smdk_snd_device)
157 return -ENOMEM;
158
159 platform_set_drvdata(smdk_snd_device, &smdk);
160
161 ret = platform_device_add(smdk_snd_device);
162 if (ret)
163 platform_device_put(smdk_snd_device);
164
165 return ret;
166}
167module_init(smdk_audio_init);
168
169static void __exit smdk_audio_exit(void)
170{
171 platform_device_unregister(smdk_snd_device);
172}
173module_exit(smdk_audio_exit);
174
175MODULE_DESCRIPTION("ALSA SoC SMDK WM8994");
176MODULE_LICENSE("GPL");
diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c
index 33ba8fdbcf07..ae5fed6f772f 100644
--- a/sound/soc/s3c24xx/smdk_wm9713.c
+++ b/sound/soc/samsung/smdk_wm9713.c
@@ -15,8 +15,8 @@
15#include <linux/device.h> 15#include <linux/device.h>
16#include <sound/soc.h> 16#include <sound/soc.h>
17 17
18#include "s3c-dma.h" 18#include "dma.h"
19#include "s3c-ac97.h" 19#include "ac97.h"
20 20
21static struct snd_soc_card smdk; 21static struct snd_soc_card smdk;
22 22
@@ -27,6 +27,7 @@ static struct snd_soc_card smdk;
27 * SMDKC100: Set CFG6 1-3 On, CFG7 1 On 27 * SMDKC100: Set CFG6 1-3 On, CFG7 1 On
28 * SMDKC110: Set CFGB10 1-2 Off, CFGB12 1-3 On 28 * SMDKC110: Set CFGB10 1-2 Off, CFGB12 1-3 On
29 * SMDKV210: Set CFGB10 1-2 Off, CFGB12 1-3 On 29 * SMDKV210: Set CFGB10 1-2 Off, CFGB12 1-3 On
30 * SMDKV310: Set CFG2 1-2 Off, CFG4 All On, CFG7 All Off, CFG8 1-On
30 */ 31 */
31 32
32/* 33/*
@@ -45,8 +46,8 @@ static struct snd_soc_card smdk;
45static struct snd_soc_dai_link smdk_dai = { 46static struct snd_soc_dai_link smdk_dai = {
46 .name = "AC97", 47 .name = "AC97",
47 .stream_name = "AC97 PCM", 48 .stream_name = "AC97 PCM",
48 .platform_name = "s3c24xx-pcm-audio", 49 .platform_name = "samsung-audio",
49 .cpu_dai_name = "s3c-ac97", 50 .cpu_dai_name = "samsung-ac97",
50 .codec_dai_name = "wm9713-hifi", 51 .codec_dai_name = "wm9713-hifi",
51 .codec_name = "wm9713-codec", 52 .codec_name = "wm9713-codec",
52}; 53};
@@ -70,24 +71,27 @@ static int __init smdk_init(void)
70 71
71 ret = platform_device_add(smdk_snd_wm9713_device); 72 ret = platform_device_add(smdk_snd_wm9713_device);
72 if (ret) 73 if (ret)
73 goto err; 74 goto err1;
74 75
75 smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1); 76 smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1);
76 if (!smdk_snd_ac97_device) { 77 if (!smdk_snd_ac97_device) {
77 ret = -ENOMEM; 78 ret = -ENOMEM;
78 goto err; 79 goto err2;
79 } 80 }
80 81
81 platform_set_drvdata(smdk_snd_ac97_device, &smdk); 82 platform_set_drvdata(smdk_snd_ac97_device, &smdk);
82 83
83 ret = platform_device_add(smdk_snd_ac97_device); 84 ret = platform_device_add(smdk_snd_ac97_device);
84 if (ret) { 85 if (ret)
85 platform_device_put(smdk_snd_ac97_device); 86 goto err3;
86 goto err;
87 }
88 87
89 return 0; 88 return 0;
90err: 89
90err3:
91 platform_device_put(smdk_snd_ac97_device);
92err2:
93 platform_device_del(smdk_snd_wm9713_device);
94err1:
91 platform_device_put(smdk_snd_wm9713_device); 95 platform_device_put(smdk_snd_wm9713_device);
92 return ret; 96 return ret;
93} 97}
diff --git a/sound/soc/s3c24xx/spdif.c b/sound/soc/samsung/spdif.c
index ce554e9cabcc..f0816404ea3e 100644
--- a/sound/soc/s3c24xx/spdif.c
+++ b/sound/soc/samsung/spdif.c
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/spdif.c 1/* sound/soc/samsung/spdif.c
2 * 2 *
3 * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver 3 * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver
4 * 4 *
@@ -20,7 +20,7 @@
20#include <plat/audio.h> 20#include <plat/audio.h>
21#include <mach/dma.h> 21#include <mach/dma.h>
22 22
23#include "s3c-dma.h" 23#include "dma.h"
24#include "spdif.h" 24#include "spdif.h"
25 25
26/* Registers */ 26/* Registers */
diff --git a/sound/soc/s3c24xx/spdif.h b/sound/soc/samsung/spdif.h
index 3ed55592710f..4f72cb446dbf 100644
--- a/sound/soc/s3c24xx/spdif.h
+++ b/sound/soc/samsung/spdif.h
@@ -1,4 +1,4 @@
1/* sound/soc/s3c24xx/spdif.h 1/* sound/soc/samsung/spdif.h
2 * 2 *
3 * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver 3 * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver
4 * 4 *
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index 7f0a496e07ce..d8e06a607a22 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -48,7 +48,7 @@ config SND_SH7760_AC97
48 48
49config SND_FSI_AK4642 49config SND_FSI_AK4642
50 tristate "FSI-AK4642 sound support" 50 tristate "FSI-AK4642 sound support"
51 depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE 51 depends on SND_SOC_SH4_FSI && I2C
52 select SND_SOC_AK4642 52 select SND_SOC_AK4642
53 help 53 help
54 This option enables generic sound support for the 54 This option enables generic sound support for the
@@ -56,7 +56,7 @@ config SND_FSI_AK4642
56 56
57config SND_FSI_DA7210 57config SND_FSI_DA7210
58 tristate "FSI-DA7210 sound support" 58 tristate "FSI-DA7210 sound support"
59 depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE 59 depends on SND_SOC_SH4_FSI && I2C
60 select SND_SOC_DA7210 60 select SND_SOC_DA7210
61 help 61 help
62 This option enables generic sound support for the 62 This option enables generic sound support for the
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c
index d96602de71de..a14820ac9665 100644
--- a/sound/soc/sh/fsi-ak4642.c
+++ b/sound/soc/sh/fsi-ak4642.c
@@ -12,6 +12,14 @@
12#include <linux/platform_device.h> 12#include <linux/platform_device.h>
13#include <sound/sh_fsi.h> 13#include <sound/sh_fsi.h>
14 14
15struct fsi_ak4642_data {
16 const char *name;
17 const char *card;
18 const char *cpu_dai;
19 const char *codec;
20 const char *platform;
21};
22
15static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd) 23static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
16{ 24{
17 struct snd_soc_dai *dai = rtd->codec_dai; 25 struct snd_soc_dai *dai = rtd->codec_dai;
@@ -27,37 +35,42 @@ static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd)
27} 35}
28 36
29static struct snd_soc_dai_link fsi_dai_link = { 37static struct snd_soc_dai_link fsi_dai_link = {
30 .name = "AK4642",
31 .stream_name = "AK4642",
32 .cpu_dai_name = "fsia-dai", /* fsi A */
33 .codec_dai_name = "ak4642-hifi", 38 .codec_dai_name = "ak4642-hifi",
34#ifdef CONFIG_MACH_AP4EVB
35 .platform_name = "sh_fsi2",
36 .codec_name = "ak4642-codec.0-0013",
37#else
38 .platform_name = "sh_fsi.0",
39 .codec_name = "ak4642-codec.0-0012",
40#endif
41 .init = fsi_ak4642_dai_init, 39 .init = fsi_ak4642_dai_init,
42 .ops = NULL,
43}; 40};
44 41
45static struct snd_soc_card fsi_soc_card = { 42static struct snd_soc_card fsi_soc_card = {
46 .name = "FSI (AK4642)",
47 .dai_link = &fsi_dai_link, 43 .dai_link = &fsi_dai_link,
48 .num_links = 1, 44 .num_links = 1,
49}; 45};
50 46
51static struct platform_device *fsi_snd_device; 47static struct platform_device *fsi_snd_device;
52 48
53static int __init fsi_ak4642_init(void) 49static int fsi_ak4642_probe(struct platform_device *pdev)
54{ 50{
55 int ret = -ENOMEM; 51 int ret = -ENOMEM;
52 const struct platform_device_id *id_entry;
53 struct fsi_ak4642_data *pdata;
54
55 id_entry = pdev->id_entry;
56 if (!id_entry) {
57 dev_err(&pdev->dev, "unknown fsi ak4642\n");
58 return -ENODEV;
59 }
60
61 pdata = (struct fsi_ak4642_data *)id_entry->driver_data;
56 62
57 fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_A); 63 fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_A);
58 if (!fsi_snd_device) 64 if (!fsi_snd_device)
59 goto out; 65 goto out;
60 66
67 fsi_dai_link.name = pdata->name;
68 fsi_dai_link.stream_name = pdata->name;
69 fsi_dai_link.cpu_dai_name = pdata->cpu_dai;
70 fsi_dai_link.platform_name = pdata->platform;
71 fsi_dai_link.codec_name = pdata->codec;
72 fsi_soc_card.name = pdata->card;
73
61 platform_set_drvdata(fsi_snd_device, &fsi_soc_card); 74 platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
62 ret = platform_device_add(fsi_snd_device); 75 ret = platform_device_add(fsi_snd_device);
63 76
@@ -68,9 +81,108 @@ out:
68 return ret; 81 return ret;
69} 82}
70 83
71static void __exit fsi_ak4642_exit(void) 84static int fsi_ak4642_remove(struct platform_device *pdev)
72{ 85{
73 platform_device_unregister(fsi_snd_device); 86 platform_device_unregister(fsi_snd_device);
87 return 0;
88}
89
90static struct fsi_ak4642_data fsi_a_ak4642 = {
91 .name = "AK4642",
92 .card = "FSIA (AK4642)",
93 .cpu_dai = "fsia-dai",
94 .codec = "ak4642-codec.0-0012",
95 .platform = "sh_fsi.0",
96};
97
98static struct fsi_ak4642_data fsi_b_ak4642 = {
99 .name = "AK4642",
100 .card = "FSIB (AK4642)",
101 .cpu_dai = "fsib-dai",
102 .codec = "ak4642-codec.0-0012",
103 .platform = "sh_fsi.0",
104};
105
106static struct fsi_ak4642_data fsi_a_ak4643 = {
107 .name = "AK4643",
108 .card = "FSIA (AK4643)",
109 .cpu_dai = "fsia-dai",
110 .codec = "ak4642-codec.0-0013",
111 .platform = "sh_fsi.0",
112};
113
114static struct fsi_ak4642_data fsi_b_ak4643 = {
115 .name = "AK4643",
116 .card = "FSIB (AK4643)",
117 .cpu_dai = "fsib-dai",
118 .codec = "ak4642-codec.0-0013",
119 .platform = "sh_fsi.0",
120};
121
122static struct fsi_ak4642_data fsi2_a_ak4642 = {
123 .name = "AK4642",
124 .card = "FSI2A (AK4642)",
125 .cpu_dai = "fsia-dai",
126 .codec = "ak4642-codec.0-0012",
127 .platform = "sh_fsi2",
128};
129
130static struct fsi_ak4642_data fsi2_b_ak4642 = {
131 .name = "AK4642",
132 .card = "FSI2B (AK4642)",
133 .cpu_dai = "fsib-dai",
134 .codec = "ak4642-codec.0-0012",
135 .platform = "sh_fsi2",
136};
137
138static struct fsi_ak4642_data fsi2_a_ak4643 = {
139 .name = "AK4643",
140 .card = "FSI2A (AK4643)",
141 .cpu_dai = "fsia-dai",
142 .codec = "ak4642-codec.0-0013",
143 .platform = "sh_fsi2",
144};
145
146static struct fsi_ak4642_data fsi2_b_ak4643 = {
147 .name = "AK4643",
148 .card = "FSI2B (AK4643)",
149 .cpu_dai = "fsib-dai",
150 .codec = "ak4642-codec.0-0013",
151 .platform = "sh_fsi2",
152};
153
154static struct platform_device_id fsi_id_table[] = {
155 /* FSI */
156 { "sh_fsi_a_ak4642", (kernel_ulong_t)&fsi_a_ak4642 },
157 { "sh_fsi_b_ak4642", (kernel_ulong_t)&fsi_b_ak4642 },
158 { "sh_fsi_a_ak4643", (kernel_ulong_t)&fsi_a_ak4643 },
159 { "sh_fsi_b_ak4643", (kernel_ulong_t)&fsi_b_ak4643 },
160
161 /* FSI 2 */
162 { "sh_fsi2_a_ak4642", (kernel_ulong_t)&fsi2_a_ak4642 },
163 { "sh_fsi2_b_ak4642", (kernel_ulong_t)&fsi2_b_ak4642 },
164 { "sh_fsi2_a_ak4643", (kernel_ulong_t)&fsi2_a_ak4643 },
165 { "sh_fsi2_b_ak4643", (kernel_ulong_t)&fsi2_b_ak4643 },
166 {},
167};
168
169static struct platform_driver fsi_ak4642 = {
170 .driver = {
171 .name = "fsi-ak4642-audio",
172 },
173 .probe = fsi_ak4642_probe,
174 .remove = fsi_ak4642_remove,
175 .id_table = fsi_id_table,
176};
177
178static int __init fsi_ak4642_init(void)
179{
180 return platform_driver_register(&fsi_ak4642);
181}
182
183static void __exit fsi_ak4642_exit(void)
184{
185 platform_driver_unregister(&fsi_ak4642);
74} 186}
75 187
76module_init(fsi_ak4642_init); 188module_init(fsi_ak4642_init);
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c
index a6adb6e43250..e8df9da92f71 100644
--- a/sound/soc/sh/fsi-da7210.c
+++ b/sound/soc/sh/fsi-da7210.c
@@ -18,7 +18,7 @@ static int fsi_da7210_init(struct snd_soc_pcm_runtime *rtd)
18 struct snd_soc_dai *dai = rtd->codec_dai; 18 struct snd_soc_dai *dai = rtd->codec_dai;
19 19
20 return snd_soc_dai_set_fmt(dai, 20 return snd_soc_dai_set_fmt(dai,
21 SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | 21 SND_SOC_DAIFMT_I2S |
22 SND_SOC_DAIFMT_CBM_CFM); 22 SND_SOC_DAIFMT_CBM_CFM);
23} 23}
24 24
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 4c2404b1b862..2b06402801ef 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -19,20 +19,26 @@
19#include <sound/soc.h> 19#include <sound/soc.h>
20#include <sound/sh_fsi.h> 20#include <sound/sh_fsi.h>
21 21
22#define DO_FMT 0x0000 22/* PortA/PortB register */
23#define DOFF_CTL 0x0004 23#define REG_DO_FMT 0x0000
24#define DOFF_ST 0x0008 24#define REG_DOFF_CTL 0x0004
25#define DI_FMT 0x000C 25#define REG_DOFF_ST 0x0008
26#define DIFF_CTL 0x0010 26#define REG_DI_FMT 0x000C
27#define DIFF_ST 0x0014 27#define REG_DIFF_CTL 0x0010
28#define CKG1 0x0018 28#define REG_DIFF_ST 0x0014
29#define CKG2 0x001C 29#define REG_CKG1 0x0018
30#define DIDT 0x0020 30#define REG_CKG2 0x001C
31#define DODT 0x0024 31#define REG_DIDT 0x0020
32#define MUTE_ST 0x0028 32#define REG_DODT 0x0024
33#define OUT_SEL 0x0030 33#define REG_MUTE_ST 0x0028
34#define REG_END OUT_SEL 34#define REG_OUT_SEL 0x0030
35 35
36/* master register */
37#define MST_CLK_RST 0x0210
38#define MST_SOFT_RST 0x0214
39#define MST_FIFO_SZ 0x0218
40
41/* core register (depend on FSI version) */
36#define A_MST_CTLR 0x0180 42#define A_MST_CTLR 0x0180
37#define B_MST_CTLR 0x01A0 43#define B_MST_CTLR 0x01A0
38#define CPU_INT_ST 0x01F4 44#define CPU_INT_ST 0x01F4
@@ -41,22 +47,23 @@
41#define INT_ST 0x0200 47#define INT_ST 0x0200
42#define IEMSK 0x0204 48#define IEMSK 0x0204
43#define IMSK 0x0208 49#define IMSK 0x0208
44#define MUTE 0x020C
45#define CLK_RST 0x0210
46#define SOFT_RST 0x0214
47#define FIFO_SZ 0x0218
48#define MREG_START A_MST_CTLR
49#define MREG_END FIFO_SZ
50 50
51/* DO_FMT */ 51/* DO_FMT */
52/* DI_FMT */ 52/* DI_FMT */
53#define CR_BWS_24 (0x0 << 20) /* FSI2 */
54#define CR_BWS_16 (0x1 << 20) /* FSI2 */
55#define CR_BWS_20 (0x2 << 20) /* FSI2 */
56
57#define CR_DTMD_PCM (0x0 << 8) /* FSI2 */
58#define CR_DTMD_SPDIF_PCM (0x1 << 8) /* FSI2 */
59#define CR_DTMD_SPDIF_STREAM (0x2 << 8) /* FSI2 */
60
53#define CR_MONO (0x0 << 4) 61#define CR_MONO (0x0 << 4)
54#define CR_MONO_D (0x1 << 4) 62#define CR_MONO_D (0x1 << 4)
55#define CR_PCM (0x2 << 4) 63#define CR_PCM (0x2 << 4)
56#define CR_I2S (0x3 << 4) 64#define CR_I2S (0x3 << 4)
57#define CR_TDM (0x4 << 4) 65#define CR_TDM (0x4 << 4)
58#define CR_TDM_D (0x5 << 4) 66#define CR_TDM_D (0x5 << 4)
59#define CR_SPDIF 0x00100120
60 67
61/* DOFF_CTL */ 68/* DOFF_CTL */
62/* DIFF_CTL */ 69/* DIFF_CTL */
@@ -93,6 +100,10 @@
93#define IR (1 << 4) /* Interrupt Reset */ 100#define IR (1 << 4) /* Interrupt Reset */
94#define FSISR (1 << 0) /* Software Reset */ 101#define FSISR (1 << 0) /* Software Reset */
95 102
103/* OUT_SEL (FSI2) */
104#define DMMD (1 << 4) /* SPDIF output timing 0: Biphase only */
105 /* 1: Biphase and serial */
106
96/* FIFO_SZ */ 107/* FIFO_SZ */
97#define FIFO_SZ_MASK 0x7 108#define FIFO_SZ_MASK 0x7
98 109
@@ -123,6 +134,9 @@ struct fsi_stream {
123 int buff_len; 134 int buff_len;
124 int period_len; 135 int period_len;
125 int period_num; 136 int period_num;
137
138 int uerr_num;
139 int oerr_num;
126}; 140};
127 141
128struct fsi_priv { 142struct fsi_priv {
@@ -133,8 +147,6 @@ struct fsi_priv {
133 struct fsi_stream capture; 147 struct fsi_stream capture;
134 148
135 long rate; 149 long rate;
136
137 u32 mst_ctrl;
138}; 150};
139 151
140struct fsi_core { 152struct fsi_core {
@@ -143,6 +155,8 @@ struct fsi_core {
143 u32 int_st; 155 u32 int_st;
144 u32 iemsk; 156 u32 iemsk;
145 u32 imsk; 157 u32 imsk;
158 u32 a_mclk;
159 u32 b_mclk;
146}; 160};
147 161
148struct fsi_master { 162struct fsi_master {
@@ -182,62 +196,22 @@ static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
182 __fsi_reg_write(reg, val); 196 __fsi_reg_write(reg, val);
183} 197}
184 198
185static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data) 199#define fsi_reg_write(p, r, d)\
186{ 200 __fsi_reg_write((u32)(p->base + REG_##r), d)
187 if (reg > REG_END) {
188 pr_err("fsi: register access err (%s)\n", __func__);
189 return;
190 }
191 201
192 __fsi_reg_write((u32)(fsi->base + reg), data); 202#define fsi_reg_read(p, r)\
193} 203 __fsi_reg_read((u32)(p->base + REG_##r))
194 204
195static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg) 205#define fsi_reg_mask_set(p, r, m, d)\
196{ 206 __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d)
197 if (reg > REG_END) {
198 pr_err("fsi: register access err (%s)\n", __func__);
199 return 0;
200 }
201 207
202 return __fsi_reg_read((u32)(fsi->base + reg)); 208#define fsi_master_read(p, r) _fsi_master_read(p, MST_##r)
203} 209#define fsi_core_read(p, r) _fsi_master_read(p, p->core->r)
204 210static u32 _fsi_master_read(struct fsi_master *master, u32 reg)
205static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
206{
207 if (reg > REG_END) {
208 pr_err("fsi: register access err (%s)\n", __func__);
209 return;
210 }
211
212 __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
213}
214
215static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
216{
217 unsigned long flags;
218
219 if ((reg < MREG_START) ||
220 (reg > MREG_END)) {
221 pr_err("fsi: register access err (%s)\n", __func__);
222 return;
223 }
224
225 spin_lock_irqsave(&master->lock, flags);
226 __fsi_reg_write((u32)(master->base + reg), data);
227 spin_unlock_irqrestore(&master->lock, flags);
228}
229
230static u32 fsi_master_read(struct fsi_master *master, u32 reg)
231{ 211{
232 u32 ret; 212 u32 ret;
233 unsigned long flags; 213 unsigned long flags;
234 214
235 if ((reg < MREG_START) ||
236 (reg > MREG_END)) {
237 pr_err("fsi: register access err (%s)\n", __func__);
238 return 0;
239 }
240
241 spin_lock_irqsave(&master->lock, flags); 215 spin_lock_irqsave(&master->lock, flags);
242 ret = __fsi_reg_read((u32)(master->base + reg)); 216 ret = __fsi_reg_read((u32)(master->base + reg));
243 spin_unlock_irqrestore(&master->lock, flags); 217 spin_unlock_irqrestore(&master->lock, flags);
@@ -245,17 +219,13 @@ static u32 fsi_master_read(struct fsi_master *master, u32 reg)
245 return ret; 219 return ret;
246} 220}
247 221
248static void fsi_master_mask_set(struct fsi_master *master, 222#define fsi_master_mask_set(p, r, m, d) _fsi_master_mask_set(p, MST_##r, m, d)
223#define fsi_core_mask_set(p, r, m, d) _fsi_master_mask_set(p, p->core->r, m, d)
224static void _fsi_master_mask_set(struct fsi_master *master,
249 u32 reg, u32 mask, u32 data) 225 u32 reg, u32 mask, u32 data)
250{ 226{
251 unsigned long flags; 227 unsigned long flags;
252 228
253 if ((reg < MREG_START) ||
254 (reg > MREG_END)) {
255 pr_err("fsi: register access err (%s)\n", __func__);
256 return;
257 }
258
259 spin_lock_irqsave(&master->lock, flags); 229 spin_lock_irqsave(&master->lock, flags);
260 __fsi_reg_mask_set((u32)(master->base + reg), mask, data); 230 __fsi_reg_mask_set((u32)(master->base + reg), mask, data);
261 spin_unlock_irqrestore(&master->lock, flags); 231 spin_unlock_irqrestore(&master->lock, flags);
@@ -359,27 +329,41 @@ static void fsi_stream_push(struct fsi_priv *fsi,
359 io->buff_offset = 0; 329 io->buff_offset = 0;
360 io->period_len = period_len; 330 io->period_len = period_len;
361 io->period_num = 0; 331 io->period_num = 0;
332 io->oerr_num = -1; /* ignore 1st err */
333 io->uerr_num = -1; /* ignore 1st err */
362} 334}
363 335
364static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) 336static void fsi_stream_pop(struct fsi_priv *fsi, int is_play)
365{ 337{
366 struct fsi_stream *io = fsi_get_stream(fsi, is_play); 338 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
339 struct snd_soc_dai *dai = fsi_get_dai(io->substream);
340
341
342 if (io->oerr_num > 0)
343 dev_err(dai->dev, "over_run = %d\n", io->oerr_num);
344
345 if (io->uerr_num > 0)
346 dev_err(dai->dev, "under_run = %d\n", io->uerr_num);
367 347
368 io->substream = NULL; 348 io->substream = NULL;
369 io->buff_len = 0; 349 io->buff_len = 0;
370 io->buff_offset = 0; 350 io->buff_offset = 0;
371 io->period_len = 0; 351 io->period_len = 0;
372 io->period_num = 0; 352 io->period_num = 0;
353 io->oerr_num = 0;
354 io->uerr_num = 0;
373} 355}
374 356
375static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) 357static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play)
376{ 358{
377 u32 status; 359 u32 status;
378 u32 reg = is_play ? DOFF_ST : DIFF_ST;
379 struct fsi_stream *io = fsi_get_stream(fsi, is_play); 360 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
380 int data_num; 361 int data_num;
381 362
382 status = fsi_reg_read(fsi, reg); 363 status = is_play ?
364 fsi_reg_read(fsi, DOFF_ST) :
365 fsi_reg_read(fsi, DIFF_ST);
366
383 data_num = 0x1ff & (status >> 8); 367 data_num = 0x1ff & (status >> 8);
384 data_num *= io->chan_num; 368 data_num *= io->chan_num;
385 369
@@ -406,6 +390,27 @@ static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play)
406 return frames_to_bytes(runtime, 1) / io->chan_num; 390 return frames_to_bytes(runtime, 1) / io->chan_num;
407} 391}
408 392
393static void fsi_count_fifo_err(struct fsi_priv *fsi)
394{
395 u32 ostatus = fsi_reg_read(fsi, DOFF_ST);
396 u32 istatus = fsi_reg_read(fsi, DIFF_ST);
397
398 if (ostatus & ERR_OVER)
399 fsi->playback.oerr_num++;
400
401 if (ostatus & ERR_UNDER)
402 fsi->playback.uerr_num++;
403
404 if (istatus & ERR_OVER)
405 fsi->capture.oerr_num++;
406
407 if (istatus & ERR_UNDER)
408 fsi->capture.uerr_num++;
409
410 fsi_reg_write(fsi, DOFF_ST, 0);
411 fsi_reg_write(fsi, DIFF_ST, 0);
412}
413
409/* 414/*
410 * dma function 415 * dma function
411 */ 416 */
@@ -473,8 +478,8 @@ static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
473 u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); 478 u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
474 struct fsi_master *master = fsi_get_master(fsi); 479 struct fsi_master *master = fsi_get_master(fsi);
475 480
476 fsi_master_mask_set(master, master->core->imsk, data, data); 481 fsi_core_mask_set(master, imsk, data, data);
477 fsi_master_mask_set(master, master->core->iemsk, data, data); 482 fsi_core_mask_set(master, iemsk, data, data);
478} 483}
479 484
480static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 485static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
@@ -482,18 +487,13 @@ static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
482 u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); 487 u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play));
483 struct fsi_master *master = fsi_get_master(fsi); 488 struct fsi_master *master = fsi_get_master(fsi);
484 489
485 fsi_master_mask_set(master, master->core->imsk, data, 0); 490 fsi_core_mask_set(master, imsk, data, 0);
486 fsi_master_mask_set(master, master->core->iemsk, data, 0); 491 fsi_core_mask_set(master, iemsk, data, 0);
487} 492}
488 493
489static u32 fsi_irq_get_status(struct fsi_master *master) 494static u32 fsi_irq_get_status(struct fsi_master *master)
490{ 495{
491 return fsi_master_read(master, master->core->int_st); 496 return fsi_core_read(master, int_st);
492}
493
494static void fsi_irq_clear_all_status(struct fsi_master *master)
495{
496 fsi_master_write(master, master->core->int_st, 0);
497} 497}
498 498
499static void fsi_irq_clear_status(struct fsi_priv *fsi) 499static void fsi_irq_clear_status(struct fsi_priv *fsi)
@@ -505,7 +505,7 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
505 data |= AB_IO(1, fsi_get_port_shift(fsi, 1)); 505 data |= AB_IO(1, fsi_get_port_shift(fsi, 1));
506 506
507 /* clear interrupt factor */ 507 /* clear interrupt factor */
508 fsi_master_mask_set(master, master->core->int_st, data, 0); 508 fsi_core_mask_set(master, int_st, data, 0);
509} 509}
510 510
511/* 511/*
@@ -516,17 +516,19 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi)
516static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) 516static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable)
517{ 517{
518 struct fsi_master *master = fsi_get_master(fsi); 518 struct fsi_master *master = fsi_get_master(fsi);
519 u32 val = BP | SE; 519 u32 mask, val;
520 520
521 if (master->core->ver < 2) { 521 if (master->core->ver < 2) {
522 pr_err("fsi: register access err (%s)\n", __func__); 522 pr_err("fsi: register access err (%s)\n", __func__);
523 return; 523 return;
524 } 524 }
525 525
526 if (enable) 526 mask = BP | SE;
527 fsi_master_mask_set(master, fsi->mst_ctrl, val, val); 527 val = enable ? mask : 0;
528 else 528
529 fsi_master_mask_set(master, fsi->mst_ctrl, val, 0); 529 fsi_is_port_a(fsi) ?
530 fsi_core_mask_set(master, a_mclk, mask, val) :
531 fsi_core_mask_set(master, b_mclk, mask, val);
530} 532}
531 533
532/* 534/*
@@ -550,7 +552,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
550{ 552{
551 struct fsi_master *master = fsi_get_master(fsi); 553 struct fsi_master *master = fsi_get_master(fsi);
552 struct fsi_stream *io = fsi_get_stream(fsi, is_play); 554 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
553 u32 ctrl, shift, i; 555 u32 shift, i;
554 556
555 /* get on-chip RAM capacity */ 557 /* get on-chip RAM capacity */
556 shift = fsi_master_read(master, FIFO_SZ); 558 shift = fsi_master_read(master, FIFO_SZ);
@@ -583,13 +585,17 @@ static void fsi_fifo_init(struct fsi_priv *fsi,
583 dev_dbg(dai->dev, "%d channel %d store\n", 585 dev_dbg(dai->dev, "%d channel %d store\n",
584 io->chan_num, io->fifo_max_num); 586 io->chan_num, io->fifo_max_num);
585 587
586 ctrl = is_play ? DOFF_CTL : DIFF_CTL; 588 /*
587 589 * set interrupt generation factor
588 /* set interrupt generation factor */ 590 * clear FIFO
589 fsi_reg_write(fsi, ctrl, IRQ_HALF); 591 */
590 592 if (is_play) {
591 /* clear FIFO */ 593 fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF);
592 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 594 fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR);
595 } else {
596 fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF);
597 fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR);
598 }
593} 599}
594 600
595static void fsi_soft_all_reset(struct fsi_master *master) 601static void fsi_soft_all_reset(struct fsi_master *master)
@@ -604,13 +610,12 @@ static void fsi_soft_all_reset(struct fsi_master *master)
604 mdelay(10); 610 mdelay(10);
605} 611}
606 612
607static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream) 613static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream)
608{ 614{
609 struct snd_pcm_runtime *runtime; 615 struct snd_pcm_runtime *runtime;
610 struct snd_pcm_substream *substream = NULL; 616 struct snd_pcm_substream *substream = NULL;
611 int is_play = fsi_stream_is_play(stream); 617 int is_play = fsi_stream_is_play(stream);
612 struct fsi_stream *io = fsi_get_stream(fsi, is_play); 618 struct fsi_stream *io = fsi_get_stream(fsi, is_play);
613 u32 status_reg = is_play ? DOFF_ST : DIFF_ST;
614 int data_residue_num; 619 int data_residue_num;
615 int data_num; 620 int data_num;
616 int data_num_max; 621 int data_num_max;
@@ -698,35 +703,20 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream)
698 /* update buff_offset */ 703 /* update buff_offset */
699 io->buff_offset += fsi_num2offset(data_num, ch_width); 704 io->buff_offset += fsi_num2offset(data_num, ch_width);
700 705
701 /* check fifo status */
702 if (!startup) {
703 struct snd_soc_dai *dai = fsi_get_dai(substream);
704 u32 status = fsi_reg_read(fsi, status_reg);
705
706 if (status & ERR_OVER)
707 dev_err(dai->dev, "over run\n");
708 if (status & ERR_UNDER)
709 dev_err(dai->dev, "under run\n");
710 }
711 fsi_reg_write(fsi, status_reg, 0);
712
713 /* re-enable irq */
714 fsi_irq_enable(fsi, is_play);
715
716 if (over_period) 706 if (over_period)
717 snd_pcm_period_elapsed(substream); 707 snd_pcm_period_elapsed(substream);
718 708
719 return 0; 709 return 0;
720} 710}
721 711
722static int fsi_data_pop(struct fsi_priv *fsi, int startup) 712static int fsi_data_pop(struct fsi_priv *fsi)
723{ 713{
724 return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_CAPTURE); 714 return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE);
725} 715}
726 716
727static int fsi_data_push(struct fsi_priv *fsi, int startup) 717static int fsi_data_push(struct fsi_priv *fsi)
728{ 718{
729 return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_PLAYBACK); 719 return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK);
730} 720}
731 721
732static irqreturn_t fsi_interrupt(int irq, void *data) 722static irqreturn_t fsi_interrupt(int irq, void *data)
@@ -739,15 +729,19 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
739 fsi_master_mask_set(master, SOFT_RST, IR, IR); 729 fsi_master_mask_set(master, SOFT_RST, IR, IR);
740 730
741 if (int_st & AB_IO(1, AO_SHIFT)) 731 if (int_st & AB_IO(1, AO_SHIFT))
742 fsi_data_push(&master->fsia, 0); 732 fsi_data_push(&master->fsia);
743 if (int_st & AB_IO(1, BO_SHIFT)) 733 if (int_st & AB_IO(1, BO_SHIFT))
744 fsi_data_push(&master->fsib, 0); 734 fsi_data_push(&master->fsib);
745 if (int_st & AB_IO(1, AI_SHIFT)) 735 if (int_st & AB_IO(1, AI_SHIFT))
746 fsi_data_pop(&master->fsia, 0); 736 fsi_data_pop(&master->fsia);
747 if (int_st & AB_IO(1, BI_SHIFT)) 737 if (int_st & AB_IO(1, BI_SHIFT))
748 fsi_data_pop(&master->fsib, 0); 738 fsi_data_pop(&master->fsib);
739
740 fsi_count_fifo_err(&master->fsia);
741 fsi_count_fifo_err(&master->fsib);
749 742
750 fsi_irq_clear_all_status(master); 743 fsi_irq_clear_status(&master->fsia);
744 fsi_irq_clear_status(&master->fsib);
751 745
752 return IRQ_HANDLED; 746 return IRQ_HANDLED;
753} 747}
@@ -764,7 +758,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
764 struct fsi_stream *io; 758 struct fsi_stream *io;
765 u32 flags = fsi_get_info_flags(fsi); 759 u32 flags = fsi_get_info_flags(fsi);
766 u32 fmt; 760 u32 fmt;
767 u32 reg;
768 u32 data; 761 u32 data;
769 int is_play = fsi_is_play(substream); 762 int is_play = fsi_is_play(substream);
770 int is_master; 763 int is_master;
@@ -796,7 +789,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
796 789
797 /* do fmt, di fmt */ 790 /* do fmt, di fmt */
798 data = 0; 791 data = 0;
799 reg = is_play ? DO_FMT : DI_FMT;
800 fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags); 792 fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags);
801 switch (fmt) { 793 switch (fmt) {
802 case SH_FSI_FMT_MONO: 794 case SH_FSI_FMT_MONO:
@@ -830,16 +822,18 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
830 dev_err(dai->dev, "This FSI can not use SPDIF\n"); 822 dev_err(dai->dev, "This FSI can not use SPDIF\n");
831 return -EINVAL; 823 return -EINVAL;
832 } 824 }
833 data = CR_SPDIF; 825 data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
834 io->chan_num = 2; 826 io->chan_num = 2;
835 fsi_spdif_clk_ctrl(fsi, 1); 827 fsi_spdif_clk_ctrl(fsi, 1);
836 fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010); 828 fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD);
837 break; 829 break;
838 default: 830 default:
839 dev_err(dai->dev, "unknown format.\n"); 831 dev_err(dai->dev, "unknown format.\n");
840 return -EINVAL; 832 return -EINVAL;
841 } 833 }
842 fsi_reg_write(fsi, reg, data); 834 is_play ?
835 fsi_reg_write(fsi, DO_FMT, data) :
836 fsi_reg_write(fsi, DI_FMT, data);
843 837
844 /* irq clear */ 838 /* irq clear */
845 fsi_irq_disable(fsi, is_play); 839 fsi_irq_disable(fsi, is_play);
@@ -883,7 +877,8 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
883 fsi_stream_push(fsi, is_play, substream, 877 fsi_stream_push(fsi, is_play, substream,
884 frames_to_bytes(runtime, runtime->buffer_size), 878 frames_to_bytes(runtime, runtime->buffer_size),
885 frames_to_bytes(runtime, runtime->period_size)); 879 frames_to_bytes(runtime, runtime->period_size));
886 ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1); 880 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi);
881 fsi_irq_enable(fsi, is_play);
887 break; 882 break;
888 case SNDRV_PCM_TRIGGER_STOP: 883 case SNDRV_PCM_TRIGGER_STOP:
889 fsi_irq_disable(fsi, is_play); 884 fsi_irq_disable(fsi, is_play);
@@ -1174,12 +1169,10 @@ static int fsi_probe(struct platform_device *pdev)
1174 /* FSI A setting */ 1169 /* FSI A setting */
1175 master->fsia.base = master->base; 1170 master->fsia.base = master->base;
1176 master->fsia.master = master; 1171 master->fsia.master = master;
1177 master->fsia.mst_ctrl = A_MST_CTLR;
1178 1172
1179 /* FSI B setting */ 1173 /* FSI B setting */
1180 master->fsib.base = master->base + 0x40; 1174 master->fsib.base = master->base + 0x40;
1181 master->fsib.master = master; 1175 master->fsib.master = master;
1182 master->fsib.mst_ctrl = B_MST_CTLR;
1183 1176
1184 pm_runtime_enable(&pdev->dev); 1177 pm_runtime_enable(&pdev->dev);
1185 pm_runtime_resume(&pdev->dev); 1178 pm_runtime_resume(&pdev->dev);
@@ -1266,6 +1259,8 @@ static struct fsi_core fsi2_core = {
1266 .int_st = CPU_INT_ST, 1259 .int_st = CPU_INT_ST,
1267 .iemsk = CPU_IEMSK, 1260 .iemsk = CPU_IEMSK,
1268 .imsk = CPU_IMSK, 1261 .imsk = CPU_IMSK,
1262 .a_mclk = A_MST_CTLR,
1263 .b_mclk = B_MST_CTLR,
1269}; 1264};
1270 1265
1271static struct platform_device_id fsi_id_table[] = { 1266static struct platform_device_id fsi_id_table[] = {
diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c
index ac6c49ce6fdf..6088a6a3238a 100644
--- a/sound/soc/sh/migor.c
+++ b/sound/soc/sh/migor.c
@@ -8,11 +8,11 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <linux/clkdev.h>
11#include <linux/device.h> 12#include <linux/device.h>
12#include <linux/firmware.h> 13#include <linux/firmware.h>
13#include <linux/module.h> 14#include <linux/module.h>
14 15
15#include <asm/clkdev.h>
16#include <asm/clock.h> 16#include <asm/clock.h>
17 17
18#include <cpu/sh7722.h> 18#include <cpu/sh7722.h>
@@ -20,7 +20,6 @@
20#include <sound/core.h> 20#include <sound/core.h>
21#include <sound/pcm.h> 21#include <sound/pcm.h>
22#include <sound/soc.h> 22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24 23
25#include "../codecs/wm8978.h" 24#include "../codecs/wm8978.h"
26#include "siu.h" 25#include "siu.h"
@@ -140,11 +139,12 @@ static const struct snd_soc_dapm_route audio_map[] = {
140static int migor_dai_init(struct snd_soc_pcm_runtime *rtd) 139static int migor_dai_init(struct snd_soc_pcm_runtime *rtd)
141{ 140{
142 struct snd_soc_codec *codec = rtd->codec; 141 struct snd_soc_codec *codec = rtd->codec;
142 struct snd_soc_dapm_context *dapm = &codec->dapm;
143 143
144 snd_soc_dapm_new_controls(codec, migor_dapm_widgets, 144 snd_soc_dapm_new_controls(dapm, migor_dapm_widgets,
145 ARRAY_SIZE(migor_dapm_widgets)); 145 ARRAY_SIZE(migor_dapm_widgets));
146 146
147 snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); 147 snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
148 148
149 return 0; 149 return 0;
150} 150}
diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c
index f8e0ab82ef59..917d3ceadc9d 100644
--- a/sound/soc/sh/sh7760-ac97.c
+++ b/sound/soc/sh/sh7760-ac97.c
@@ -12,7 +12,6 @@
12#include <sound/core.h> 12#include <sound/core.h>
13#include <sound/pcm.h> 13#include <sound/pcm.h>
14#include <sound/soc.h> 14#include <sound/soc.h>
15#include <sound/soc-dapm.h>
16#include <asm/io.h> 15#include <asm/io.h>
17 16
18#define IPSEL 0xFE400034 17#define IPSEL 0xFE400034
@@ -23,7 +22,7 @@ extern struct snd_soc_platform_driver sh7760_soc_platform;
23 22
24static int machine_init(struct snd_soc_pcm_runtime *rtd) 23static int machine_init(struct snd_soc_pcm_runtime *rtd)
25{ 24{
26 snd_soc_dapm_sync(rtd->codec); 25 snd_soc_dapm_sync(&rtd->codec->dapm);
27 return 0; 26 return 0;
28} 27}
29 28
diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h
index 9f4dcb921ff0..83c3430ad797 100644
--- a/sound/soc/sh/siu.h
+++ b/sound/soc/sh/siu.h
@@ -75,7 +75,7 @@ struct siu_firmware {
75 75
76#include <sound/core.h> 76#include <sound/core.h>
77#include <sound/pcm.h> 77#include <sound/pcm.h>
78#include <sound/soc-dai.h> 78#include <sound/soc.h>
79 79
80#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */ 80#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */
81#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */ 81#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */
diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c
index af53b64d8af2..4973c2939d79 100644
--- a/sound/soc/sh/siu_dai.c
+++ b/sound/soc/sh/siu_dai.c
@@ -28,7 +28,7 @@
28#include <asm/siu.h> 28#include <asm/siu.h>
29 29
30#include <sound/control.h> 30#include <sound/control.h>
31#include <sound/soc-dai.h> 31#include <sound/soc.h>
32 32
33#include "siu.h" 33#include "siu.h"
34 34
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index ed29c9e1ed4e..a423babcf145 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -29,7 +29,7 @@
29#include <sound/core.h> 29#include <sound/core.h>
30#include <sound/pcm.h> 30#include <sound/pcm.h>
31#include <sound/pcm_params.h> 31#include <sound/pcm_params.h>
32#include <sound/soc-dai.h> 32#include <sound/soc.h>
33 33
34#include <asm/siu.h> 34#include <asm/siu.h>
35 35
diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c
index d214f02cbb65..8c2a21a978ac 100644
--- a/sound/soc/soc-cache.c
+++ b/sound/soc/soc-cache.c
@@ -14,27 +14,34 @@
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/spi/spi.h> 15#include <linux/spi/spi.h>
16#include <sound/soc.h> 16#include <sound/soc.h>
17#include <linux/lzo.h>
18#include <linux/bitmap.h>
19#include <linux/rbtree.h>
17 20
18static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, 21static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec,
19 unsigned int reg) 22 unsigned int reg)
20{ 23{
21 u16 *cache = codec->reg_cache; 24 int ret;
25 unsigned int val;
22 26
23 if (reg >= codec->driver->reg_cache_size || 27 if (reg >= codec->driver->reg_cache_size ||
24 snd_soc_codec_volatile_register(codec, reg)) { 28 snd_soc_codec_volatile_register(codec, reg)) {
25 if (codec->cache_only) 29 if (codec->cache_only)
26 return -1; 30 return -1;
27 31
32 BUG_ON(!codec->hw_read);
28 return codec->hw_read(codec, reg); 33 return codec->hw_read(codec, reg);
29 } 34 }
30 35
31 return cache[reg]; 36 ret = snd_soc_cache_read(codec, reg, &val);
37 if (ret < 0)
38 return -1;
39 return val;
32} 40}
33 41
34static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, 42static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
35 unsigned int value) 43 unsigned int value)
36{ 44{
37 u16 *cache = codec->reg_cache;
38 u8 data[2]; 45 u8 data[2];
39 int ret; 46 int ret;
40 47
@@ -42,16 +49,17 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg,
42 data[1] = value & 0x00ff; 49 data[1] = value & 0x00ff;
43 50
44 if (!snd_soc_codec_volatile_register(codec, reg) && 51 if (!snd_soc_codec_volatile_register(codec, reg) &&
45 reg < codec->driver->reg_cache_size) 52 reg < codec->driver->reg_cache_size) {
46 cache[reg] = value; 53 ret = snd_soc_cache_write(codec, reg, value);
54 if (ret < 0)
55 return -1;
56 }
47 57
48 if (codec->cache_only) { 58 if (codec->cache_only) {
49 codec->cache_sync = 1; 59 codec->cache_sync = 1;
50 return 0; 60 return 0;
51 } 61 }
52 62
53 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
54
55 ret = codec->hw_write(codec->control_data, data, 2); 63 ret = codec->hw_write(codec->control_data, data, 2);
56 if (ret == 2) 64 if (ret == 2)
57 return 0; 65 return 0;
@@ -77,7 +85,7 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data,
77 msg[1] = data[0]; 85 msg[1] = data[0];
78 86
79 spi_message_init(&m); 87 spi_message_init(&m);
80 memset(&t, 0, (sizeof t)); 88 memset(&t, 0, sizeof t);
81 89
82 t.tx_buf = &msg[0]; 90 t.tx_buf = &msg[0];
83 t.len = len; 91 t.len = len;
@@ -94,23 +102,27 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data,
94static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, 102static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec,
95 unsigned int reg) 103 unsigned int reg)
96{ 104{
97 u16 *cache = codec->reg_cache; 105 int ret;
106 unsigned int val;
98 107
99 if (reg >= codec->driver->reg_cache_size || 108 if (reg >= codec->driver->reg_cache_size ||
100 snd_soc_codec_volatile_register(codec, reg)) { 109 snd_soc_codec_volatile_register(codec, reg)) {
101 if (codec->cache_only) 110 if (codec->cache_only)
102 return -1; 111 return -1;
103 112
113 BUG_ON(!codec->hw_read);
104 return codec->hw_read(codec, reg); 114 return codec->hw_read(codec, reg);
105 } 115 }
106 116
107 return cache[reg]; 117 ret = snd_soc_cache_read(codec, reg, &val);
118 if (ret < 0)
119 return -1;
120 return val;
108} 121}
109 122
110static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, 123static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
111 unsigned int value) 124 unsigned int value)
112{ 125{
113 u16 *cache = codec->reg_cache;
114 u8 data[2]; 126 u8 data[2];
115 int ret; 127 int ret;
116 128
@@ -118,16 +130,17 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg,
118 data[1] = value & 0x00ff; 130 data[1] = value & 0x00ff;
119 131
120 if (!snd_soc_codec_volatile_register(codec, reg) && 132 if (!snd_soc_codec_volatile_register(codec, reg) &&
121 reg < codec->driver->reg_cache_size) 133 reg < codec->driver->reg_cache_size) {
122 cache[reg] = value; 134 ret = snd_soc_cache_write(codec, reg, value);
135 if (ret < 0)
136 return -1;
137 }
123 138
124 if (codec->cache_only) { 139 if (codec->cache_only) {
125 codec->cache_sync = 1; 140 codec->cache_sync = 1;
126 return 0; 141 return 0;
127 } 142 }
128 143
129 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
130
131 ret = codec->hw_write(codec->control_data, data, 2); 144 ret = codec->hw_write(codec->control_data, data, 2);
132 if (ret == 2) 145 if (ret == 2)
133 return 0; 146 return 0;
@@ -153,7 +166,7 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data,
153 msg[1] = data[1]; 166 msg[1] = data[1];
154 167
155 spi_message_init(&m); 168 spi_message_init(&m);
156 memset(&t, 0, (sizeof t)); 169 memset(&t, 0, sizeof t);
157 170
158 t.tx_buf = &msg[0]; 171 t.tx_buf = &msg[0];
159 t.len = len; 172 t.len = len;
@@ -170,24 +183,25 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data,
170static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, 183static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
171 unsigned int value) 184 unsigned int value)
172{ 185{
173 u8 *cache = codec->reg_cache;
174 u8 data[2]; 186 u8 data[2];
187 int ret;
175 188
176 reg &= 0xff; 189 reg &= 0xff;
177 data[0] = reg; 190 data[0] = reg;
178 data[1] = value & 0xff; 191 data[1] = value & 0xff;
179 192
180 if (!snd_soc_codec_volatile_register(codec, reg) && 193 if (!snd_soc_codec_volatile_register(codec, reg) &&
181 reg < codec->driver->reg_cache_size) 194 reg < codec->driver->reg_cache_size) {
182 cache[reg] = value; 195 ret = snd_soc_cache_write(codec, reg, value);
196 if (ret < 0)
197 return -1;
198 }
183 199
184 if (codec->cache_only) { 200 if (codec->cache_only) {
185 codec->cache_sync = 1; 201 codec->cache_sync = 1;
186 return 0; 202 return 0;
187 } 203 }
188 204
189 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
190
191 if (codec->hw_write(codec->control_data, data, 2) == 2) 205 if (codec->hw_write(codec->control_data, data, 2) == 2)
192 return 0; 206 return 0;
193 else 207 else
@@ -197,7 +211,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg,
197static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, 211static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
198 unsigned int reg) 212 unsigned int reg)
199{ 213{
200 u8 *cache = codec->reg_cache; 214 int ret;
215 unsigned int val;
201 216
202 reg &= 0xff; 217 reg &= 0xff;
203 if (reg >= codec->driver->reg_cache_size || 218 if (reg >= codec->driver->reg_cache_size ||
@@ -205,10 +220,14 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec,
205 if (codec->cache_only) 220 if (codec->cache_only)
206 return -1; 221 return -1;
207 222
223 BUG_ON(!codec->hw_read);
208 return codec->hw_read(codec, reg); 224 return codec->hw_read(codec, reg);
209 } 225 }
210 226
211 return cache[reg]; 227 ret = snd_soc_cache_read(codec, reg, &val);
228 if (ret < 0)
229 return -1;
230 return val;
212} 231}
213 232
214#if defined(CONFIG_SPI_MASTER) 233#if defined(CONFIG_SPI_MASTER)
@@ -227,7 +246,7 @@ static int snd_soc_8_8_spi_write(void *control_data, const char *data,
227 msg[1] = data[1]; 246 msg[1] = data[1];
228 247
229 spi_message_init(&m); 248 spi_message_init(&m);
230 memset(&t, 0, (sizeof t)); 249 memset(&t, 0, sizeof t);
231 250
232 t.tx_buf = &msg[0]; 251 t.tx_buf = &msg[0];
233 t.len = len; 252 t.len = len;
@@ -244,24 +263,25 @@ static int snd_soc_8_8_spi_write(void *control_data, const char *data,
244static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, 263static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
245 unsigned int value) 264 unsigned int value)
246{ 265{
247 u16 *reg_cache = codec->reg_cache;
248 u8 data[3]; 266 u8 data[3];
267 int ret;
249 268
250 data[0] = reg; 269 data[0] = reg;
251 data[1] = (value >> 8) & 0xff; 270 data[1] = (value >> 8) & 0xff;
252 data[2] = value & 0xff; 271 data[2] = value & 0xff;
253 272
254 if (!snd_soc_codec_volatile_register(codec, reg) && 273 if (!snd_soc_codec_volatile_register(codec, reg) &&
255 reg < codec->driver->reg_cache_size) 274 reg < codec->driver->reg_cache_size) {
256 reg_cache[reg] = value; 275 ret = snd_soc_cache_write(codec, reg, value);
276 if (ret < 0)
277 return -1;
278 }
257 279
258 if (codec->cache_only) { 280 if (codec->cache_only) {
259 codec->cache_sync = 1; 281 codec->cache_sync = 1;
260 return 0; 282 return 0;
261 } 283 }
262 284
263 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
264
265 if (codec->hw_write(codec->control_data, data, 3) == 3) 285 if (codec->hw_write(codec->control_data, data, 3) == 3)
266 return 0; 286 return 0;
267 else 287 else
@@ -271,17 +291,22 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg,
271static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, 291static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec,
272 unsigned int reg) 292 unsigned int reg)
273{ 293{
274 u16 *cache = codec->reg_cache; 294 int ret;
295 unsigned int val;
275 296
276 if (reg >= codec->driver->reg_cache_size || 297 if (reg >= codec->driver->reg_cache_size ||
277 snd_soc_codec_volatile_register(codec, reg)) { 298 snd_soc_codec_volatile_register(codec, reg)) {
278 if (codec->cache_only) 299 if (codec->cache_only)
279 return -1; 300 return -1;
280 301
302 BUG_ON(!codec->hw_read);
281 return codec->hw_read(codec, reg); 303 return codec->hw_read(codec, reg);
282 } else {
283 return cache[reg];
284 } 304 }
305
306 ret = snd_soc_cache_read(codec, reg, &val);
307 if (ret < 0)
308 return -1;
309 return val;
285} 310}
286 311
287#if defined(CONFIG_SPI_MASTER) 312#if defined(CONFIG_SPI_MASTER)
@@ -301,7 +326,7 @@ static int snd_soc_8_16_spi_write(void *control_data, const char *data,
301 msg[2] = data[2]; 326 msg[2] = data[2];
302 327
303 spi_message_init(&m); 328 spi_message_init(&m);
304 memset(&t, 0, (sizeof t)); 329 memset(&t, 0, sizeof t);
305 330
306 t.tx_buf = &msg[0]; 331 t.tx_buf = &msg[0];
307 t.len = len; 332 t.len = len;
@@ -420,7 +445,8 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec,
420static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, 445static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
421 unsigned int reg) 446 unsigned int reg)
422{ 447{
423 u8 *cache = codec->reg_cache; 448 int ret;
449 unsigned int val;
424 450
425 reg &= 0xff; 451 reg &= 0xff;
426 if (reg >= codec->driver->reg_cache_size || 452 if (reg >= codec->driver->reg_cache_size ||
@@ -428,16 +454,19 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec,
428 if (codec->cache_only) 454 if (codec->cache_only)
429 return -1; 455 return -1;
430 456
457 BUG_ON(!codec->hw_read);
431 return codec->hw_read(codec, reg); 458 return codec->hw_read(codec, reg);
432 } 459 }
433 460
434 return cache[reg]; 461 ret = snd_soc_cache_read(codec, reg, &val);
462 if (ret < 0)
463 return -1;
464 return val;
435} 465}
436 466
437static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, 467static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
438 unsigned int value) 468 unsigned int value)
439{ 469{
440 u8 *cache = codec->reg_cache;
441 u8 data[3]; 470 u8 data[3];
442 int ret; 471 int ret;
443 472
@@ -447,16 +476,17 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg,
447 476
448 reg &= 0xff; 477 reg &= 0xff;
449 if (!snd_soc_codec_volatile_register(codec, reg) && 478 if (!snd_soc_codec_volatile_register(codec, reg) &&
450 reg < codec->driver->reg_cache_size) 479 reg < codec->driver->reg_cache_size) {
451 cache[reg] = value; 480 ret = snd_soc_cache_write(codec, reg, value);
481 if (ret < 0)
482 return -1;
483 }
452 484
453 if (codec->cache_only) { 485 if (codec->cache_only) {
454 codec->cache_sync = 1; 486 codec->cache_sync = 1;
455 return 0; 487 return 0;
456 } 488 }
457 489
458 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
459
460 ret = codec->hw_write(codec->control_data, data, 3); 490 ret = codec->hw_write(codec->control_data, data, 3);
461 if (ret == 3) 491 if (ret == 3)
462 return 0; 492 return 0;
@@ -483,7 +513,7 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data,
483 msg[2] = data[2]; 513 msg[2] = data[2];
484 514
485 spi_message_init(&m); 515 spi_message_init(&m);
486 memset(&t, 0, (sizeof t)); 516 memset(&t, 0, sizeof t);
487 517
488 t.tx_buf = &msg[0]; 518 t.tx_buf = &msg[0];
489 t.len = len; 519 t.len = len;
@@ -534,23 +564,28 @@ static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec,
534static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, 564static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec,
535 unsigned int reg) 565 unsigned int reg)
536{ 566{
537 u16 *cache = codec->reg_cache; 567 int ret;
568 unsigned int val;
538 569
539 if (reg >= codec->driver->reg_cache_size || 570 if (reg >= codec->driver->reg_cache_size ||
540 snd_soc_codec_volatile_register(codec, reg)) { 571 snd_soc_codec_volatile_register(codec, reg)) {
541 if (codec->cache_only) 572 if (codec->cache_only)
542 return -1; 573 return -1;
543 574
575 BUG_ON(!codec->hw_read);
544 return codec->hw_read(codec, reg); 576 return codec->hw_read(codec, reg);
545 } 577 }
546 578
547 return cache[reg]; 579 ret = snd_soc_cache_read(codec, reg, &val);
580 if (ret < 0)
581 return -1;
582
583 return val;
548} 584}
549 585
550static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, 586static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
551 unsigned int value) 587 unsigned int value)
552{ 588{
553 u16 *cache = codec->reg_cache;
554 u8 data[4]; 589 u8 data[4];
555 int ret; 590 int ret;
556 591
@@ -560,16 +595,17 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg,
560 data[3] = value & 0xff; 595 data[3] = value & 0xff;
561 596
562 if (!snd_soc_codec_volatile_register(codec, reg) && 597 if (!snd_soc_codec_volatile_register(codec, reg) &&
563 reg < codec->driver->reg_cache_size) 598 reg < codec->driver->reg_cache_size) {
564 cache[reg] = value; 599 ret = snd_soc_cache_write(codec, reg, value);
600 if (ret < 0)
601 return -1;
602 }
565 603
566 if (codec->cache_only) { 604 if (codec->cache_only) {
567 codec->cache_sync = 1; 605 codec->cache_sync = 1;
568 return 0; 606 return 0;
569 } 607 }
570 608
571 dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value);
572
573 ret = codec->hw_write(codec->control_data, data, 4); 609 ret = codec->hw_write(codec->control_data, data, 4);
574 if (ret == 4) 610 if (ret == 4)
575 return 0; 611 return 0;
@@ -597,7 +633,7 @@ static int snd_soc_16_16_spi_write(void *control_data, const char *data,
597 msg[3] = data[3]; 633 msg[3] = data[3];
598 634
599 spi_message_init(&m); 635 spi_message_init(&m);
600 memset(&t, 0, (sizeof t)); 636 memset(&t, 0, sizeof t);
601 637
602 t.tx_buf = &msg[0]; 638 t.tx_buf = &msg[0];
603 t.len = len; 639 t.len = len;
@@ -692,8 +728,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
692 return -EINVAL; 728 return -EINVAL;
693 } 729 }
694 730
695 codec->driver->write = io_types[i].write; 731 codec->write = io_types[i].write;
696 codec->driver->read = io_types[i].read; 732 codec->read = io_types[i].read;
697 733
698 switch (control) { 734 switch (control) {
699 case SND_SOC_CUSTOM: 735 case SND_SOC_CUSTOM:
@@ -724,3 +760,930 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
724 return 0; 760 return 0;
725} 761}
726EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); 762EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io);
763
764struct snd_soc_rbtree_node {
765 struct rb_node node;
766 unsigned int reg;
767 unsigned int value;
768 unsigned int defval;
769} __attribute__ ((packed));
770
771struct snd_soc_rbtree_ctx {
772 struct rb_root root;
773};
774
775static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup(
776 struct rb_root *root, unsigned int reg)
777{
778 struct rb_node *node;
779 struct snd_soc_rbtree_node *rbnode;
780
781 node = root->rb_node;
782 while (node) {
783 rbnode = container_of(node, struct snd_soc_rbtree_node, node);
784 if (rbnode->reg < reg)
785 node = node->rb_left;
786 else if (rbnode->reg > reg)
787 node = node->rb_right;
788 else
789 return rbnode;
790 }
791
792 return NULL;
793}
794
795static int snd_soc_rbtree_insert(struct rb_root *root,
796 struct snd_soc_rbtree_node *rbnode)
797{
798 struct rb_node **new, *parent;
799 struct snd_soc_rbtree_node *rbnode_tmp;
800
801 parent = NULL;
802 new = &root->rb_node;
803 while (*new) {
804 rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node,
805 node);
806 parent = *new;
807 if (rbnode_tmp->reg < rbnode->reg)
808 new = &((*new)->rb_left);
809 else if (rbnode_tmp->reg > rbnode->reg)
810 new = &((*new)->rb_right);
811 else
812 return 0;
813 }
814
815 /* insert the node into the rbtree */
816 rb_link_node(&rbnode->node, parent, new);
817 rb_insert_color(&rbnode->node, root);
818
819 return 1;
820}
821
822static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec)
823{
824 struct snd_soc_rbtree_ctx *rbtree_ctx;
825 struct rb_node *node;
826 struct snd_soc_rbtree_node *rbnode;
827 unsigned int val;
828 int ret;
829
830 rbtree_ctx = codec->reg_cache;
831 for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) {
832 rbnode = rb_entry(node, struct snd_soc_rbtree_node, node);
833 if (rbnode->value == rbnode->defval)
834 continue;
835 ret = snd_soc_cache_read(codec, rbnode->reg, &val);
836 if (ret)
837 return ret;
838 ret = snd_soc_write(codec, rbnode->reg, val);
839 if (ret)
840 return ret;
841 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
842 rbnode->reg, val);
843 }
844
845 return 0;
846}
847
848static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec,
849 unsigned int reg, unsigned int value)
850{
851 struct snd_soc_rbtree_ctx *rbtree_ctx;
852 struct snd_soc_rbtree_node *rbnode;
853
854 rbtree_ctx = codec->reg_cache;
855 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
856 if (rbnode) {
857 if (rbnode->value == value)
858 return 0;
859 rbnode->value = value;
860 } else {
861 /* bail out early, no need to create the rbnode yet */
862 if (!value)
863 return 0;
864 /*
865 * for uninitialized registers whose value is changed
866 * from the default zero, create an rbnode and insert
867 * it into the tree.
868 */
869 rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL);
870 if (!rbnode)
871 return -ENOMEM;
872 rbnode->reg = reg;
873 rbnode->value = value;
874 snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode);
875 }
876
877 return 0;
878}
879
880static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec,
881 unsigned int reg, unsigned int *value)
882{
883 struct snd_soc_rbtree_ctx *rbtree_ctx;
884 struct snd_soc_rbtree_node *rbnode;
885
886 rbtree_ctx = codec->reg_cache;
887 rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg);
888 if (rbnode) {
889 *value = rbnode->value;
890 } else {
891 /* uninitialized registers default to 0 */
892 *value = 0;
893 }
894
895 return 0;
896}
897
898static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec)
899{
900 struct rb_node *next;
901 struct snd_soc_rbtree_ctx *rbtree_ctx;
902 struct snd_soc_rbtree_node *rbtree_node;
903
904 /* if we've already been called then just return */
905 rbtree_ctx = codec->reg_cache;
906 if (!rbtree_ctx)
907 return 0;
908
909 /* free up the rbtree */
910 next = rb_first(&rbtree_ctx->root);
911 while (next) {
912 rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node);
913 next = rb_next(&rbtree_node->node);
914 rb_erase(&rbtree_node->node, &rbtree_ctx->root);
915 kfree(rbtree_node);
916 }
917
918 /* release the resources */
919 kfree(codec->reg_cache);
920 codec->reg_cache = NULL;
921
922 return 0;
923}
924
925static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec)
926{
927 struct snd_soc_rbtree_ctx *rbtree_ctx;
928
929 codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL);
930 if (!codec->reg_cache)
931 return -ENOMEM;
932
933 rbtree_ctx = codec->reg_cache;
934 rbtree_ctx->root = RB_ROOT;
935
936 if (!codec->reg_def_copy)
937 return 0;
938
939/*
940 * populate the rbtree with the initialized registers. All other
941 * registers will be inserted into the tree when they are first written.
942 *
943 * The reasoning behind this, is that we need to step through and
944 * dereference the cache in u8/u16 increments without sacrificing
945 * portability. This could also be done using memcpy() but that would
946 * be slightly more cryptic.
947 */
948#define snd_soc_rbtree_populate(cache) \
949({ \
950 int ret, i; \
951 struct snd_soc_rbtree_node *rbtree_node; \
952 \
953 ret = 0; \
954 cache = codec->reg_def_copy; \
955 for (i = 0; i < codec->driver->reg_cache_size; ++i) { \
956 if (!cache[i]) \
957 continue; \
958 rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL); \
959 if (!rbtree_node) { \
960 ret = -ENOMEM; \
961 snd_soc_cache_exit(codec); \
962 break; \
963 } \
964 rbtree_node->reg = i; \
965 rbtree_node->value = cache[i]; \
966 rbtree_node->defval = cache[i]; \
967 snd_soc_rbtree_insert(&rbtree_ctx->root, \
968 rbtree_node); \
969 } \
970 ret; \
971})
972
973 switch (codec->driver->reg_word_size) {
974 case 1: {
975 const u8 *cache;
976
977 return snd_soc_rbtree_populate(cache);
978 }
979 case 2: {
980 const u16 *cache;
981
982 return snd_soc_rbtree_populate(cache);
983 }
984 default:
985 BUG();
986 }
987
988 return 0;
989}
990
991#ifdef CONFIG_SND_SOC_CACHE_LZO
992struct snd_soc_lzo_ctx {
993 void *wmem;
994 void *dst;
995 const void *src;
996 size_t src_len;
997 size_t dst_len;
998 size_t decompressed_size;
999 unsigned long *sync_bmp;
1000 int sync_bmp_nbits;
1001};
1002
1003#define LZO_BLOCK_NUM 8
1004static int snd_soc_lzo_block_count(void)
1005{
1006 return LZO_BLOCK_NUM;
1007}
1008
1009static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx)
1010{
1011 lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL);
1012 if (!lzo_ctx->wmem)
1013 return -ENOMEM;
1014 return 0;
1015}
1016
1017static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx)
1018{
1019 size_t compress_size;
1020 int ret;
1021
1022 ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len,
1023 lzo_ctx->dst, &compress_size, lzo_ctx->wmem);
1024 if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len)
1025 return -EINVAL;
1026 lzo_ctx->dst_len = compress_size;
1027 return 0;
1028}
1029
1030static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx)
1031{
1032 size_t dst_len;
1033 int ret;
1034
1035 dst_len = lzo_ctx->dst_len;
1036 ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len,
1037 lzo_ctx->dst, &dst_len);
1038 if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len)
1039 return -EINVAL;
1040 return 0;
1041}
1042
1043static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec,
1044 struct snd_soc_lzo_ctx *lzo_ctx)
1045{
1046 int ret;
1047
1048 lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE);
1049 lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
1050 if (!lzo_ctx->dst) {
1051 lzo_ctx->dst_len = 0;
1052 return -ENOMEM;
1053 }
1054
1055 ret = snd_soc_lzo_compress(lzo_ctx);
1056 if (ret < 0)
1057 return ret;
1058 return 0;
1059}
1060
1061static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec,
1062 struct snd_soc_lzo_ctx *lzo_ctx)
1063{
1064 int ret;
1065
1066 lzo_ctx->dst_len = lzo_ctx->decompressed_size;
1067 lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL);
1068 if (!lzo_ctx->dst) {
1069 lzo_ctx->dst_len = 0;
1070 return -ENOMEM;
1071 }
1072
1073 ret = snd_soc_lzo_decompress(lzo_ctx);
1074 if (ret < 0)
1075 return ret;
1076 return 0;
1077}
1078
1079static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec,
1080 unsigned int reg)
1081{
1082 const struct snd_soc_codec_driver *codec_drv;
1083 size_t reg_size;
1084
1085 codec_drv = codec->driver;
1086 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1087 return (reg * codec_drv->reg_word_size) /
1088 DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
1089}
1090
1091static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec,
1092 unsigned int reg)
1093{
1094 const struct snd_soc_codec_driver *codec_drv;
1095 size_t reg_size;
1096
1097 codec_drv = codec->driver;
1098 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1099 return reg % (DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()) /
1100 codec_drv->reg_word_size);
1101}
1102
1103static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec)
1104{
1105 const struct snd_soc_codec_driver *codec_drv;
1106 size_t reg_size;
1107
1108 codec_drv = codec->driver;
1109 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1110 return DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count());
1111}
1112
1113static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec)
1114{
1115 struct snd_soc_lzo_ctx **lzo_blocks;
1116 unsigned int val;
1117 int i;
1118 int ret;
1119
1120 lzo_blocks = codec->reg_cache;
1121 for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) {
1122 ret = snd_soc_cache_read(codec, i, &val);
1123 if (ret)
1124 return ret;
1125 ret = snd_soc_write(codec, i, val);
1126 if (ret)
1127 return ret;
1128 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
1129 i, val);
1130 }
1131
1132 return 0;
1133}
1134
1135static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec,
1136 unsigned int reg, unsigned int value)
1137{
1138 struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
1139 int ret, blkindex, blkpos;
1140 size_t blksize, tmp_dst_len;
1141 void *tmp_dst;
1142
1143 /* index of the compressed lzo block */
1144 blkindex = snd_soc_lzo_get_blkindex(codec, reg);
1145 /* register index within the decompressed block */
1146 blkpos = snd_soc_lzo_get_blkpos(codec, reg);
1147 /* size of the compressed block */
1148 blksize = snd_soc_lzo_get_blksize(codec);
1149 lzo_blocks = codec->reg_cache;
1150 lzo_block = lzo_blocks[blkindex];
1151
1152 /* save the pointer and length of the compressed block */
1153 tmp_dst = lzo_block->dst;
1154 tmp_dst_len = lzo_block->dst_len;
1155
1156 /* prepare the source to be the compressed block */
1157 lzo_block->src = lzo_block->dst;
1158 lzo_block->src_len = lzo_block->dst_len;
1159
1160 /* decompress the block */
1161 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1162 if (ret < 0) {
1163 kfree(lzo_block->dst);
1164 goto out;
1165 }
1166
1167 /* write the new value to the cache */
1168 switch (codec->driver->reg_word_size) {
1169 case 1: {
1170 u8 *cache;
1171 cache = lzo_block->dst;
1172 if (cache[blkpos] == value) {
1173 kfree(lzo_block->dst);
1174 goto out;
1175 }
1176 cache[blkpos] = value;
1177 }
1178 break;
1179 case 2: {
1180 u16 *cache;
1181 cache = lzo_block->dst;
1182 if (cache[blkpos] == value) {
1183 kfree(lzo_block->dst);
1184 goto out;
1185 }
1186 cache[blkpos] = value;
1187 }
1188 break;
1189 default:
1190 BUG();
1191 }
1192
1193 /* prepare the source to be the decompressed block */
1194 lzo_block->src = lzo_block->dst;
1195 lzo_block->src_len = lzo_block->dst_len;
1196
1197 /* compress the block */
1198 ret = snd_soc_lzo_compress_cache_block(codec, lzo_block);
1199 if (ret < 0) {
1200 kfree(lzo_block->dst);
1201 kfree(lzo_block->src);
1202 goto out;
1203 }
1204
1205 /* set the bit so we know we have to sync this register */
1206 set_bit(reg, lzo_block->sync_bmp);
1207 kfree(tmp_dst);
1208 kfree(lzo_block->src);
1209 return 0;
1210out:
1211 lzo_block->dst = tmp_dst;
1212 lzo_block->dst_len = tmp_dst_len;
1213 return ret;
1214}
1215
1216static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec,
1217 unsigned int reg, unsigned int *value)
1218{
1219 struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks;
1220 int ret, blkindex, blkpos;
1221 size_t blksize, tmp_dst_len;
1222 void *tmp_dst;
1223
1224 *value = 0;
1225 /* index of the compressed lzo block */
1226 blkindex = snd_soc_lzo_get_blkindex(codec, reg);
1227 /* register index within the decompressed block */
1228 blkpos = snd_soc_lzo_get_blkpos(codec, reg);
1229 /* size of the compressed block */
1230 blksize = snd_soc_lzo_get_blksize(codec);
1231 lzo_blocks = codec->reg_cache;
1232 lzo_block = lzo_blocks[blkindex];
1233
1234 /* save the pointer and length of the compressed block */
1235 tmp_dst = lzo_block->dst;
1236 tmp_dst_len = lzo_block->dst_len;
1237
1238 /* prepare the source to be the compressed block */
1239 lzo_block->src = lzo_block->dst;
1240 lzo_block->src_len = lzo_block->dst_len;
1241
1242 /* decompress the block */
1243 ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block);
1244 if (ret >= 0) {
1245 /* fetch the value from the cache */
1246 switch (codec->driver->reg_word_size) {
1247 case 1: {
1248 u8 *cache;
1249 cache = lzo_block->dst;
1250 *value = cache[blkpos];
1251 }
1252 break;
1253 case 2: {
1254 u16 *cache;
1255 cache = lzo_block->dst;
1256 *value = cache[blkpos];
1257 }
1258 break;
1259 default:
1260 BUG();
1261 }
1262 }
1263
1264 kfree(lzo_block->dst);
1265 /* restore the pointer and length of the compressed block */
1266 lzo_block->dst = tmp_dst;
1267 lzo_block->dst_len = tmp_dst_len;
1268 return 0;
1269}
1270
1271static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec)
1272{
1273 struct snd_soc_lzo_ctx **lzo_blocks;
1274 int i, blkcount;
1275
1276 lzo_blocks = codec->reg_cache;
1277 if (!lzo_blocks)
1278 return 0;
1279
1280 blkcount = snd_soc_lzo_block_count();
1281 /*
1282 * the pointer to the bitmap used for syncing the cache
1283 * is shared amongst all lzo_blocks. Ensure it is freed
1284 * only once.
1285 */
1286 if (lzo_blocks[0])
1287 kfree(lzo_blocks[0]->sync_bmp);
1288 for (i = 0; i < blkcount; ++i) {
1289 if (lzo_blocks[i]) {
1290 kfree(lzo_blocks[i]->wmem);
1291 kfree(lzo_blocks[i]->dst);
1292 }
1293 /* each lzo_block is a pointer returned by kmalloc or NULL */
1294 kfree(lzo_blocks[i]);
1295 }
1296 kfree(lzo_blocks);
1297 codec->reg_cache = NULL;
1298 return 0;
1299}
1300
1301static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec)
1302{
1303 struct snd_soc_lzo_ctx **lzo_blocks;
1304 size_t reg_size, bmp_size;
1305 const struct snd_soc_codec_driver *codec_drv;
1306 int ret, tofree, i, blksize, blkcount;
1307 const char *p, *end;
1308 unsigned long *sync_bmp;
1309
1310 ret = 0;
1311 codec_drv = codec->driver;
1312 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1313
1314 /*
1315 * If we have not been given a default register cache
1316 * then allocate a dummy zero-ed out region, compress it
1317 * and remember to free it afterwards.
1318 */
1319 tofree = 0;
1320 if (!codec->reg_def_copy)
1321 tofree = 1;
1322
1323 if (!codec->reg_def_copy) {
1324 codec->reg_def_copy = kzalloc(reg_size,
1325 GFP_KERNEL);
1326 if (!codec->reg_def_copy)
1327 return -ENOMEM;
1328 }
1329
1330 blkcount = snd_soc_lzo_block_count();
1331 codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks,
1332 GFP_KERNEL);
1333 if (!codec->reg_cache) {
1334 ret = -ENOMEM;
1335 goto err_tofree;
1336 }
1337 lzo_blocks = codec->reg_cache;
1338
1339 /*
1340 * allocate a bitmap to be used when syncing the cache with
1341 * the hardware. Each time a register is modified, the corresponding
1342 * bit is set in the bitmap, so we know that we have to sync
1343 * that register.
1344 */
1345 bmp_size = codec_drv->reg_cache_size;
1346 sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long),
1347 GFP_KERNEL);
1348 if (!sync_bmp) {
1349 ret = -ENOMEM;
1350 goto err;
1351 }
1352 bitmap_zero(sync_bmp, bmp_size);
1353
1354 /* allocate the lzo blocks and initialize them */
1355 for (i = 0; i < blkcount; ++i) {
1356 lzo_blocks[i] = kzalloc(sizeof **lzo_blocks,
1357 GFP_KERNEL);
1358 if (!lzo_blocks[i]) {
1359 kfree(sync_bmp);
1360 ret = -ENOMEM;
1361 goto err;
1362 }
1363 lzo_blocks[i]->sync_bmp = sync_bmp;
1364 lzo_blocks[i]->sync_bmp_nbits = bmp_size;
1365 /* alloc the working space for the compressed block */
1366 ret = snd_soc_lzo_prepare(lzo_blocks[i]);
1367 if (ret < 0)
1368 goto err;
1369 }
1370
1371 blksize = snd_soc_lzo_get_blksize(codec);
1372 p = codec->reg_def_copy;
1373 end = codec->reg_def_copy + reg_size;
1374 /* compress the register map and fill the lzo blocks */
1375 for (i = 0; i < blkcount; ++i, p += blksize) {
1376 lzo_blocks[i]->src = p;
1377 if (p + blksize > end)
1378 lzo_blocks[i]->src_len = end - p;
1379 else
1380 lzo_blocks[i]->src_len = blksize;
1381 ret = snd_soc_lzo_compress_cache_block(codec,
1382 lzo_blocks[i]);
1383 if (ret < 0)
1384 goto err;
1385 lzo_blocks[i]->decompressed_size =
1386 lzo_blocks[i]->src_len;
1387 }
1388
1389 if (tofree) {
1390 kfree(codec->reg_def_copy);
1391 codec->reg_def_copy = NULL;
1392 }
1393 return 0;
1394err:
1395 snd_soc_cache_exit(codec);
1396err_tofree:
1397 if (tofree) {
1398 kfree(codec->reg_def_copy);
1399 codec->reg_def_copy = NULL;
1400 }
1401 return ret;
1402}
1403#endif
1404
1405static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec)
1406{
1407 int i;
1408 int ret;
1409 const struct snd_soc_codec_driver *codec_drv;
1410 unsigned int val;
1411
1412 codec_drv = codec->driver;
1413 for (i = 0; i < codec_drv->reg_cache_size; ++i) {
1414 ret = snd_soc_cache_read(codec, i, &val);
1415 if (ret)
1416 return ret;
1417 if (codec_drv->reg_cache_default) {
1418 switch (codec_drv->reg_word_size) {
1419 case 1: {
1420 const u8 *cache;
1421
1422 cache = codec_drv->reg_cache_default;
1423 if (cache[i] == val)
1424 continue;
1425 }
1426 break;
1427 case 2: {
1428 const u16 *cache;
1429
1430 cache = codec_drv->reg_cache_default;
1431 if (cache[i] == val)
1432 continue;
1433 }
1434 break;
1435 default:
1436 BUG();
1437 }
1438 }
1439 ret = snd_soc_write(codec, i, val);
1440 if (ret)
1441 return ret;
1442 dev_dbg(codec->dev, "Synced register %#x, value = %#x\n",
1443 i, val);
1444 }
1445 return 0;
1446}
1447
1448static int snd_soc_flat_cache_write(struct snd_soc_codec *codec,
1449 unsigned int reg, unsigned int value)
1450{
1451 switch (codec->driver->reg_word_size) {
1452 case 1: {
1453 u8 *cache;
1454
1455 cache = codec->reg_cache;
1456 cache[reg] = value;
1457 }
1458 break;
1459 case 2: {
1460 u16 *cache;
1461
1462 cache = codec->reg_cache;
1463 cache[reg] = value;
1464 }
1465 break;
1466 default:
1467 BUG();
1468 }
1469
1470 return 0;
1471}
1472
1473static int snd_soc_flat_cache_read(struct snd_soc_codec *codec,
1474 unsigned int reg, unsigned int *value)
1475{
1476 switch (codec->driver->reg_word_size) {
1477 case 1: {
1478 u8 *cache;
1479
1480 cache = codec->reg_cache;
1481 *value = cache[reg];
1482 }
1483 break;
1484 case 2: {
1485 u16 *cache;
1486
1487 cache = codec->reg_cache;
1488 *value = cache[reg];
1489 }
1490 break;
1491 default:
1492 BUG();
1493 }
1494
1495 return 0;
1496}
1497
1498static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec)
1499{
1500 if (!codec->reg_cache)
1501 return 0;
1502 kfree(codec->reg_cache);
1503 codec->reg_cache = NULL;
1504 return 0;
1505}
1506
1507static int snd_soc_flat_cache_init(struct snd_soc_codec *codec)
1508{
1509 const struct snd_soc_codec_driver *codec_drv;
1510 size_t reg_size;
1511
1512 codec_drv = codec->driver;
1513 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
1514
1515 /*
1516 * for flat compression, we don't need to keep a copy of the
1517 * original defaults register cache as it will definitely not
1518 * be marked as __devinitconst
1519 */
1520 kfree(codec->reg_def_copy);
1521 codec->reg_def_copy = NULL;
1522
1523 if (codec_drv->reg_cache_default)
1524 codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
1525 reg_size, GFP_KERNEL);
1526 else
1527 codec->reg_cache = kzalloc(reg_size, GFP_KERNEL);
1528 if (!codec->reg_cache)
1529 return -ENOMEM;
1530
1531 return 0;
1532}
1533
1534/* an array of all supported compression types */
1535static const struct snd_soc_cache_ops cache_types[] = {
1536 /* Flat *must* be the first entry for fallback */
1537 {
1538 .id = SND_SOC_FLAT_COMPRESSION,
1539 .name = "flat",
1540 .init = snd_soc_flat_cache_init,
1541 .exit = snd_soc_flat_cache_exit,
1542 .read = snd_soc_flat_cache_read,
1543 .write = snd_soc_flat_cache_write,
1544 .sync = snd_soc_flat_cache_sync
1545 },
1546#ifdef CONFIG_SND_SOC_CACHE_LZO
1547 {
1548 .id = SND_SOC_LZO_COMPRESSION,
1549 .name = "LZO",
1550 .init = snd_soc_lzo_cache_init,
1551 .exit = snd_soc_lzo_cache_exit,
1552 .read = snd_soc_lzo_cache_read,
1553 .write = snd_soc_lzo_cache_write,
1554 .sync = snd_soc_lzo_cache_sync
1555 },
1556#endif
1557 {
1558 .id = SND_SOC_RBTREE_COMPRESSION,
1559 .name = "rbtree",
1560 .init = snd_soc_rbtree_cache_init,
1561 .exit = snd_soc_rbtree_cache_exit,
1562 .read = snd_soc_rbtree_cache_read,
1563 .write = snd_soc_rbtree_cache_write,
1564 .sync = snd_soc_rbtree_cache_sync
1565 }
1566};
1567
1568int snd_soc_cache_init(struct snd_soc_codec *codec)
1569{
1570 int i;
1571
1572 for (i = 0; i < ARRAY_SIZE(cache_types); ++i)
1573 if (cache_types[i].id == codec->compress_type)
1574 break;
1575
1576 /* Fall back to flat compression */
1577 if (i == ARRAY_SIZE(cache_types)) {
1578 dev_warn(codec->dev, "Could not match compress type: %d\n",
1579 codec->compress_type);
1580 i = 0;
1581 }
1582
1583 mutex_init(&codec->cache_rw_mutex);
1584 codec->cache_ops = &cache_types[i];
1585
1586 if (codec->cache_ops->init) {
1587 if (codec->cache_ops->name)
1588 dev_dbg(codec->dev, "Initializing %s cache for %s codec\n",
1589 codec->cache_ops->name, codec->name);
1590 return codec->cache_ops->init(codec);
1591 }
1592 return -EINVAL;
1593}
1594
1595/*
1596 * NOTE: keep in mind that this function might be called
1597 * multiple times.
1598 */
1599int snd_soc_cache_exit(struct snd_soc_codec *codec)
1600{
1601 if (codec->cache_ops && codec->cache_ops->exit) {
1602 if (codec->cache_ops->name)
1603 dev_dbg(codec->dev, "Destroying %s cache for %s codec\n",
1604 codec->cache_ops->name, codec->name);
1605 return codec->cache_ops->exit(codec);
1606 }
1607 return -EINVAL;
1608}
1609
1610/**
1611 * snd_soc_cache_read: Fetch the value of a given register from the cache.
1612 *
1613 * @codec: CODEC to configure.
1614 * @reg: The register index.
1615 * @value: The value to be returned.
1616 */
1617int snd_soc_cache_read(struct snd_soc_codec *codec,
1618 unsigned int reg, unsigned int *value)
1619{
1620 int ret;
1621
1622 mutex_lock(&codec->cache_rw_mutex);
1623
1624 if (value && codec->cache_ops && codec->cache_ops->read) {
1625 ret = codec->cache_ops->read(codec, reg, value);
1626 mutex_unlock(&codec->cache_rw_mutex);
1627 return ret;
1628 }
1629
1630 mutex_unlock(&codec->cache_rw_mutex);
1631 return -EINVAL;
1632}
1633EXPORT_SYMBOL_GPL(snd_soc_cache_read);
1634
1635/**
1636 * snd_soc_cache_write: Set the value of a given register in the cache.
1637 *
1638 * @codec: CODEC to configure.
1639 * @reg: The register index.
1640 * @value: The new register value.
1641 */
1642int snd_soc_cache_write(struct snd_soc_codec *codec,
1643 unsigned int reg, unsigned int value)
1644{
1645 int ret;
1646
1647 mutex_lock(&codec->cache_rw_mutex);
1648
1649 if (codec->cache_ops && codec->cache_ops->write) {
1650 ret = codec->cache_ops->write(codec, reg, value);
1651 mutex_unlock(&codec->cache_rw_mutex);
1652 return ret;
1653 }
1654
1655 mutex_unlock(&codec->cache_rw_mutex);
1656 return -EINVAL;
1657}
1658EXPORT_SYMBOL_GPL(snd_soc_cache_write);
1659
1660/**
1661 * snd_soc_cache_sync: Sync the register cache with the hardware.
1662 *
1663 * @codec: CODEC to configure.
1664 *
1665 * Any registers that should not be synced should be marked as
1666 * volatile. In general drivers can choose not to use the provided
1667 * syncing functionality if they so require.
1668 */
1669int snd_soc_cache_sync(struct snd_soc_codec *codec)
1670{
1671 int ret;
1672
1673 if (!codec->cache_sync) {
1674 return 0;
1675 }
1676
1677 if (codec->cache_ops && codec->cache_ops->sync) {
1678 if (codec->cache_ops->name)
1679 dev_dbg(codec->dev, "Syncing %s cache for %s codec\n",
1680 codec->cache_ops->name, codec->name);
1681 ret = codec->cache_ops->sync(codec);
1682 if (!ret)
1683 codec->cache_sync = 0;
1684 return ret;
1685 }
1686
1687 return -EINVAL;
1688}
1689EXPORT_SYMBOL_GPL(snd_soc_cache_sync);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 85b7d548f167..bac7291b6ff6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -33,12 +33,15 @@
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <sound/ac97_codec.h> 34#include <sound/ac97_codec.h>
35#include <sound/core.h> 35#include <sound/core.h>
36#include <sound/jack.h>
36#include <sound/pcm.h> 37#include <sound/pcm.h>
37#include <sound/pcm_params.h> 38#include <sound/pcm_params.h>
38#include <sound/soc.h> 39#include <sound/soc.h>
39#include <sound/soc-dapm.h>
40#include <sound/initval.h> 40#include <sound/initval.h>
41 41
42#define CREATE_TRACE_POINTS
43#include <trace/events/asoc.h>
44
42#define NAME_SIZE 32 45#define NAME_SIZE 32
43 46
44static DEFINE_MUTEX(pcm_mutex); 47static DEFINE_MUTEX(pcm_mutex);
@@ -67,25 +70,6 @@ static int pmdown_time = 5000;
67module_param(pmdown_time, int, 0); 70module_param(pmdown_time, int, 0);
68MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)"); 71MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)");
69 72
70/*
71 * This function forces any delayed work to be queued and run.
72 */
73static int run_delayed_work(struct delayed_work *dwork)
74{
75 int ret;
76
77 /* cancel any work waiting to be queued. */
78 ret = cancel_delayed_work(dwork);
79
80 /* if there was any work waiting then we run it now and
81 * wait for it's completion */
82 if (ret) {
83 schedule_delayed_work(dwork, 0);
84 flush_scheduled_work();
85 }
86 return ret;
87}
88
89/* codec register dump */ 73/* codec register dump */
90static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) 74static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
91{ 75{
@@ -114,7 +98,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
114 * the register being volatile and the device being 98 * the register being volatile and the device being
115 * powered off. 99 * powered off.
116 */ 100 */
117 ret = codec->driver->read(codec, i); 101 ret = snd_soc_read(codec, i);
118 if (ret >= 0) 102 if (ret >= 0)
119 count += snprintf(buf + count, 103 count += snprintf(buf + count,
120 PAGE_SIZE - count, 104 PAGE_SIZE - count,
@@ -225,7 +209,7 @@ static ssize_t codec_reg_write_file(struct file *file,
225 start++; 209 start++;
226 if (strict_strtoul(start, 16, &value)) 210 if (strict_strtoul(start, 16, &value))
227 return -EINVAL; 211 return -EINVAL;
228 codec->driver->write(codec, reg, value); 212 snd_soc_write(codec, reg, value);
229 return buf_size; 213 return buf_size;
230} 214}
231 215
@@ -238,8 +222,10 @@ static const struct file_operations codec_reg_fops = {
238 222
239static void soc_init_codec_debugfs(struct snd_soc_codec *codec) 223static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
240{ 224{
241 codec->debugfs_codec_root = debugfs_create_dir(codec->name , 225 struct dentry *debugfs_card_root = codec->card->debugfs_card_root;
242 debugfs_root); 226
227 codec->debugfs_codec_root = debugfs_create_dir(codec->name,
228 debugfs_card_root);
243 if (!codec->debugfs_codec_root) { 229 if (!codec->debugfs_codec_root) {
244 printk(KERN_WARNING 230 printk(KERN_WARNING
245 "ASoC: Failed to create codec debugfs directory\n"); 231 "ASoC: Failed to create codec debugfs directory\n");
@@ -253,20 +239,13 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
253 printk(KERN_WARNING 239 printk(KERN_WARNING
254 "ASoC: Failed to create codec register debugfs file\n"); 240 "ASoC: Failed to create codec register debugfs file\n");
255 241
256 codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644, 242 codec->dapm.debugfs_dapm = debugfs_create_dir("dapm",
257 codec->debugfs_codec_root,
258 &codec->pop_time);
259 if (!codec->debugfs_pop_time)
260 printk(KERN_WARNING
261 "Failed to create pop time debugfs file\n");
262
263 codec->debugfs_dapm = debugfs_create_dir("dapm",
264 codec->debugfs_codec_root); 243 codec->debugfs_codec_root);
265 if (!codec->debugfs_dapm) 244 if (!codec->dapm.debugfs_dapm)
266 printk(KERN_WARNING 245 printk(KERN_WARNING
267 "Failed to create DAPM debugfs directory\n"); 246 "Failed to create DAPM debugfs directory\n");
268 247
269 snd_soc_dapm_debugfs_init(codec); 248 snd_soc_dapm_debugfs_init(&codec->dapm);
270} 249}
271 250
272static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) 251static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
@@ -374,6 +353,29 @@ static const struct file_operations platform_list_fops = {
374 .llseek = default_llseek,/* read accesses f_pos */ 353 .llseek = default_llseek,/* read accesses f_pos */
375}; 354};
376 355
356static void soc_init_card_debugfs(struct snd_soc_card *card)
357{
358 card->debugfs_card_root = debugfs_create_dir(card->name,
359 debugfs_root);
360 if (!card->debugfs_card_root) {
361 dev_warn(card->dev,
362 "ASoC: Failed to create codec debugfs directory\n");
363 return;
364 }
365
366 card->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644,
367 card->debugfs_card_root,
368 &card->pop_time);
369 if (!card->debugfs_pop_time)
370 dev_warn(card->dev,
371 "Failed to create pop time debugfs file\n");
372}
373
374static void soc_cleanup_card_debugfs(struct snd_soc_card *card)
375{
376 debugfs_remove_recursive(card->debugfs_card_root);
377}
378
377#else 379#else
378 380
379static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec) 381static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
@@ -383,6 +385,14 @@ static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
383static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) 385static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
384{ 386{
385} 387}
388
389static inline void soc_init_card_debugfs(struct snd_soc_card *card)
390{
391}
392
393static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card)
394{
395}
386#endif 396#endif
387 397
388#ifdef CONFIG_SND_SOC_AC97_BUS 398#ifdef CONFIG_SND_SOC_AC97_BUS
@@ -497,7 +507,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
497 } 507 }
498 } 508 }
499 509
500 /* Check that the codec and cpu DAI's are compatible */ 510 /* Check that the codec and cpu DAIs are compatible */
501 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 511 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
502 runtime->hw.rate_min = 512 runtime->hw.rate_min =
503 max(codec_dai_drv->playback.rate_min, 513 max(codec_dai_drv->playback.rate_min,
@@ -846,7 +856,7 @@ codec_err:
846} 856}
847 857
848/* 858/*
849 * Free's resources allocated by hw_params, can be called multiple times 859 * Frees resources allocated by hw_params, can be called multiple times
850 */ 860 */
851static int soc_pcm_hw_free(struct snd_pcm_substream *substream) 861static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
852{ 862{
@@ -870,7 +880,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream)
870 if (platform->driver->ops->hw_free) 880 if (platform->driver->ops->hw_free)
871 platform->driver->ops->hw_free(substream); 881 platform->driver->ops->hw_free(substream);
872 882
873 /* now free hw params for the DAI's */ 883 /* now free hw params for the DAIs */
874 if (codec_dai->driver->ops->hw_free) 884 if (codec_dai->driver->ops->hw_free)
875 codec_dai->driver->ops->hw_free(substream, codec_dai); 885 codec_dai->driver->ops->hw_free(substream, codec_dai);
876 886
@@ -958,6 +968,7 @@ static int soc_suspend(struct device *dev)
958{ 968{
959 struct platform_device *pdev = to_platform_device(dev); 969 struct platform_device *pdev = to_platform_device(dev);
960 struct snd_soc_card *card = platform_get_drvdata(pdev); 970 struct snd_soc_card *card = platform_get_drvdata(pdev);
971 struct snd_soc_codec *codec;
961 int i; 972 int i;
962 973
963 /* If the initialization of this soc device failed, there is no codec 974 /* If the initialization of this soc device failed, there is no codec
@@ -976,7 +987,7 @@ static int soc_suspend(struct device *dev)
976 /* we're going to block userspace touching us until resume completes */ 987 /* we're going to block userspace touching us until resume completes */
977 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot); 988 snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot);
978 989
979 /* mute any active DAC's */ 990 /* mute any active DACs */
980 for (i = 0; i < card->num_rtd; i++) { 991 for (i = 0; i < card->num_rtd; i++) {
981 struct snd_soc_dai *dai = card->rtd[i].codec_dai; 992 struct snd_soc_dai *dai = card->rtd[i].codec_dai;
982 struct snd_soc_dai_driver *drv = dai->driver; 993 struct snd_soc_dai_driver *drv = dai->driver;
@@ -1016,8 +1027,8 @@ static int soc_suspend(struct device *dev)
1016 1027
1017 /* close any waiting streams and save state */ 1028 /* close any waiting streams and save state */
1018 for (i = 0; i < card->num_rtd; i++) { 1029 for (i = 0; i < card->num_rtd; i++) {
1019 run_delayed_work(&card->rtd[i].delayed_work); 1030 flush_delayed_work_sync(&card->rtd[i].delayed_work);
1020 card->rtd[i].codec->suspend_bias_level = card->rtd[i].codec->bias_level; 1031 card->rtd[i].codec->dapm.suspend_bias_level = card->rtd[i].codec->dapm.bias_level;
1021 } 1032 }
1022 1033
1023 for (i = 0; i < card->num_rtd; i++) { 1034 for (i = 0; i < card->num_rtd; i++) {
@@ -1036,12 +1047,11 @@ static int soc_suspend(struct device *dev)
1036 } 1047 }
1037 1048
1038 /* suspend all CODECs */ 1049 /* suspend all CODECs */
1039 for (i = 0; i < card->num_rtd; i++) { 1050 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
1040 struct snd_soc_codec *codec = card->rtd[i].codec;
1041 /* If there are paths active then the CODEC will be held with 1051 /* If there are paths active then the CODEC will be held with
1042 * bias _ON and should not be suspended. */ 1052 * bias _ON and should not be suspended. */
1043 if (!codec->suspended && codec->driver->suspend) { 1053 if (!codec->suspended && codec->driver->suspend) {
1044 switch (codec->bias_level) { 1054 switch (codec->dapm.bias_level) {
1045 case SND_SOC_BIAS_STANDBY: 1055 case SND_SOC_BIAS_STANDBY:
1046 case SND_SOC_BIAS_OFF: 1056 case SND_SOC_BIAS_OFF:
1047 codec->driver->suspend(codec, PMSG_SUSPEND); 1057 codec->driver->suspend(codec, PMSG_SUSPEND);
@@ -1078,6 +1088,7 @@ static void soc_resume_deferred(struct work_struct *work)
1078 struct snd_soc_card *card = 1088 struct snd_soc_card *card =
1079 container_of(work, struct snd_soc_card, deferred_resume_work); 1089 container_of(work, struct snd_soc_card, deferred_resume_work);
1080 struct platform_device *pdev = to_platform_device(card->dev); 1090 struct platform_device *pdev = to_platform_device(card->dev);
1091 struct snd_soc_codec *codec;
1081 int i; 1092 int i;
1082 1093
1083 /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time, 1094 /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time,
@@ -1103,14 +1114,13 @@ static void soc_resume_deferred(struct work_struct *work)
1103 cpu_dai->driver->resume(cpu_dai); 1114 cpu_dai->driver->resume(cpu_dai);
1104 } 1115 }
1105 1116
1106 for (i = 0; i < card->num_rtd; i++) { 1117 list_for_each_entry(codec, &card->codec_dev_list, card_list) {
1107 struct snd_soc_codec *codec = card->rtd[i].codec;
1108 /* If the CODEC was idle over suspend then it will have been 1118 /* If the CODEC was idle over suspend then it will have been
1109 * left with bias OFF or STANDBY and suspended so we must now 1119 * left with bias OFF or STANDBY and suspended so we must now
1110 * resume. Otherwise the suspend was suppressed. 1120 * resume. Otherwise the suspend was suppressed.
1111 */ 1121 */
1112 if (codec->driver->resume && codec->suspended) { 1122 if (codec->driver->resume && codec->suspended) {
1113 switch (codec->bias_level) { 1123 switch (codec->dapm.bias_level) {
1114 case SND_SOC_BIAS_STANDBY: 1124 case SND_SOC_BIAS_STANDBY:
1115 case SND_SOC_BIAS_OFF: 1125 case SND_SOC_BIAS_OFF:
1116 codec->driver->resume(codec); 1126 codec->driver->resume(codec);
@@ -1249,9 +1259,6 @@ find_codec:
1249 if (!strcmp(codec->name, dai_link->codec_name)) { 1259 if (!strcmp(codec->name, dai_link->codec_name)) {
1250 rtd->codec = codec; 1260 rtd->codec = codec;
1251 1261
1252 if (!try_module_get(codec->dev->driver->owner))
1253 return -ENODEV;
1254
1255 /* CODEC found, so find CODEC DAI from registered DAIs from this CODEC*/ 1262 /* CODEC found, so find CODEC DAI from registered DAIs from this CODEC*/
1256 list_for_each_entry(codec_dai, &dai_list, list) { 1263 list_for_each_entry(codec_dai, &dai_list, list) {
1257 if (codec->dev == codec_dai->dev && 1264 if (codec->dev == codec_dai->dev &&
@@ -1277,10 +1284,6 @@ find_platform:
1277 /* no, then find CPU DAI from registered DAIs*/ 1284 /* no, then find CPU DAI from registered DAIs*/
1278 list_for_each_entry(platform, &platform_list, list) { 1285 list_for_each_entry(platform, &platform_list, list) {
1279 if (!strcmp(platform->name, dai_link->platform_name)) { 1286 if (!strcmp(platform->name, dai_link->platform_name)) {
1280
1281 if (!try_module_get(platform->dev->driver->owner))
1282 return -ENODEV;
1283
1284 rtd->platform = platform; 1287 rtd->platform = platform;
1285 goto out; 1288 goto out;
1286 } 1289 }
@@ -1299,6 +1302,27 @@ out:
1299 return 1; 1302 return 1;
1300} 1303}
1301 1304
1305static void soc_remove_codec(struct snd_soc_codec *codec)
1306{
1307 int err;
1308
1309 if (codec->driver->remove) {
1310 err = codec->driver->remove(codec);
1311 if (err < 0)
1312 dev_err(codec->dev,
1313 "asoc: failed to remove %s: %d\n",
1314 codec->name, err);
1315 }
1316
1317 /* Make sure all DAPM widgets are freed */
1318 snd_soc_dapm_free(&codec->dapm);
1319
1320 soc_cleanup_codec_debugfs(codec);
1321 codec->probed = 0;
1322 list_del(&codec->card_list);
1323 module_put(codec->dev->driver->owner);
1324}
1325
1302static void soc_remove_dai_link(struct snd_soc_card *card, int num) 1326static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1303{ 1327{
1304 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1328 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
@@ -1310,6 +1334,7 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1310 /* unregister the rtd device */ 1334 /* unregister the rtd device */
1311 if (rtd->dev_registered) { 1335 if (rtd->dev_registered) {
1312 device_remove_file(&rtd->dev, &dev_attr_pmdown_time); 1336 device_remove_file(&rtd->dev, &dev_attr_pmdown_time);
1337 device_remove_file(&rtd->dev, &dev_attr_codec_reg);
1313 device_unregister(&rtd->dev); 1338 device_unregister(&rtd->dev);
1314 rtd->dev_registered = 0; 1339 rtd->dev_registered = 0;
1315 } 1340 }
@@ -1338,22 +1363,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1338 } 1363 }
1339 1364
1340 /* remove the CODEC */ 1365 /* remove the CODEC */
1341 if (codec && codec->probed) { 1366 if (codec && codec->probed)
1342 if (codec->driver->remove) { 1367 soc_remove_codec(codec);
1343 err = codec->driver->remove(codec);
1344 if (err < 0)
1345 printk(KERN_ERR "asoc: failed to remove %s\n", codec->name);
1346 }
1347
1348 /* Make sure all DAPM widgets are freed */
1349 snd_soc_dapm_free(codec);
1350
1351 soc_cleanup_codec_debugfs(codec);
1352 device_remove_file(&rtd->dev, &dev_attr_codec_reg);
1353 codec->probed = 0;
1354 list_del(&codec->card_list);
1355 module_put(codec->dev->driver->owner);
1356 }
1357 1368
1358 /* remove the cpu_dai */ 1369 /* remove the cpu_dai */
1359 if (cpu_dai && cpu_dai->probed) { 1370 if (cpu_dai && cpu_dai->probed) {
@@ -1368,8 +1379,126 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
1368 } 1379 }
1369} 1380}
1370 1381
1382static void soc_set_name_prefix(struct snd_soc_card *card,
1383 struct snd_soc_codec *codec)
1384{
1385 int i;
1386
1387 if (card->codec_conf == NULL)
1388 return;
1389
1390 for (i = 0; i < card->num_configs; i++) {
1391 struct snd_soc_codec_conf *map = &card->codec_conf[i];
1392 if (map->dev_name && !strcmp(codec->name, map->dev_name)) {
1393 codec->name_prefix = map->name_prefix;
1394 break;
1395 }
1396 }
1397}
1398
1399static int soc_probe_codec(struct snd_soc_card *card,
1400 struct snd_soc_codec *codec)
1401{
1402 int ret = 0;
1403
1404 codec->card = card;
1405 codec->dapm.card = card;
1406 soc_set_name_prefix(card, codec);
1407
1408 if (codec->driver->probe) {
1409 ret = codec->driver->probe(codec);
1410 if (ret < 0) {
1411 dev_err(codec->dev,
1412 "asoc: failed to probe CODEC %s: %d\n",
1413 codec->name, ret);
1414 return ret;
1415 }
1416 }
1417
1418 soc_init_codec_debugfs(codec);
1419
1420 /* mark codec as probed and add to card codec list */
1421 if (!try_module_get(codec->dev->driver->owner))
1422 return -ENODEV;
1423
1424 codec->probed = 1;
1425 list_add(&codec->card_list, &card->codec_dev_list);
1426 list_add(&codec->dapm.list, &card->dapm_list);
1427
1428 return ret;
1429}
1430
1371static void rtd_release(struct device *dev) {} 1431static void rtd_release(struct device *dev) {}
1372 1432
1433static int soc_post_component_init(struct snd_soc_card *card,
1434 struct snd_soc_codec *codec,
1435 int num, int dailess)
1436{
1437 struct snd_soc_dai_link *dai_link = NULL;
1438 struct snd_soc_aux_dev *aux_dev = NULL;
1439 struct snd_soc_pcm_runtime *rtd;
1440 const char *temp, *name;
1441 int ret = 0;
1442
1443 if (!dailess) {
1444 dai_link = &card->dai_link[num];
1445 rtd = &card->rtd[num];
1446 name = dai_link->name;
1447 } else {
1448 aux_dev = &card->aux_dev[num];
1449 rtd = &card->rtd_aux[num];
1450 name = aux_dev->name;
1451 }
1452
1453 /* machine controls, routes and widgets are not prefixed */
1454 temp = codec->name_prefix;
1455 codec->name_prefix = NULL;
1456
1457 /* do machine specific initialization */
1458 if (!dailess && dai_link->init)
1459 ret = dai_link->init(rtd);
1460 else if (dailess && aux_dev->init)
1461 ret = aux_dev->init(&codec->dapm);
1462 if (ret < 0) {
1463 dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret);
1464 return ret;
1465 }
1466 codec->name_prefix = temp;
1467
1468 /* Make sure all DAPM widgets are instantiated */
1469 snd_soc_dapm_new_widgets(&codec->dapm);
1470 snd_soc_dapm_sync(&codec->dapm);
1471
1472 /* register the rtd device */
1473 rtd->codec = codec;
1474 rtd->card = card;
1475 rtd->dev.parent = card->dev;
1476 rtd->dev.release = rtd_release;
1477 rtd->dev.init_name = name;
1478 ret = device_register(&rtd->dev);
1479 if (ret < 0) {
1480 dev_err(card->dev,
1481 "asoc: failed to register runtime device: %d\n", ret);
1482 return ret;
1483 }
1484 rtd->dev_registered = 1;
1485
1486 /* add DAPM sysfs entries for this codec */
1487 ret = snd_soc_dapm_sys_add(&rtd->dev);
1488 if (ret < 0)
1489 dev_err(codec->dev,
1490 "asoc: failed to add codec dapm sysfs entries: %d\n",
1491 ret);
1492
1493 /* add codec sysfs entries */
1494 ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
1495 if (ret < 0)
1496 dev_err(codec->dev,
1497 "asoc: failed to add codec sysfs files: %d\n", ret);
1498
1499 return 0;
1500}
1501
1373static int soc_probe_dai_link(struct snd_soc_card *card, int num) 1502static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1374{ 1503{
1375 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 1504 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
@@ -1383,10 +1512,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1383 1512
1384 /* config components */ 1513 /* config components */
1385 codec_dai->codec = codec; 1514 codec_dai->codec = codec;
1386 codec->card = card;
1387 cpu_dai->platform = platform; 1515 cpu_dai->platform = platform;
1388 rtd->card = card;
1389 rtd->dev.parent = card->dev;
1390 codec_dai->card = card; 1516 codec_dai->card = card;
1391 cpu_dai->card = card; 1517 cpu_dai->card = card;
1392 1518
@@ -1410,20 +1536,9 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1410 1536
1411 /* probe the CODEC */ 1537 /* probe the CODEC */
1412 if (!codec->probed) { 1538 if (!codec->probed) {
1413 if (codec->driver->probe) { 1539 ret = soc_probe_codec(card, codec);
1414 ret = codec->driver->probe(codec); 1540 if (ret < 0)
1415 if (ret < 0) { 1541 return ret;
1416 printk(KERN_ERR "asoc: failed to probe CODEC %s\n",
1417 codec->name);
1418 return ret;
1419 }
1420 }
1421
1422 soc_init_codec_debugfs(codec);
1423
1424 /* mark codec as probed and add to card codec list */
1425 codec->probed = 1;
1426 list_add(&codec->card_list, &card->codec_dev_list);
1427 } 1542 }
1428 1543
1429 /* probe the platform */ 1544 /* probe the platform */
@@ -1437,6 +1552,10 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1437 } 1552 }
1438 } 1553 }
1439 /* mark platform as probed and add to card platform list */ 1554 /* mark platform as probed and add to card platform list */
1555
1556 if (!try_module_get(platform->dev->driver->owner))
1557 return -ENODEV;
1558
1440 platform->probed = 1; 1559 platform->probed = 1;
1441 list_add(&platform->card_list, &card->platform_dev_list); 1560 list_add(&platform->card_list, &card->platform_dev_list);
1442 } 1561 }
@@ -1460,43 +1579,14 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
1460 /* DAPM dai link stream work */ 1579 /* DAPM dai link stream work */
1461 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); 1580 INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
1462 1581
1463 /* now that all clients have probed, initialise the DAI link */ 1582 ret = soc_post_component_init(card, codec, num, 0);
1464 if (dai_link->init) { 1583 if (ret)
1465 ret = dai_link->init(rtd);
1466 if (ret < 0) {
1467 printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name);
1468 return ret;
1469 }
1470 }
1471
1472 /* Make sure all DAPM widgets are instantiated */
1473 snd_soc_dapm_new_widgets(codec);
1474 snd_soc_dapm_sync(codec);
1475
1476 /* register the rtd device */
1477 rtd->dev.release = rtd_release;
1478 rtd->dev.init_name = dai_link->name;
1479 ret = device_register(&rtd->dev);
1480 if (ret < 0) {
1481 printk(KERN_ERR "asoc: failed to register DAI runtime device %d\n", ret);
1482 return ret; 1584 return ret;
1483 }
1484 1585
1485 rtd->dev_registered = 1;
1486 ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time); 1586 ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time);
1487 if (ret < 0) 1587 if (ret < 0)
1488 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n"); 1588 printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
1489 1589
1490 /* add DAPM sysfs entries for this codec */
1491 ret = snd_soc_dapm_sys_add(&rtd->dev);
1492 if (ret < 0)
1493 printk(KERN_WARNING "asoc: failed to add codec dapm sysfs entries\n");
1494
1495 /* add codec sysfs entries */
1496 ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
1497 if (ret < 0)
1498 printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
1499
1500 /* create the pcm */ 1590 /* create the pcm */
1501 ret = soc_new_pcm(rtd, num); 1591 ret = soc_new_pcm(rtd, num);
1502 if (ret < 0) { 1592 if (ret < 0) {
@@ -1551,9 +1641,85 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
1551} 1641}
1552#endif 1642#endif
1553 1643
1644static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
1645{
1646 struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
1647 struct snd_soc_codec *codec;
1648 int ret = -ENODEV;
1649
1650 /* find CODEC from registered CODECs*/
1651 list_for_each_entry(codec, &codec_list, list) {
1652 if (!strcmp(codec->name, aux_dev->codec_name)) {
1653 if (codec->probed) {
1654 dev_err(codec->dev,
1655 "asoc: codec already probed");
1656 ret = -EBUSY;
1657 goto out;
1658 }
1659 goto found;
1660 }
1661 }
1662 /* codec not found */
1663 dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name);
1664 goto out;
1665
1666found:
1667 if (!try_module_get(codec->dev->driver->owner))
1668 return -ENODEV;
1669
1670 ret = soc_probe_codec(card, codec);
1671 if (ret < 0)
1672 return ret;
1673
1674 ret = soc_post_component_init(card, codec, num, 1);
1675
1676out:
1677 return ret;
1678}
1679
1680static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
1681{
1682 struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
1683 struct snd_soc_codec *codec = rtd->codec;
1684
1685 /* unregister the rtd device */
1686 if (rtd->dev_registered) {
1687 device_remove_file(&rtd->dev, &dev_attr_codec_reg);
1688 device_unregister(&rtd->dev);
1689 rtd->dev_registered = 0;
1690 }
1691
1692 if (codec && codec->probed)
1693 soc_remove_codec(codec);
1694}
1695
1696static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
1697 enum snd_soc_compress_type compress_type)
1698{
1699 int ret;
1700
1701 if (codec->cache_init)
1702 return 0;
1703
1704 /* override the compress_type if necessary */
1705 if (compress_type && codec->compress_type != compress_type)
1706 codec->compress_type = compress_type;
1707 ret = snd_soc_cache_init(codec);
1708 if (ret < 0) {
1709 dev_err(codec->dev, "Failed to set cache compression type: %d\n",
1710 ret);
1711 return ret;
1712 }
1713 codec->cache_init = 1;
1714 return 0;
1715}
1716
1554static void snd_soc_instantiate_card(struct snd_soc_card *card) 1717static void snd_soc_instantiate_card(struct snd_soc_card *card)
1555{ 1718{
1556 struct platform_device *pdev = to_platform_device(card->dev); 1719 struct platform_device *pdev = to_platform_device(card->dev);
1720 struct snd_soc_codec *codec;
1721 struct snd_soc_codec_conf *codec_conf;
1722 enum snd_soc_compress_type compress_type;
1557 int ret, i; 1723 int ret, i;
1558 1724
1559 mutex_lock(&card->mutex); 1725 mutex_lock(&card->mutex);
@@ -1573,6 +1739,39 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1573 return; 1739 return;
1574 } 1740 }
1575 1741
1742 /* initialize the register cache for each available codec */
1743 list_for_each_entry(codec, &codec_list, list) {
1744 if (codec->cache_init)
1745 continue;
1746 /* check to see if we need to override the compress_type */
1747 for (i = 0; i < card->num_configs; ++i) {
1748 codec_conf = &card->codec_conf[i];
1749 if (!strcmp(codec->name, codec_conf->dev_name)) {
1750 compress_type = codec_conf->compress_type;
1751 if (compress_type && compress_type
1752 != codec->compress_type)
1753 break;
1754 }
1755 }
1756 if (i == card->num_configs) {
1757 /* no need to override the compress_type so
1758 * go ahead and do the standard thing */
1759 ret = snd_soc_init_codec_cache(codec, 0);
1760 if (ret < 0) {
1761 mutex_unlock(&card->mutex);
1762 return;
1763 }
1764 continue;
1765 }
1766 /* override the compress_type with the one supplied in
1767 * the machine driver */
1768 ret = snd_soc_init_codec_cache(codec, compress_type);
1769 if (ret < 0) {
1770 mutex_unlock(&card->mutex);
1771 return;
1772 }
1773 }
1774
1576 /* card bind complete so register a sound card */ 1775 /* card bind complete so register a sound card */
1577 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 1776 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
1578 card->owner, 0, &card->snd_card); 1777 card->owner, 0, &card->snd_card);
@@ -1605,6 +1804,15 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1605 } 1804 }
1606 } 1805 }
1607 1806
1807 for (i = 0; i < card->num_aux_devs; i++) {
1808 ret = soc_probe_aux_dev(card, i);
1809 if (ret < 0) {
1810 pr_err("asoc: failed to add auxiliary devices %s: %d\n",
1811 card->name, ret);
1812 goto probe_aux_dev_err;
1813 }
1814 }
1815
1608 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), 1816 snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
1609 "%s", card->name); 1817 "%s", card->name);
1610 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), 1818 snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
@@ -1613,7 +1821,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1613 ret = snd_card_register(card->snd_card); 1821 ret = snd_card_register(card->snd_card);
1614 if (ret < 0) { 1822 if (ret < 0) {
1615 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); 1823 printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name);
1616 goto probe_dai_err; 1824 goto probe_aux_dev_err;
1617 } 1825 }
1618 1826
1619#ifdef CONFIG_SND_SOC_AC97_BUS 1827#ifdef CONFIG_SND_SOC_AC97_BUS
@@ -1623,8 +1831,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1623 if (ret < 0) { 1831 if (ret < 0) {
1624 printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); 1832 printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name);
1625 while (--i >= 0) 1833 while (--i >= 0)
1626 soc_unregister_ac97_dai_link(&card->rtd[i]); 1834 soc_unregister_ac97_dai_link(card->rtd[i].codec);
1627 goto probe_dai_err; 1835 goto probe_aux_dev_err;
1628 } 1836 }
1629 } 1837 }
1630#endif 1838#endif
@@ -1633,6 +1841,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
1633 mutex_unlock(&card->mutex); 1841 mutex_unlock(&card->mutex);
1634 return; 1842 return;
1635 1843
1844probe_aux_dev_err:
1845 for (i = 0; i < card->num_aux_devs; i++)
1846 soc_remove_aux_dev(card, i);
1847
1636probe_dai_err: 1848probe_dai_err:
1637 for (i = 0; i < card->num_links; i++) 1849 for (i = 0; i < card->num_links; i++)
1638 soc_remove_dai_link(card, i); 1850 soc_remove_dai_link(card, i);
@@ -1668,6 +1880,11 @@ static int soc_probe(struct platform_device *pdev)
1668 INIT_LIST_HEAD(&card->dai_dev_list); 1880 INIT_LIST_HEAD(&card->dai_dev_list);
1669 INIT_LIST_HEAD(&card->codec_dev_list); 1881 INIT_LIST_HEAD(&card->codec_dev_list);
1670 INIT_LIST_HEAD(&card->platform_dev_list); 1882 INIT_LIST_HEAD(&card->platform_dev_list);
1883 INIT_LIST_HEAD(&card->widgets);
1884 INIT_LIST_HEAD(&card->paths);
1885 INIT_LIST_HEAD(&card->dapm_list);
1886
1887 soc_init_card_debugfs(card);
1671 1888
1672 ret = snd_soc_register_card(card); 1889 ret = snd_soc_register_card(card);
1673 if (ret != 0) { 1890 if (ret != 0) {
@@ -1689,13 +1906,19 @@ static int soc_remove(struct platform_device *pdev)
1689 /* make sure any delayed work runs */ 1906 /* make sure any delayed work runs */
1690 for (i = 0; i < card->num_rtd; i++) { 1907 for (i = 0; i < card->num_rtd; i++) {
1691 struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; 1908 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1692 run_delayed_work(&rtd->delayed_work); 1909 flush_delayed_work_sync(&rtd->delayed_work);
1693 } 1910 }
1694 1911
1912 /* remove auxiliary devices */
1913 for (i = 0; i < card->num_aux_devs; i++)
1914 soc_remove_aux_dev(card, i);
1915
1695 /* remove and free each DAI */ 1916 /* remove and free each DAI */
1696 for (i = 0; i < card->num_rtd; i++) 1917 for (i = 0; i < card->num_rtd; i++)
1697 soc_remove_dai_link(card, i); 1918 soc_remove_dai_link(card, i);
1698 1919
1920 soc_cleanup_card_debugfs(card);
1921
1699 /* remove the card */ 1922 /* remove the card */
1700 if (card->remove) 1923 if (card->remove)
1701 card->remove(pdev); 1924 card->remove(pdev);
@@ -1720,7 +1943,7 @@ static int soc_poweroff(struct device *dev)
1720 * now, we're shutting down so no imminent restart. */ 1943 * now, we're shutting down so no imminent restart. */
1721 for (i = 0; i < card->num_rtd; i++) { 1944 for (i = 0; i < card->num_rtd; i++) {
1722 struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; 1945 struct snd_soc_pcm_runtime *rtd = &card->rtd[i];
1723 run_delayed_work(&rtd->delayed_work); 1946 flush_delayed_work_sync(&rtd->delayed_work);
1724 } 1947 }
1725 1948
1726 snd_soc_dapm_shutdown(card); 1949 snd_soc_dapm_shutdown(card);
@@ -1879,6 +2102,27 @@ void snd_soc_free_ac97_codec(struct snd_soc_codec *codec)
1879} 2102}
1880EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec); 2103EXPORT_SYMBOL_GPL(snd_soc_free_ac97_codec);
1881 2104
2105unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg)
2106{
2107 unsigned int ret;
2108
2109 ret = codec->read(codec, reg);
2110 dev_dbg(codec->dev, "read %x => %x\n", reg, ret);
2111 trace_snd_soc_reg_read(codec, reg, ret);
2112
2113 return ret;
2114}
2115EXPORT_SYMBOL_GPL(snd_soc_read);
2116
2117unsigned int snd_soc_write(struct snd_soc_codec *codec,
2118 unsigned int reg, unsigned int val)
2119{
2120 dev_dbg(codec->dev, "write %x = %x\n", reg, val);
2121 trace_snd_soc_reg_write(codec, reg, val);
2122 return codec->write(codec, reg, val);
2123}
2124EXPORT_SYMBOL_GPL(snd_soc_write);
2125
1882/** 2126/**
1883 * snd_soc_update_bits - update codec register bits 2127 * snd_soc_update_bits - update codec register bits
1884 * @codec: audio codec 2128 * @codec: audio codec
@@ -2019,14 +2263,22 @@ int snd_soc_add_controls(struct snd_soc_codec *codec,
2019 const struct snd_kcontrol_new *controls, int num_controls) 2263 const struct snd_kcontrol_new *controls, int num_controls)
2020{ 2264{
2021 struct snd_card *card = codec->card->snd_card; 2265 struct snd_card *card = codec->card->snd_card;
2266 char prefixed_name[44], *name;
2022 int err, i; 2267 int err, i;
2023 2268
2024 for (i = 0; i < num_controls; i++) { 2269 for (i = 0; i < num_controls; i++) {
2025 const struct snd_kcontrol_new *control = &controls[i]; 2270 const struct snd_kcontrol_new *control = &controls[i];
2026 err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL)); 2271 if (codec->name_prefix) {
2272 snprintf(prefixed_name, sizeof(prefixed_name), "%s %s",
2273 codec->name_prefix, control->name);
2274 name = prefixed_name;
2275 } else {
2276 name = control->name;
2277 }
2278 err = snd_ctl_add(card, snd_soc_cnew(control, codec, name));
2027 if (err < 0) { 2279 if (err < 0) {
2028 dev_err(codec->dev, "%s: Failed to add %s: %d\n", 2280 dev_err(codec->dev, "%s: Failed to add %s: %d\n",
2029 codec->name, control->name, err); 2281 codec->name, name, err);
2030 return err; 2282 return err;
2031 } 2283 }
2032 } 2284 }
@@ -2863,10 +3115,12 @@ static int snd_soc_register_card(struct snd_soc_card *card)
2863 if (!card->name || !card->dev) 3115 if (!card->name || !card->dev)
2864 return -EINVAL; 3116 return -EINVAL;
2865 3117
2866 card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * card->num_links, 3118 card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) *
2867 GFP_KERNEL); 3119 (card->num_links + card->num_aux_devs),
3120 GFP_KERNEL);
2868 if (card->rtd == NULL) 3121 if (card->rtd == NULL)
2869 return -ENOMEM; 3122 return -ENOMEM;
3123 card->rtd_aux = &card->rtd[card->num_links];
2870 3124
2871 for (i = 0; i < card->num_links; i++) 3125 for (i = 0; i < card->num_links; i++)
2872 card->rtd[i].dai_link = &card->dai_link[i]; 3126 card->rtd[i].dai_link = &card->dai_link[i];
@@ -2908,7 +3162,7 @@ static int snd_soc_unregister_card(struct snd_soc_card *card)
2908 * Simplify DAI link configuration by removing ".-1" from device names 3162 * Simplify DAI link configuration by removing ".-1" from device names
2909 * and sanitizing names. 3163 * and sanitizing names.
2910 */ 3164 */
2911static inline char *fmt_single_name(struct device *dev, int *id) 3165static char *fmt_single_name(struct device *dev, int *id)
2912{ 3166{
2913 char *found, name[NAME_SIZE]; 3167 char *found, name[NAME_SIZE];
2914 int id1, id2; 3168 int id1, id2;
@@ -2916,7 +3170,7 @@ static inline char *fmt_single_name(struct device *dev, int *id)
2916 if (dev_name(dev) == NULL) 3170 if (dev_name(dev) == NULL)
2917 return NULL; 3171 return NULL;
2918 3172
2919 strncpy(name, dev_name(dev), NAME_SIZE); 3173 strlcpy(name, dev_name(dev), NAME_SIZE);
2920 3174
2921 /* are we a "%s.%d" name (platform and SPI components) */ 3175 /* are we a "%s.%d" name (platform and SPI components) */
2922 found = strstr(name, dev->driver->name); 3176 found = strstr(name, dev->driver->name);
@@ -2939,7 +3193,7 @@ static inline char *fmt_single_name(struct device *dev, int *id)
2939 3193
2940 /* sanitize component name for DAI link creation */ 3194 /* sanitize component name for DAI link creation */
2941 snprintf(tmp, NAME_SIZE, "%s.%s", dev->driver->name, name); 3195 snprintf(tmp, NAME_SIZE, "%s.%s", dev->driver->name, name);
2942 strncpy(name, tmp, NAME_SIZE); 3196 strlcpy(name, tmp, NAME_SIZE);
2943 } else 3197 } else
2944 *id = 0; 3198 *id = 0;
2945 } 3199 }
@@ -3204,9 +3458,11 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream)
3204 * @codec: codec to register 3458 * @codec: codec to register
3205 */ 3459 */
3206int snd_soc_register_codec(struct device *dev, 3460int snd_soc_register_codec(struct device *dev,
3207 struct snd_soc_codec_driver *codec_drv, 3461 const struct snd_soc_codec_driver *codec_drv,
3208 struct snd_soc_dai_driver *dai_drv, int num_dai) 3462 struct snd_soc_dai_driver *dai_drv,
3463 int num_dai)
3209{ 3464{
3465 size_t reg_size;
3210 struct snd_soc_codec *codec; 3466 struct snd_soc_codec *codec;
3211 int ret, i; 3467 int ret, i;
3212 3468
@@ -3223,30 +3479,37 @@ int snd_soc_register_codec(struct device *dev,
3223 return -ENOMEM; 3479 return -ENOMEM;
3224 } 3480 }
3225 3481
3226 /* allocate CODEC register cache */ 3482 if (codec_drv->compress_type)
3227 if (codec_drv->reg_cache_size && codec_drv->reg_word_size) { 3483 codec->compress_type = codec_drv->compress_type;
3228 3484 else
3229 if (codec_drv->reg_cache_default) 3485 codec->compress_type = SND_SOC_FLAT_COMPRESSION;
3230 codec->reg_cache = kmemdup(codec_drv->reg_cache_default,
3231 codec_drv->reg_cache_size * codec_drv->reg_word_size, GFP_KERNEL);
3232 else
3233 codec->reg_cache = kzalloc(codec_drv->reg_cache_size *
3234 codec_drv->reg_word_size, GFP_KERNEL);
3235
3236 if (codec->reg_cache == NULL) {
3237 kfree(codec->name);
3238 kfree(codec);
3239 return -ENOMEM;
3240 }
3241 }
3242 3486
3487 codec->write = codec_drv->write;
3488 codec->read = codec_drv->read;
3489 codec->dapm.bias_level = SND_SOC_BIAS_OFF;
3490 codec->dapm.dev = dev;
3491 codec->dapm.codec = codec;
3243 codec->dev = dev; 3492 codec->dev = dev;
3244 codec->driver = codec_drv; 3493 codec->driver = codec_drv;
3245 codec->bias_level = SND_SOC_BIAS_OFF;
3246 codec->num_dai = num_dai; 3494 codec->num_dai = num_dai;
3247 mutex_init(&codec->mutex); 3495 mutex_init(&codec->mutex);
3248 INIT_LIST_HEAD(&codec->dapm_widgets); 3496
3249 INIT_LIST_HEAD(&codec->dapm_paths); 3497 /* allocate CODEC register cache */
3498 if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
3499 reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
3500 /* it is necessary to make a copy of the default register cache
3501 * because in the case of using a compression type that requires
3502 * the default register cache to be marked as __devinitconst the
3503 * kernel might have freed the array by the time we initialize
3504 * the cache.
3505 */
3506 codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default,
3507 reg_size, GFP_KERNEL);
3508 if (!codec->reg_def_copy) {
3509 ret = -ENOMEM;
3510 goto fail;
3511 }
3512 }
3250 3513
3251 for (i = 0; i < num_dai; i++) { 3514 for (i = 0; i < num_dai; i++) {
3252 fixup_codec_formats(&dai_drv[i].playback); 3515 fixup_codec_formats(&dai_drv[i].playback);
@@ -3257,7 +3520,7 @@ int snd_soc_register_codec(struct device *dev,
3257 if (num_dai) { 3520 if (num_dai) {
3258 ret = snd_soc_register_dais(dev, dai_drv, num_dai); 3521 ret = snd_soc_register_dais(dev, dai_drv, num_dai);
3259 if (ret < 0) 3522 if (ret < 0)
3260 goto error; 3523 goto fail;
3261 } 3524 }
3262 3525
3263 mutex_lock(&client_mutex); 3526 mutex_lock(&client_mutex);
@@ -3268,9 +3531,9 @@ int snd_soc_register_codec(struct device *dev,
3268 pr_debug("Registered codec '%s'\n", codec->name); 3531 pr_debug("Registered codec '%s'\n", codec->name);
3269 return 0; 3532 return 0;
3270 3533
3271error: 3534fail:
3272 if (codec->reg_cache) 3535 kfree(codec->reg_def_copy);
3273 kfree(codec->reg_cache); 3536 codec->reg_def_copy = NULL;
3274 kfree(codec->name); 3537 kfree(codec->name);
3275 kfree(codec); 3538 kfree(codec);
3276 return ret; 3539 return ret;
@@ -3304,8 +3567,8 @@ found:
3304 3567
3305 pr_debug("Unregistered codec '%s'\n", codec->name); 3568 pr_debug("Unregistered codec '%s'\n", codec->name);
3306 3569
3307 if (codec->reg_cache) 3570 snd_soc_cache_exit(codec);
3308 kfree(codec->reg_cache); 3571 kfree(codec->reg_def_copy);
3309 kfree(codec->name); 3572 kfree(codec->name);
3310 kfree(codec); 3573 kfree(codec);
3311} 3574}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index c721502833bc..499730ab5638 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -42,9 +42,11 @@
42#include <sound/core.h> 42#include <sound/core.h>
43#include <sound/pcm.h> 43#include <sound/pcm.h>
44#include <sound/pcm_params.h> 44#include <sound/pcm_params.h>
45#include <sound/soc-dapm.h> 45#include <sound/soc.h>
46#include <sound/initval.h> 46#include <sound/initval.h>
47 47
48#include <trace/events/asoc.h>
49
48/* dapm power sequences - make this per codec in the future */ 50/* dapm power sequences - make this per codec in the future */
49static int dapm_up_seq[] = { 51static int dapm_up_seq[] = {
50 [snd_soc_dapm_pre] = 0, 52 [snd_soc_dapm_pre] = 0,
@@ -54,12 +56,14 @@ static int dapm_up_seq[] = {
54 [snd_soc_dapm_aif_out] = 3, 56 [snd_soc_dapm_aif_out] = 3,
55 [snd_soc_dapm_mic] = 4, 57 [snd_soc_dapm_mic] = 4,
56 [snd_soc_dapm_mux] = 5, 58 [snd_soc_dapm_mux] = 5,
59 [snd_soc_dapm_virt_mux] = 5,
57 [snd_soc_dapm_value_mux] = 5, 60 [snd_soc_dapm_value_mux] = 5,
58 [snd_soc_dapm_dac] = 6, 61 [snd_soc_dapm_dac] = 6,
59 [snd_soc_dapm_mixer] = 7, 62 [snd_soc_dapm_mixer] = 7,
60 [snd_soc_dapm_mixer_named_ctl] = 7, 63 [snd_soc_dapm_mixer_named_ctl] = 7,
61 [snd_soc_dapm_pga] = 8, 64 [snd_soc_dapm_pga] = 8,
62 [snd_soc_dapm_adc] = 9, 65 [snd_soc_dapm_adc] = 9,
66 [snd_soc_dapm_out_drv] = 10,
63 [snd_soc_dapm_hp] = 10, 67 [snd_soc_dapm_hp] = 10,
64 [snd_soc_dapm_spk] = 10, 68 [snd_soc_dapm_spk] = 10,
65 [snd_soc_dapm_post] = 11, 69 [snd_soc_dapm_post] = 11,
@@ -70,6 +74,7 @@ static int dapm_down_seq[] = {
70 [snd_soc_dapm_adc] = 1, 74 [snd_soc_dapm_adc] = 1,
71 [snd_soc_dapm_hp] = 2, 75 [snd_soc_dapm_hp] = 2,
72 [snd_soc_dapm_spk] = 2, 76 [snd_soc_dapm_spk] = 2,
77 [snd_soc_dapm_out_drv] = 2,
73 [snd_soc_dapm_pga] = 4, 78 [snd_soc_dapm_pga] = 4,
74 [snd_soc_dapm_mixer_named_ctl] = 5, 79 [snd_soc_dapm_mixer_named_ctl] = 5,
75 [snd_soc_dapm_mixer] = 5, 80 [snd_soc_dapm_mixer] = 5,
@@ -77,6 +82,7 @@ static int dapm_down_seq[] = {
77 [snd_soc_dapm_mic] = 7, 82 [snd_soc_dapm_mic] = 7,
78 [snd_soc_dapm_micbias] = 8, 83 [snd_soc_dapm_micbias] = 8,
79 [snd_soc_dapm_mux] = 9, 84 [snd_soc_dapm_mux] = 9,
85 [snd_soc_dapm_virt_mux] = 9,
80 [snd_soc_dapm_value_mux] = 9, 86 [snd_soc_dapm_value_mux] = 9,
81 [snd_soc_dapm_aif_in] = 10, 87 [snd_soc_dapm_aif_in] = 10,
82 [snd_soc_dapm_aif_out] = 10, 88 [snd_soc_dapm_aif_out] = 10,
@@ -90,17 +96,24 @@ static void pop_wait(u32 pop_time)
90 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); 96 schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time));
91} 97}
92 98
93static void pop_dbg(u32 pop_time, const char *fmt, ...) 99static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...)
94{ 100{
95 va_list args; 101 va_list args;
102 char *buf;
96 103
97 va_start(args, fmt); 104 if (!pop_time)
105 return;
98 106
99 if (pop_time) { 107 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
100 vprintk(fmt, args); 108 if (buf == NULL)
101 } 109 return;
102 110
111 va_start(args, fmt);
112 vsnprintf(buf, PAGE_SIZE, fmt, args);
113 dev_info(dev, "%s", buf);
103 va_end(args); 114 va_end(args);
115
116 kfree(buf);
104} 117}
105 118
106/* create a new dapm widget */ 119/* create a new dapm widget */
@@ -120,36 +133,45 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
120 * Returns 0 for success else error. 133 * Returns 0 for success else error.
121 */ 134 */
122static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, 135static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card,
123 struct snd_soc_codec *codec, enum snd_soc_bias_level level) 136 struct snd_soc_dapm_context *dapm,
137 enum snd_soc_bias_level level)
124{ 138{
125 int ret = 0; 139 int ret = 0;
126 140
127 switch (level) { 141 switch (level) {
128 case SND_SOC_BIAS_ON: 142 case SND_SOC_BIAS_ON:
129 dev_dbg(codec->dev, "Setting full bias\n"); 143 dev_dbg(dapm->dev, "Setting full bias\n");
130 break; 144 break;
131 case SND_SOC_BIAS_PREPARE: 145 case SND_SOC_BIAS_PREPARE:
132 dev_dbg(codec->dev, "Setting bias prepare\n"); 146 dev_dbg(dapm->dev, "Setting bias prepare\n");
133 break; 147 break;
134 case SND_SOC_BIAS_STANDBY: 148 case SND_SOC_BIAS_STANDBY:
135 dev_dbg(codec->dev, "Setting standby bias\n"); 149 dev_dbg(dapm->dev, "Setting standby bias\n");
136 break; 150 break;
137 case SND_SOC_BIAS_OFF: 151 case SND_SOC_BIAS_OFF:
138 dev_dbg(codec->dev, "Setting bias off\n"); 152 dev_dbg(dapm->dev, "Setting bias off\n");
139 break; 153 break;
140 default: 154 default:
141 dev_err(codec->dev, "Setting invalid bias %d\n", level); 155 dev_err(dapm->dev, "Setting invalid bias %d\n", level);
142 return -EINVAL; 156 return -EINVAL;
143 } 157 }
144 158
159 trace_snd_soc_bias_level_start(card, level);
160
145 if (card && card->set_bias_level) 161 if (card && card->set_bias_level)
146 ret = card->set_bias_level(card, level); 162 ret = card->set_bias_level(card, level);
147 if (ret == 0) { 163 if (ret == 0) {
148 if (codec->driver->set_bias_level) 164 if (dapm->codec && dapm->codec->driver->set_bias_level)
149 ret = codec->driver->set_bias_level(codec, level); 165 ret = dapm->codec->driver->set_bias_level(dapm->codec, level);
150 else 166 else
151 codec->bias_level = level; 167 dapm->bias_level = level;
152 } 168 }
169 if (ret == 0) {
170 if (card && card->set_bias_level_post)
171 ret = card->set_bias_level_post(card, level);
172 }
173
174 trace_snd_soc_bias_level_done(card, level);
153 175
154 return ret; 176 return ret;
155} 177}
@@ -196,6 +218,20 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
196 } 218 }
197 } 219 }
198 break; 220 break;
221 case snd_soc_dapm_virt_mux: {
222 struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value;
223
224 p->connect = 0;
225 /* since a virtual mux has no backing registers to
226 * decide which path to connect, it will try to match
227 * with the first enumeration. This is to ensure
228 * that the default mux choice (the first) will be
229 * correctly powered up during initialization.
230 */
231 if (!strcmp(p->name, e->texts[0]))
232 p->connect = 1;
233 }
234 break;
199 case snd_soc_dapm_value_mux: { 235 case snd_soc_dapm_value_mux: {
200 struct soc_enum *e = (struct soc_enum *) 236 struct soc_enum *e = (struct soc_enum *)
201 w->kcontrols[i].private_value; 237 w->kcontrols[i].private_value;
@@ -217,6 +253,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
217 break; 253 break;
218 /* does not effect routing - always connected */ 254 /* does not effect routing - always connected */
219 case snd_soc_dapm_pga: 255 case snd_soc_dapm_pga:
256 case snd_soc_dapm_out_drv:
220 case snd_soc_dapm_output: 257 case snd_soc_dapm_output:
221 case snd_soc_dapm_adc: 258 case snd_soc_dapm_adc:
222 case snd_soc_dapm_input: 259 case snd_soc_dapm_input:
@@ -241,7 +278,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
241} 278}
242 279
243/* connect mux widget to its interconnecting audio paths */ 280/* connect mux widget to its interconnecting audio paths */
244static int dapm_connect_mux(struct snd_soc_codec *codec, 281static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
245 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 282 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
246 struct snd_soc_dapm_path *path, const char *control_name, 283 struct snd_soc_dapm_path *path, const char *control_name,
247 const struct snd_kcontrol_new *kcontrol) 284 const struct snd_kcontrol_new *kcontrol)
@@ -251,7 +288,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
251 288
252 for (i = 0; i < e->max; i++) { 289 for (i = 0; i < e->max; i++) {
253 if (!(strcmp(control_name, e->texts[i]))) { 290 if (!(strcmp(control_name, e->texts[i]))) {
254 list_add(&path->list, &codec->dapm_paths); 291 list_add(&path->list, &dapm->card->paths);
255 list_add(&path->list_sink, &dest->sources); 292 list_add(&path->list_sink, &dest->sources);
256 list_add(&path->list_source, &src->sinks); 293 list_add(&path->list_source, &src->sinks);
257 path->name = (char*)e->texts[i]; 294 path->name = (char*)e->texts[i];
@@ -264,7 +301,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
264} 301}
265 302
266/* connect mixer widget to its interconnecting audio paths */ 303/* connect mixer widget to its interconnecting audio paths */
267static int dapm_connect_mixer(struct snd_soc_codec *codec, 304static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
268 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, 305 struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
269 struct snd_soc_dapm_path *path, const char *control_name) 306 struct snd_soc_dapm_path *path, const char *control_name)
270{ 307{
@@ -273,7 +310,7 @@ static int dapm_connect_mixer(struct snd_soc_codec *codec,
273 /* search for mixer kcontrol */ 310 /* search for mixer kcontrol */
274 for (i = 0; i < dest->num_kcontrols; i++) { 311 for (i = 0; i < dest->num_kcontrols; i++) {
275 if (!strcmp(control_name, dest->kcontrols[i].name)) { 312 if (!strcmp(control_name, dest->kcontrols[i].name)) {
276 list_add(&path->list, &codec->dapm_paths); 313 list_add(&path->list, &dapm->card->paths);
277 list_add(&path->list_sink, &dest->sources); 314 list_add(&path->list_sink, &dest->sources);
278 list_add(&path->list_source, &src->sinks); 315 list_add(&path->list_source, &src->sinks);
279 path->name = dest->kcontrols[i].name; 316 path->name = dest->kcontrols[i].name;
@@ -290,6 +327,8 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
290 int change, power; 327 int change, power;
291 unsigned int old, new; 328 unsigned int old, new;
292 struct snd_soc_codec *codec = widget->codec; 329 struct snd_soc_codec *codec = widget->codec;
330 struct snd_soc_dapm_context *dapm = widget->dapm;
331 struct snd_soc_card *card = dapm->card;
293 332
294 /* check for valid widgets */ 333 /* check for valid widgets */
295 if (widget->reg < 0 || widget->id == snd_soc_dapm_input || 334 if (widget->reg < 0 || widget->id == snd_soc_dapm_input ||
@@ -309,24 +348,26 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget)
309 348
310 change = old != new; 349 change = old != new;
311 if (change) { 350 if (change) {
312 pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n", 351 pop_dbg(dapm->dev, card->pop_time,
352 "pop test %s : %s in %d ms\n",
313 widget->name, widget->power ? "on" : "off", 353 widget->name, widget->power ? "on" : "off",
314 codec->pop_time); 354 card->pop_time);
315 pop_wait(codec->pop_time); 355 pop_wait(card->pop_time);
316 snd_soc_write(codec, widget->reg, new); 356 snd_soc_write(codec, widget->reg, new);
317 } 357 }
318 pr_debug("reg %x old %x new %x change %d\n", widget->reg, 358 dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg,
319 old, new, change); 359 old, new, change);
320 return change; 360 return change;
321} 361}
322 362
323/* create new dapm mixer control */ 363/* create new dapm mixer control */
324static int dapm_new_mixer(struct snd_soc_codec *codec, 364static int dapm_new_mixer(struct snd_soc_dapm_context *dapm,
325 struct snd_soc_dapm_widget *w) 365 struct snd_soc_dapm_widget *w)
326{ 366{
327 int i, ret = 0; 367 int i, ret = 0;
328 size_t name_len; 368 size_t name_len;
329 struct snd_soc_dapm_path *path; 369 struct snd_soc_dapm_path *path;
370 struct snd_card *card = dapm->codec->card->snd_card;
330 371
331 /* add kcontrol */ 372 /* add kcontrol */
332 for (i = 0; i < w->num_kcontrols; i++) { 373 for (i = 0; i < w->num_kcontrols; i++) {
@@ -368,11 +409,11 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
368 409
369 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, 410 path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w,
370 path->long_name); 411 path->long_name);
371 ret = snd_ctl_add(codec->card->snd_card, path->kcontrol); 412 ret = snd_ctl_add(card, path->kcontrol);
372 if (ret < 0) { 413 if (ret < 0) {
373 printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", 414 dev_err(dapm->dev,
374 path->long_name, 415 "asoc: failed to add dapm kcontrol %s: %d\n",
375 ret); 416 path->long_name, ret);
376 kfree(path->long_name); 417 kfree(path->long_name);
377 path->long_name = NULL; 418 path->long_name = NULL;
378 return ret; 419 return ret;
@@ -383,20 +424,22 @@ static int dapm_new_mixer(struct snd_soc_codec *codec,
383} 424}
384 425
385/* create new dapm mux control */ 426/* create new dapm mux control */
386static int dapm_new_mux(struct snd_soc_codec *codec, 427static int dapm_new_mux(struct snd_soc_dapm_context *dapm,
387 struct snd_soc_dapm_widget *w) 428 struct snd_soc_dapm_widget *w)
388{ 429{
389 struct snd_soc_dapm_path *path = NULL; 430 struct snd_soc_dapm_path *path = NULL;
390 struct snd_kcontrol *kcontrol; 431 struct snd_kcontrol *kcontrol;
432 struct snd_card *card = dapm->codec->card->snd_card;
391 int ret = 0; 433 int ret = 0;
392 434
393 if (!w->num_kcontrols) { 435 if (!w->num_kcontrols) {
394 printk(KERN_ERR "asoc: mux %s has no controls\n", w->name); 436 dev_err(dapm->dev, "asoc: mux %s has no controls\n", w->name);
395 return -EINVAL; 437 return -EINVAL;
396 } 438 }
397 439
398 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); 440 kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name);
399 ret = snd_ctl_add(codec->card->snd_card, kcontrol); 441 ret = snd_ctl_add(card, kcontrol);
442
400 if (ret < 0) 443 if (ret < 0)
401 goto err; 444 goto err;
402 445
@@ -406,26 +449,27 @@ static int dapm_new_mux(struct snd_soc_codec *codec,
406 return ret; 449 return ret;
407 450
408err: 451err:
409 printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name); 452 dev_err(dapm->dev, "asoc: failed to add kcontrol %s\n", w->name);
410 return ret; 453 return ret;
411} 454}
412 455
413/* create new dapm volume control */ 456/* create new dapm volume control */
414static int dapm_new_pga(struct snd_soc_codec *codec, 457static int dapm_new_pga(struct snd_soc_dapm_context *dapm,
415 struct snd_soc_dapm_widget *w) 458 struct snd_soc_dapm_widget *w)
416{ 459{
417 if (w->num_kcontrols) 460 if (w->num_kcontrols)
418 pr_err("asoc: PGA controls not supported: '%s'\n", w->name); 461 dev_err(w->dapm->dev,
462 "asoc: PGA controls not supported: '%s'\n", w->name);
419 463
420 return 0; 464 return 0;
421} 465}
422 466
423/* reset 'walked' bit for each dapm path */ 467/* reset 'walked' bit for each dapm path */
424static inline void dapm_clear_walk(struct snd_soc_codec *codec) 468static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm)
425{ 469{
426 struct snd_soc_dapm_path *p; 470 struct snd_soc_dapm_path *p;
427 471
428 list_for_each_entry(p, &codec->dapm_paths, list) 472 list_for_each_entry(p, &dapm->card->paths, list)
429 p->walked = 0; 473 p->walked = 0;
430} 474}
431 475
@@ -435,13 +479,14 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec)
435 */ 479 */
436static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) 480static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget)
437{ 481{
438 int level = snd_power_get_state(widget->codec->card->snd_card); 482 int level = snd_power_get_state(widget->dapm->codec->card->snd_card);
439 483
440 switch (level) { 484 switch (level) {
441 case SNDRV_CTL_POWER_D3hot: 485 case SNDRV_CTL_POWER_D3hot:
442 case SNDRV_CTL_POWER_D3cold: 486 case SNDRV_CTL_POWER_D3cold:
443 if (widget->ignore_suspend) 487 if (widget->ignore_suspend)
444 pr_debug("%s ignoring suspend\n", widget->name); 488 dev_dbg(widget->dapm->dev, "%s ignoring suspend\n",
489 widget->name);
445 return widget->ignore_suspend; 490 return widget->ignore_suspend;
446 default: 491 default:
447 return 1; 492 return 1;
@@ -572,7 +617,7 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w)
572 617
573 /* call any power change event handlers */ 618 /* call any power change event handlers */
574 if (w->event) 619 if (w->event)
575 pr_debug("power %s event for %s flags %x\n", 620 dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n",
576 w->power ? "on" : "off", 621 w->power ? "on" : "off",
577 w->name, w->event_flags); 622 w->name, w->event_flags);
578 623
@@ -621,9 +666,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w)
621 int in, out; 666 int in, out;
622 667
623 in = is_connected_input_ep(w); 668 in = is_connected_input_ep(w);
624 dapm_clear_walk(w->codec); 669 dapm_clear_walk(w->dapm);
625 out = is_connected_output_ep(w); 670 out = is_connected_output_ep(w);
626 dapm_clear_walk(w->codec); 671 dapm_clear_walk(w->dapm);
627 return out != 0 && in != 0; 672 return out != 0 && in != 0;
628} 673}
629 674
@@ -634,7 +679,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w)
634 679
635 if (w->active) { 680 if (w->active) {
636 in = is_connected_input_ep(w); 681 in = is_connected_input_ep(w);
637 dapm_clear_walk(w->codec); 682 dapm_clear_walk(w->dapm);
638 return in != 0; 683 return in != 0;
639 } else { 684 } else {
640 return dapm_generic_check_power(w); 685 return dapm_generic_check_power(w);
@@ -648,7 +693,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w)
648 693
649 if (w->active) { 694 if (w->active) {
650 out = is_connected_output_ep(w); 695 out = is_connected_output_ep(w);
651 dapm_clear_walk(w->codec); 696 dapm_clear_walk(w->dapm);
652 return out != 0; 697 return out != 0;
653 } else { 698 } else {
654 return dapm_generic_check_power(w); 699 return dapm_generic_check_power(w);
@@ -674,7 +719,7 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w)
674 } 719 }
675 } 720 }
676 721
677 dapm_clear_walk(w->codec); 722 dapm_clear_walk(w->dapm);
678 723
679 return power; 724 return power;
680} 725}
@@ -687,8 +732,8 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a,
687 return sort[a->id] - sort[b->id]; 732 return sort[a->id] - sort[b->id];
688 if (a->reg != b->reg) 733 if (a->reg != b->reg)
689 return a->reg - b->reg; 734 return a->reg - b->reg;
690 if (a->codec != b->codec) 735 if (a->dapm != b->dapm)
691 return (unsigned long)a->codec - (unsigned long)b->codec; 736 return (unsigned long)a->dapm - (unsigned long)b->dapm;
692 737
693 return 0; 738 return 0;
694} 739}
@@ -709,12 +754,57 @@ static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget,
709 list_add_tail(&new_widget->power_list, list); 754 list_add_tail(&new_widget->power_list, list);
710} 755}
711 756
757static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm,
758 struct snd_soc_dapm_widget *w, int event)
759{
760 struct snd_soc_card *card = dapm->card;
761 const char *ev_name;
762 int power, ret;
763
764 switch (event) {
765 case SND_SOC_DAPM_PRE_PMU:
766 ev_name = "PRE_PMU";
767 power = 1;
768 break;
769 case SND_SOC_DAPM_POST_PMU:
770 ev_name = "POST_PMU";
771 power = 1;
772 break;
773 case SND_SOC_DAPM_PRE_PMD:
774 ev_name = "PRE_PMD";
775 power = 0;
776 break;
777 case SND_SOC_DAPM_POST_PMD:
778 ev_name = "POST_PMD";
779 power = 0;
780 break;
781 default:
782 BUG();
783 return;
784 }
785
786 if (w->power != power)
787 return;
788
789 if (w->event && (w->event_flags & event)) {
790 pop_dbg(dapm->dev, card->pop_time, "pop test : %s %s\n",
791 w->name, ev_name);
792 trace_snd_soc_dapm_widget_event_start(w, event);
793 ret = w->event(w, NULL, event);
794 trace_snd_soc_dapm_widget_event_done(w, event);
795 if (ret < 0)
796 pr_err("%s: %s event failed: %d\n",
797 ev_name, w->name, ret);
798 }
799}
800
712/* Apply the coalesced changes from a DAPM sequence */ 801/* Apply the coalesced changes from a DAPM sequence */
713static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, 802static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm,
714 struct list_head *pending) 803 struct list_head *pending)
715{ 804{
805 struct snd_soc_card *card = dapm->card;
716 struct snd_soc_dapm_widget *w; 806 struct snd_soc_dapm_widget *w;
717 int reg, power, ret; 807 int reg, power;
718 unsigned int value = 0; 808 unsigned int value = 0;
719 unsigned int mask = 0; 809 unsigned int mask = 0;
720 unsigned int cur_mask; 810 unsigned int cur_mask;
@@ -735,64 +825,26 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
735 if (power) 825 if (power)
736 value |= cur_mask; 826 value |= cur_mask;
737 827
738 pop_dbg(codec->pop_time, 828 pop_dbg(dapm->dev, card->pop_time,
739 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", 829 "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n",
740 w->name, reg, value, mask); 830 w->name, reg, value, mask);
741 831
742 /* power up pre event */ 832 /* Check for events */
743 if (w->power && w->event && 833 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMU);
744 (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { 834 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMD);
745 pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n",
746 w->name);
747 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU);
748 if (ret < 0)
749 pr_err("%s: pre event failed: %d\n",
750 w->name, ret);
751 }
752
753 /* power down pre event */
754 if (!w->power && w->event &&
755 (w->event_flags & SND_SOC_DAPM_PRE_PMD)) {
756 pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n",
757 w->name);
758 ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD);
759 if (ret < 0)
760 pr_err("%s: pre event failed: %d\n",
761 w->name, ret);
762 }
763 } 835 }
764 836
765 if (reg >= 0) { 837 if (reg >= 0) {
766 pop_dbg(codec->pop_time, 838 pop_dbg(dapm->dev, card->pop_time,
767 "pop test : Applying 0x%x/0x%x to %x in %dms\n", 839 "pop test : Applying 0x%x/0x%x to %x in %dms\n",
768 value, mask, reg, codec->pop_time); 840 value, mask, reg, card->pop_time);
769 pop_wait(codec->pop_time); 841 pop_wait(card->pop_time);
770 snd_soc_update_bits(codec, reg, mask, value); 842 snd_soc_update_bits(dapm->codec, reg, mask, value);
771 } 843 }
772 844
773 list_for_each_entry(w, pending, power_list) { 845 list_for_each_entry(w, pending, power_list) {
774 /* power up post event */ 846 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMU);
775 if (w->power && w->event && 847 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMD);
776 (w->event_flags & SND_SOC_DAPM_POST_PMU)) {
777 pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n",
778 w->name);
779 ret = w->event(w,
780 NULL, SND_SOC_DAPM_POST_PMU);
781 if (ret < 0)
782 pr_err("%s: post event failed: %d\n",
783 w->name, ret);
784 }
785
786 /* power down post event */
787 if (!w->power && w->event &&
788 (w->event_flags & SND_SOC_DAPM_POST_PMD)) {
789 pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n",
790 w->name);
791 ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD);
792 if (ret < 0)
793 pr_err("%s: post event failed: %d\n",
794 w->name, ret);
795 }
796 } 848 }
797} 849}
798 850
@@ -804,26 +856,29 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec,
804 * Currently anything that requires more than a single write is not 856 * Currently anything that requires more than a single write is not
805 * handled. 857 * handled.
806 */ 858 */
807static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, 859static void dapm_seq_run(struct snd_soc_dapm_context *dapm,
808 int event, int sort[]) 860 struct list_head *list, int event, int sort[])
809{ 861{
810 struct snd_soc_dapm_widget *w, *n; 862 struct snd_soc_dapm_widget *w, *n;
811 LIST_HEAD(pending); 863 LIST_HEAD(pending);
812 int cur_sort = -1; 864 int cur_sort = -1;
813 int cur_reg = SND_SOC_NOPM; 865 int cur_reg = SND_SOC_NOPM;
866 struct snd_soc_dapm_context *cur_dapm = NULL;
814 int ret; 867 int ret;
815 868
816 list_for_each_entry_safe(w, n, list, power_list) { 869 list_for_each_entry_safe(w, n, list, power_list) {
817 ret = 0; 870 ret = 0;
818 871
819 /* Do we need to apply any queued changes? */ 872 /* Do we need to apply any queued changes? */
820 if (sort[w->id] != cur_sort || w->reg != cur_reg) { 873 if (sort[w->id] != cur_sort || w->reg != cur_reg ||
874 w->dapm != cur_dapm) {
821 if (!list_empty(&pending)) 875 if (!list_empty(&pending))
822 dapm_seq_run_coalesced(codec, &pending); 876 dapm_seq_run_coalesced(cur_dapm, &pending);
823 877
824 INIT_LIST_HEAD(&pending); 878 INIT_LIST_HEAD(&pending);
825 cur_sort = -1; 879 cur_sort = -1;
826 cur_reg = SND_SOC_NOPM; 880 cur_reg = SND_SOC_NOPM;
881 cur_dapm = NULL;
827 } 882 }
828 883
829 switch (w->id) { 884 switch (w->id) {
@@ -867,19 +922,55 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
867 /* Queue it up for application */ 922 /* Queue it up for application */
868 cur_sort = sort[w->id]; 923 cur_sort = sort[w->id];
869 cur_reg = w->reg; 924 cur_reg = w->reg;
925 cur_dapm = w->dapm;
870 list_move(&w->power_list, &pending); 926 list_move(&w->power_list, &pending);
871 break; 927 break;
872 } 928 }
873 929
874 if (ret < 0) 930 if (ret < 0)
875 pr_err("Failed to apply widget power: %d\n", 931 dev_err(w->dapm->dev,
876 ret); 932 "Failed to apply widget power: %d\n", ret);
877 } 933 }
878 934
879 if (!list_empty(&pending)) 935 if (!list_empty(&pending))
880 dapm_seq_run_coalesced(codec, &pending); 936 dapm_seq_run_coalesced(dapm, &pending);
937}
938
939static void dapm_widget_update(struct snd_soc_dapm_context *dapm)
940{
941 struct snd_soc_dapm_update *update = dapm->update;
942 struct snd_soc_dapm_widget *w;
943 int ret;
944
945 if (!update)
946 return;
947
948 w = update->widget;
949
950 if (w->event &&
951 (w->event_flags & SND_SOC_DAPM_PRE_REG)) {
952 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG);
953 if (ret != 0)
954 pr_err("%s DAPM pre-event failed: %d\n",
955 w->name, ret);
956 }
957
958 ret = snd_soc_update_bits(w->codec, update->reg, update->mask,
959 update->val);
960 if (ret < 0)
961 pr_err("%s DAPM update failed: %d\n", w->name, ret);
962
963 if (w->event &&
964 (w->event_flags & SND_SOC_DAPM_POST_REG)) {
965 ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG);
966 if (ret != 0)
967 pr_err("%s DAPM post-event failed: %d\n",
968 w->name, ret);
969 }
881} 970}
882 971
972
973
883/* 974/*
884 * Scan each dapm widget for complete audio path. 975 * Scan each dapm widget for complete audio path.
885 * A complete path is a route that has valid endpoints i.e.:- 976 * A complete path is a route that has valid endpoints i.e.:-
@@ -889,20 +980,26 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list,
889 * o Input pin to Output pin (bypass, sidetone) 980 * o Input pin to Output pin (bypass, sidetone)
890 * o DAC to ADC (loopback). 981 * o DAC to ADC (loopback).
891 */ 982 */
892static int dapm_power_widgets(struct snd_soc_codec *codec, int event) 983static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
893{ 984{
894 struct snd_soc_card *card = codec->card; 985 struct snd_soc_card *card = dapm->codec->card;
895 struct snd_soc_dapm_widget *w; 986 struct snd_soc_dapm_widget *w;
987 struct snd_soc_dapm_context *d;
896 LIST_HEAD(up_list); 988 LIST_HEAD(up_list);
897 LIST_HEAD(down_list); 989 LIST_HEAD(down_list);
898 int ret = 0; 990 int ret = 0;
899 int power; 991 int power;
900 int sys_power = 0; 992
993 trace_snd_soc_dapm_start(card);
994
995 list_for_each_entry(d, &card->dapm_list, list)
996 if (d->n_widgets)
997 d->dev_power = 0;
901 998
902 /* Check which widgets we need to power and store them in 999 /* Check which widgets we need to power and store them in
903 * lists indicating if they should be powered up or down. 1000 * lists indicating if they should be powered up or down.
904 */ 1001 */
905 list_for_each_entry(w, &codec->dapm_widgets, list) { 1002 list_for_each_entry(w, &card->widgets, list) {
906 switch (w->id) { 1003 switch (w->id) {
907 case snd_soc_dapm_pre: 1004 case snd_soc_dapm_pre:
908 dapm_seq_insert(w, &down_list, dapm_down_seq); 1005 dapm_seq_insert(w, &down_list, dapm_down_seq);
@@ -920,11 +1017,13 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
920 else 1017 else
921 power = 1; 1018 power = 1;
922 if (power) 1019 if (power)
923 sys_power = 1; 1020 w->dapm->dev_power = 1;
924 1021
925 if (w->power == power) 1022 if (w->power == power)
926 continue; 1023 continue;
927 1024
1025 trace_snd_soc_dapm_widget_power(w, power);
1026
928 if (power) 1027 if (power)
929 dapm_seq_insert(w, &up_list, dapm_up_seq); 1028 dapm_seq_insert(w, &up_list, dapm_up_seq);
930 else 1029 else
@@ -938,26 +1037,26 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
938 /* If there are no DAPM widgets then try to figure out power from the 1037 /* If there are no DAPM widgets then try to figure out power from the
939 * event type. 1038 * event type.
940 */ 1039 */
941 if (list_empty(&codec->dapm_widgets)) { 1040 if (!dapm->n_widgets) {
942 switch (event) { 1041 switch (event) {
943 case SND_SOC_DAPM_STREAM_START: 1042 case SND_SOC_DAPM_STREAM_START:
944 case SND_SOC_DAPM_STREAM_RESUME: 1043 case SND_SOC_DAPM_STREAM_RESUME:
945 sys_power = 1; 1044 dapm->dev_power = 1;
946 break; 1045 break;
947 case SND_SOC_DAPM_STREAM_STOP: 1046 case SND_SOC_DAPM_STREAM_STOP:
948 sys_power = !!codec->active; 1047 dapm->dev_power = !!dapm->codec->active;
949 break; 1048 break;
950 case SND_SOC_DAPM_STREAM_SUSPEND: 1049 case SND_SOC_DAPM_STREAM_SUSPEND:
951 sys_power = 0; 1050 dapm->dev_power = 0;
952 break; 1051 break;
953 case SND_SOC_DAPM_STREAM_NOP: 1052 case SND_SOC_DAPM_STREAM_NOP:
954 switch (codec->bias_level) { 1053 switch (dapm->bias_level) {
955 case SND_SOC_BIAS_STANDBY: 1054 case SND_SOC_BIAS_STANDBY:
956 case SND_SOC_BIAS_OFF: 1055 case SND_SOC_BIAS_OFF:
957 sys_power = 0; 1056 dapm->dev_power = 0;
958 break; 1057 break;
959 default: 1058 default:
960 sys_power = 1; 1059 dapm->dev_power = 1;
961 break; 1060 break;
962 } 1061 }
963 break; 1062 break;
@@ -966,52 +1065,71 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event)
966 } 1065 }
967 } 1066 }
968 1067
969 if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) { 1068 list_for_each_entry(d, &dapm->card->dapm_list, list) {
970 ret = snd_soc_dapm_set_bias_level(card, codec, 1069 if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) {
971 SND_SOC_BIAS_STANDBY); 1070 ret = snd_soc_dapm_set_bias_level(card, d,
972 if (ret != 0) 1071 SND_SOC_BIAS_STANDBY);
973 pr_err("Failed to turn on bias: %d\n", ret); 1072 if (ret != 0)
974 } 1073 dev_err(d->dev,
1074 "Failed to turn on bias: %d\n", ret);
1075 }
975 1076
976 /* If we're changing to all on or all off then prepare */ 1077 /* If we're changing to all on or all off then prepare */
977 if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || 1078 if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) ||
978 (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { 1079 (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) {
979 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_PREPARE); 1080 ret = snd_soc_dapm_set_bias_level(card, d,
980 if (ret != 0) 1081 SND_SOC_BIAS_PREPARE);
981 pr_err("Failed to prepare bias: %d\n", ret); 1082 if (ret != 0)
1083 dev_err(d->dev,
1084 "Failed to prepare bias: %d\n", ret);
1085 }
982 } 1086 }
983 1087
984 /* Power down widgets first; try to avoid amplifying pops. */ 1088 /* Power down widgets first; try to avoid amplifying pops. */
985 dapm_seq_run(codec, &down_list, event, dapm_down_seq); 1089 dapm_seq_run(dapm, &down_list, event, dapm_down_seq);
1090
1091 dapm_widget_update(dapm);
986 1092
987 /* Now power up. */ 1093 /* Now power up. */
988 dapm_seq_run(codec, &up_list, event, dapm_up_seq); 1094 dapm_seq_run(dapm, &up_list, event, dapm_up_seq);
1095
1096 list_for_each_entry(d, &dapm->card->dapm_list, list) {
1097 /* If we just powered the last thing off drop to standby bias */
1098 if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) {
1099 ret = snd_soc_dapm_set_bias_level(card, d,
1100 SND_SOC_BIAS_STANDBY);
1101 if (ret != 0)
1102 dev_err(d->dev,
1103 "Failed to apply standby bias: %d\n",
1104 ret);
1105 }
989 1106
990 /* If we just powered the last thing off drop to standby bias */ 1107 /* If we're in standby and can support bias off then do that */
991 if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { 1108 if (d->bias_level == SND_SOC_BIAS_STANDBY &&
992 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_STANDBY); 1109 d->idle_bias_off) {
993 if (ret != 0) 1110 ret = snd_soc_dapm_set_bias_level(card, d,
994 pr_err("Failed to apply standby bias: %d\n", ret); 1111 SND_SOC_BIAS_OFF);
995 } 1112 if (ret != 0)
1113 dev_err(d->dev,
1114 "Failed to turn off bias: %d\n", ret);
1115 }
996 1116
997 /* If we're in standby and can support bias off then do that */ 1117 /* If we just powered up then move to active bias */
998 if (codec->bias_level == SND_SOC_BIAS_STANDBY && 1118 if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) {
999 codec->idle_bias_off) { 1119 ret = snd_soc_dapm_set_bias_level(card, d,
1000 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); 1120 SND_SOC_BIAS_ON);
1001 if (ret != 0) 1121 if (ret != 0)
1002 pr_err("Failed to turn off bias: %d\n", ret); 1122 dev_err(d->dev,
1123 "Failed to apply active bias: %d\n",
1124 ret);
1125 }
1003 } 1126 }
1004 1127
1005 /* If we just powered up then move to active bias */ 1128 pop_dbg(dapm->dev, card->pop_time,
1006 if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { 1129 "DAPM sequencing finished, waiting %dms\n", card->pop_time);
1007 ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_ON); 1130 pop_wait(card->pop_time);
1008 if (ret != 0)
1009 pr_err("Failed to apply active bias: %d\n", ret);
1010 }
1011 1131
1012 pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n", 1132 trace_snd_soc_dapm_done(card);
1013 codec->pop_time);
1014 pop_wait(codec->pop_time);
1015 1133
1016 return 0; 1134 return 0;
1017} 1135}
@@ -1038,9 +1156,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file,
1038 return -ENOMEM; 1156 return -ENOMEM;
1039 1157
1040 in = is_connected_input_ep(w); 1158 in = is_connected_input_ep(w);
1041 dapm_clear_walk(w->codec); 1159 dapm_clear_walk(w->dapm);
1042 out = is_connected_output_ep(w); 1160 out = is_connected_output_ep(w);
1043 dapm_clear_walk(w->codec); 1161 dapm_clear_walk(w->dapm);
1044 1162
1045 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d", 1163 ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d",
1046 w->name, w->power ? "On" : "Off", in, out); 1164 w->name, w->power ? "On" : "Off", in, out);
@@ -1090,29 +1208,29 @@ static const struct file_operations dapm_widget_power_fops = {
1090 .llseek = default_llseek, 1208 .llseek = default_llseek,
1091}; 1209};
1092 1210
1093void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) 1211void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
1094{ 1212{
1095 struct snd_soc_dapm_widget *w; 1213 struct snd_soc_dapm_widget *w;
1096 struct dentry *d; 1214 struct dentry *d;
1097 1215
1098 if (!codec->debugfs_dapm) 1216 if (!dapm->debugfs_dapm)
1099 return; 1217 return;
1100 1218
1101 list_for_each_entry(w, &codec->dapm_widgets, list) { 1219 list_for_each_entry(w, &dapm->card->widgets, list) {
1102 if (!w->name) 1220 if (!w->name || w->dapm != dapm)
1103 continue; 1221 continue;
1104 1222
1105 d = debugfs_create_file(w->name, 0444, 1223 d = debugfs_create_file(w->name, 0444,
1106 codec->debugfs_dapm, w, 1224 dapm->debugfs_dapm, w,
1107 &dapm_widget_power_fops); 1225 &dapm_widget_power_fops);
1108 if (!d) 1226 if (!d)
1109 printk(KERN_WARNING 1227 dev_warn(w->dapm->dev,
1110 "ASoC: Failed to create %s debugfs file\n", 1228 "ASoC: Failed to create %s debugfs file\n",
1111 w->name); 1229 w->name);
1112 } 1230 }
1113} 1231}
1114#else 1232#else
1115void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) 1233void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm)
1116{ 1234{
1117} 1235}
1118#endif 1236#endif
@@ -1126,6 +1244,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1126 int found = 0; 1244 int found = 0;
1127 1245
1128 if (widget->id != snd_soc_dapm_mux && 1246 if (widget->id != snd_soc_dapm_mux &&
1247 widget->id != snd_soc_dapm_virt_mux &&
1129 widget->id != snd_soc_dapm_value_mux) 1248 widget->id != snd_soc_dapm_value_mux)
1130 return -ENODEV; 1249 return -ENODEV;
1131 1250
@@ -1133,7 +1252,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1133 return 0; 1252 return 0;
1134 1253
1135 /* find dapm widget path assoc with kcontrol */ 1254 /* find dapm widget path assoc with kcontrol */
1136 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 1255 list_for_each_entry(path, &widget->dapm->card->paths, list) {
1137 if (path->kcontrol != kcontrol) 1256 if (path->kcontrol != kcontrol)
1138 continue; 1257 continue;
1139 1258
@@ -1149,7 +1268,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
1149 } 1268 }
1150 1269
1151 if (found) 1270 if (found)
1152 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1271 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
1153 1272
1154 return 0; 1273 return 0;
1155} 1274}
@@ -1167,7 +1286,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1167 return -ENODEV; 1286 return -ENODEV;
1168 1287
1169 /* find dapm widget path assoc with kcontrol */ 1288 /* find dapm widget path assoc with kcontrol */
1170 list_for_each_entry(path, &widget->codec->dapm_paths, list) { 1289 list_for_each_entry(path, &widget->dapm->card->paths, list) {
1171 if (path->kcontrol != kcontrol) 1290 if (path->kcontrol != kcontrol)
1172 continue; 1291 continue;
1173 1292
@@ -1178,7 +1297,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
1178 } 1297 }
1179 1298
1180 if (found) 1299 if (found)
1181 dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); 1300 dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP);
1182 1301
1183 return 0; 1302 return 0;
1184} 1303}
@@ -1194,7 +1313,9 @@ static ssize_t dapm_widget_show(struct device *dev,
1194 int count = 0; 1313 int count = 0;
1195 char *state = "not set"; 1314 char *state = "not set";
1196 1315
1197 list_for_each_entry(w, &codec->dapm_widgets, list) { 1316 list_for_each_entry(w, &codec->card->widgets, list) {
1317 if (w->dapm != &codec->dapm)
1318 continue;
1198 1319
1199 /* only display widgets that burnm power */ 1320 /* only display widgets that burnm power */
1200 switch (w->id) { 1321 switch (w->id) {
@@ -1206,6 +1327,7 @@ static ssize_t dapm_widget_show(struct device *dev,
1206 case snd_soc_dapm_dac: 1327 case snd_soc_dapm_dac:
1207 case snd_soc_dapm_adc: 1328 case snd_soc_dapm_adc:
1208 case snd_soc_dapm_pga: 1329 case snd_soc_dapm_pga:
1330 case snd_soc_dapm_out_drv:
1209 case snd_soc_dapm_mixer: 1331 case snd_soc_dapm_mixer:
1210 case snd_soc_dapm_mixer_named_ctl: 1332 case snd_soc_dapm_mixer_named_ctl:
1211 case snd_soc_dapm_supply: 1333 case snd_soc_dapm_supply:
@@ -1218,7 +1340,7 @@ static ssize_t dapm_widget_show(struct device *dev,
1218 } 1340 }
1219 } 1341 }
1220 1342
1221 switch (codec->bias_level) { 1343 switch (codec->dapm.bias_level) {
1222 case SND_SOC_BIAS_ON: 1344 case SND_SOC_BIAS_ON:
1223 state = "On"; 1345 state = "On";
1224 break; 1346 break;
@@ -1250,31 +1372,50 @@ static void snd_soc_dapm_sys_remove(struct device *dev)
1250} 1372}
1251 1373
1252/* free all dapm widgets and resources */ 1374/* free all dapm widgets and resources */
1253static void dapm_free_widgets(struct snd_soc_codec *codec) 1375static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
1254{ 1376{
1255 struct snd_soc_dapm_widget *w, *next_w; 1377 struct snd_soc_dapm_widget *w, *next_w;
1256 struct snd_soc_dapm_path *p, *next_p; 1378 struct snd_soc_dapm_path *p, *next_p;
1257 1379
1258 list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) { 1380 list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) {
1381 if (w->dapm != dapm)
1382 continue;
1259 list_del(&w->list); 1383 list_del(&w->list);
1384 /*
1385 * remove source and sink paths associated to this widget.
1386 * While removing the path, remove reference to it from both
1387 * source and sink widgets so that path is removed only once.
1388 */
1389 list_for_each_entry_safe(p, next_p, &w->sources, list_sink) {
1390 list_del(&p->list_sink);
1391 list_del(&p->list_source);
1392 list_del(&p->list);
1393 kfree(p->long_name);
1394 kfree(p);
1395 }
1396 list_for_each_entry_safe(p, next_p, &w->sinks, list_source) {
1397 list_del(&p->list_sink);
1398 list_del(&p->list_source);
1399 list_del(&p->list);
1400 kfree(p->long_name);
1401 kfree(p);
1402 }
1403 kfree(w->name);
1260 kfree(w); 1404 kfree(w);
1261 } 1405 }
1262
1263 list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) {
1264 list_del(&p->list);
1265 kfree(p->long_name);
1266 kfree(p);
1267 }
1268} 1406}
1269 1407
1270static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, 1408static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
1271 const char *pin, int status) 1409 const char *pin, int status)
1272{ 1410{
1273 struct snd_soc_dapm_widget *w; 1411 struct snd_soc_dapm_widget *w;
1274 1412
1275 list_for_each_entry(w, &codec->dapm_widgets, list) { 1413 list_for_each_entry(w, &dapm->card->widgets, list) {
1414 if (w->dapm != dapm)
1415 continue;
1276 if (!strcmp(w->name, pin)) { 1416 if (!strcmp(w->name, pin)) {
1277 pr_debug("dapm: %s: pin %s\n", codec->name, pin); 1417 dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n",
1418 pin, status);
1278 w->connected = status; 1419 w->connected = status;
1279 /* Allow disabling of forced pins */ 1420 /* Allow disabling of forced pins */
1280 if (status == 0) 1421 if (status == 0)
@@ -1283,46 +1424,72 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec,
1283 } 1424 }
1284 } 1425 }
1285 1426
1286 pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); 1427 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
1287 return -EINVAL; 1428 return -EINVAL;
1288} 1429}
1289 1430
1290/** 1431/**
1291 * snd_soc_dapm_sync - scan and power dapm paths 1432 * snd_soc_dapm_sync - scan and power dapm paths
1292 * @codec: audio codec 1433 * @dapm: DAPM context
1293 * 1434 *
1294 * Walks all dapm audio paths and powers widgets according to their 1435 * Walks all dapm audio paths and powers widgets according to their
1295 * stream or path usage. 1436 * stream or path usage.
1296 * 1437 *
1297 * Returns 0 for success. 1438 * Returns 0 for success.
1298 */ 1439 */
1299int snd_soc_dapm_sync(struct snd_soc_codec *codec) 1440int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm)
1300{ 1441{
1301 return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); 1442 return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
1302} 1443}
1303EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); 1444EXPORT_SYMBOL_GPL(snd_soc_dapm_sync);
1304 1445
1305static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, 1446static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
1306 const struct snd_soc_dapm_route *route) 1447 const struct snd_soc_dapm_route *route)
1307{ 1448{
1308 struct snd_soc_dapm_path *path; 1449 struct snd_soc_dapm_path *path;
1309 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; 1450 struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w;
1310 const char *sink = route->sink; 1451 struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL;
1452 const char *sink;
1311 const char *control = route->control; 1453 const char *control = route->control;
1312 const char *source = route->source; 1454 const char *source;
1455 char prefixed_sink[80];
1456 char prefixed_source[80];
1313 int ret = 0; 1457 int ret = 0;
1314 1458
1315 /* find src and dest widgets */ 1459 if (dapm->codec->name_prefix) {
1316 list_for_each_entry(w, &codec->dapm_widgets, list) { 1460 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
1461 dapm->codec->name_prefix, route->sink);
1462 sink = prefixed_sink;
1463 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
1464 dapm->codec->name_prefix, route->source);
1465 source = prefixed_source;
1466 } else {
1467 sink = route->sink;
1468 source = route->source;
1469 }
1317 1470
1471 /*
1472 * find src and dest widgets over all widgets but favor a widget from
1473 * current DAPM context
1474 */
1475 list_for_each_entry(w, &dapm->card->widgets, list) {
1318 if (!wsink && !(strcmp(w->name, sink))) { 1476 if (!wsink && !(strcmp(w->name, sink))) {
1319 wsink = w; 1477 wtsink = w;
1478 if (w->dapm == dapm)
1479 wsink = w;
1320 continue; 1480 continue;
1321 } 1481 }
1322 if (!wsource && !(strcmp(w->name, source))) { 1482 if (!wsource && !(strcmp(w->name, source))) {
1323 wsource = w; 1483 wtsource = w;
1484 if (w->dapm == dapm)
1485 wsource = w;
1324 } 1486 }
1325 } 1487 }
1488 /* use widget from another DAPM context if not found from this */
1489 if (!wsink)
1490 wsink = wtsink;
1491 if (!wsource)
1492 wsource = wtsource;
1326 1493
1327 if (wsource == NULL || wsink == NULL) 1494 if (wsource == NULL || wsink == NULL)
1328 return -ENODEV; 1495 return -ENODEV;
@@ -1356,7 +1523,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1356 1523
1357 /* connect static paths */ 1524 /* connect static paths */
1358 if (control == NULL) { 1525 if (control == NULL) {
1359 list_add(&path->list, &codec->dapm_paths); 1526 list_add(&path->list, &dapm->card->paths);
1360 list_add(&path->list_sink, &wsink->sources); 1527 list_add(&path->list_sink, &wsink->sources);
1361 list_add(&path->list_source, &wsource->sinks); 1528 list_add(&path->list_source, &wsource->sinks);
1362 path->connect = 1; 1529 path->connect = 1;
@@ -1368,6 +1535,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1368 case snd_soc_dapm_adc: 1535 case snd_soc_dapm_adc:
1369 case snd_soc_dapm_dac: 1536 case snd_soc_dapm_dac:
1370 case snd_soc_dapm_pga: 1537 case snd_soc_dapm_pga:
1538 case snd_soc_dapm_out_drv:
1371 case snd_soc_dapm_input: 1539 case snd_soc_dapm_input:
1372 case snd_soc_dapm_output: 1540 case snd_soc_dapm_output:
1373 case snd_soc_dapm_micbias: 1541 case snd_soc_dapm_micbias:
@@ -1377,14 +1545,15 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1377 case snd_soc_dapm_supply: 1545 case snd_soc_dapm_supply:
1378 case snd_soc_dapm_aif_in: 1546 case snd_soc_dapm_aif_in:
1379 case snd_soc_dapm_aif_out: 1547 case snd_soc_dapm_aif_out:
1380 list_add(&path->list, &codec->dapm_paths); 1548 list_add(&path->list, &dapm->card->paths);
1381 list_add(&path->list_sink, &wsink->sources); 1549 list_add(&path->list_sink, &wsink->sources);
1382 list_add(&path->list_source, &wsource->sinks); 1550 list_add(&path->list_source, &wsource->sinks);
1383 path->connect = 1; 1551 path->connect = 1;
1384 return 0; 1552 return 0;
1385 case snd_soc_dapm_mux: 1553 case snd_soc_dapm_mux:
1554 case snd_soc_dapm_virt_mux:
1386 case snd_soc_dapm_value_mux: 1555 case snd_soc_dapm_value_mux:
1387 ret = dapm_connect_mux(codec, wsource, wsink, path, control, 1556 ret = dapm_connect_mux(dapm, wsource, wsink, path, control,
1388 &wsink->kcontrols[0]); 1557 &wsink->kcontrols[0]);
1389 if (ret != 0) 1558 if (ret != 0)
1390 goto err; 1559 goto err;
@@ -1392,7 +1561,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1392 case snd_soc_dapm_switch: 1561 case snd_soc_dapm_switch:
1393 case snd_soc_dapm_mixer: 1562 case snd_soc_dapm_mixer:
1394 case snd_soc_dapm_mixer_named_ctl: 1563 case snd_soc_dapm_mixer_named_ctl:
1395 ret = dapm_connect_mixer(codec, wsource, wsink, path, control); 1564 ret = dapm_connect_mixer(dapm, wsource, wsink, path, control);
1396 if (ret != 0) 1565 if (ret != 0)
1397 goto err; 1566 goto err;
1398 break; 1567 break;
@@ -1400,7 +1569,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1400 case snd_soc_dapm_mic: 1569 case snd_soc_dapm_mic:
1401 case snd_soc_dapm_line: 1570 case snd_soc_dapm_line:
1402 case snd_soc_dapm_spk: 1571 case snd_soc_dapm_spk:
1403 list_add(&path->list, &codec->dapm_paths); 1572 list_add(&path->list, &dapm->card->paths);
1404 list_add(&path->list_sink, &wsink->sources); 1573 list_add(&path->list_sink, &wsink->sources);
1405 list_add(&path->list_source, &wsource->sinks); 1574 list_add(&path->list_source, &wsource->sinks);
1406 path->connect = 0; 1575 path->connect = 0;
@@ -1409,15 +1578,15 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
1409 return 0; 1578 return 0;
1410 1579
1411err: 1580err:
1412 printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source, 1581 dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n",
1413 control, sink); 1582 source, control, sink);
1414 kfree(path); 1583 kfree(path);
1415 return ret; 1584 return ret;
1416} 1585}
1417 1586
1418/** 1587/**
1419 * snd_soc_dapm_add_routes - Add routes between DAPM widgets 1588 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
1420 * @codec: codec 1589 * @dapm: DAPM context
1421 * @route: audio routes 1590 * @route: audio routes
1422 * @num: number of routes 1591 * @num: number of routes
1423 * 1592 *
@@ -1428,17 +1597,16 @@ err:
1428 * Returns 0 for success else error. On error all resources can be freed 1597 * Returns 0 for success else error. On error all resources can be freed
1429 * with a call to snd_soc_card_free(). 1598 * with a call to snd_soc_card_free().
1430 */ 1599 */
1431int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, 1600int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
1432 const struct snd_soc_dapm_route *route, int num) 1601 const struct snd_soc_dapm_route *route, int num)
1433{ 1602{
1434 int i, ret; 1603 int i, ret;
1435 1604
1436 for (i = 0; i < num; i++) { 1605 for (i = 0; i < num; i++) {
1437 ret = snd_soc_dapm_add_route(codec, route); 1606 ret = snd_soc_dapm_add_route(dapm, route);
1438 if (ret < 0) { 1607 if (ret < 0) {
1439 printk(KERN_ERR "Failed to add route %s->%s\n", 1608 dev_err(dapm->dev, "Failed to add route %s->%s\n",
1440 route->source, 1609 route->source, route->sink);
1441 route->sink);
1442 return ret; 1610 return ret;
1443 } 1611 }
1444 route++; 1612 route++;
@@ -1450,17 +1618,17 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
1450 1618
1451/** 1619/**
1452 * snd_soc_dapm_new_widgets - add new dapm widgets 1620 * snd_soc_dapm_new_widgets - add new dapm widgets
1453 * @codec: audio codec 1621 * @dapm: DAPM context
1454 * 1622 *
1455 * Checks the codec for any new dapm widgets and creates them if found. 1623 * Checks the codec for any new dapm widgets and creates them if found.
1456 * 1624 *
1457 * Returns 0 for success. 1625 * Returns 0 for success.
1458 */ 1626 */
1459int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) 1627int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm)
1460{ 1628{
1461 struct snd_soc_dapm_widget *w; 1629 struct snd_soc_dapm_widget *w;
1462 1630
1463 list_for_each_entry(w, &codec->dapm_widgets, list) 1631 list_for_each_entry(w, &dapm->card->widgets, list)
1464 { 1632 {
1465 if (w->new) 1633 if (w->new)
1466 continue; 1634 continue;
@@ -1470,12 +1638,13 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1470 case snd_soc_dapm_mixer: 1638 case snd_soc_dapm_mixer:
1471 case snd_soc_dapm_mixer_named_ctl: 1639 case snd_soc_dapm_mixer_named_ctl:
1472 w->power_check = dapm_generic_check_power; 1640 w->power_check = dapm_generic_check_power;
1473 dapm_new_mixer(codec, w); 1641 dapm_new_mixer(dapm, w);
1474 break; 1642 break;
1475 case snd_soc_dapm_mux: 1643 case snd_soc_dapm_mux:
1644 case snd_soc_dapm_virt_mux:
1476 case snd_soc_dapm_value_mux: 1645 case snd_soc_dapm_value_mux:
1477 w->power_check = dapm_generic_check_power; 1646 w->power_check = dapm_generic_check_power;
1478 dapm_new_mux(codec, w); 1647 dapm_new_mux(dapm, w);
1479 break; 1648 break;
1480 case snd_soc_dapm_adc: 1649 case snd_soc_dapm_adc:
1481 case snd_soc_dapm_aif_out: 1650 case snd_soc_dapm_aif_out:
@@ -1486,8 +1655,9 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1486 w->power_check = dapm_dac_check_power; 1655 w->power_check = dapm_dac_check_power;
1487 break; 1656 break;
1488 case snd_soc_dapm_pga: 1657 case snd_soc_dapm_pga:
1658 case snd_soc_dapm_out_drv:
1489 w->power_check = dapm_generic_check_power; 1659 w->power_check = dapm_generic_check_power;
1490 dapm_new_pga(codec, w); 1660 dapm_new_pga(dapm, w);
1491 break; 1661 break;
1492 case snd_soc_dapm_input: 1662 case snd_soc_dapm_input:
1493 case snd_soc_dapm_output: 1663 case snd_soc_dapm_output:
@@ -1508,7 +1678,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec)
1508 w->new = 1; 1678 w->new = 1;
1509 } 1679 }
1510 1680
1511 dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); 1681 dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP);
1512 return 0; 1682 return 0;
1513} 1683}
1514EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); 1684EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets);
@@ -1569,13 +1739,12 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1569 (struct soc_mixer_control *)kcontrol->private_value; 1739 (struct soc_mixer_control *)kcontrol->private_value;
1570 unsigned int reg = mc->reg; 1740 unsigned int reg = mc->reg;
1571 unsigned int shift = mc->shift; 1741 unsigned int shift = mc->shift;
1572 unsigned int rshift = mc->rshift;
1573 int max = mc->max; 1742 int max = mc->max;
1574 unsigned int mask = (1 << fls(max)) - 1; 1743 unsigned int mask = (1 << fls(max)) - 1;
1575 unsigned int invert = mc->invert; 1744 unsigned int invert = mc->invert;
1576 unsigned int val, val2, val_mask; 1745 unsigned int val, val_mask;
1577 int connect; 1746 int connect, change;
1578 int ret; 1747 struct snd_soc_dapm_update update;
1579 1748
1580 val = (ucontrol->value.integer.value[0] & mask); 1749 val = (ucontrol->value.integer.value[0] & mask);
1581 1750
@@ -1583,18 +1752,12 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1583 val = max - val; 1752 val = max - val;
1584 val_mask = mask << shift; 1753 val_mask = mask << shift;
1585 val = val << shift; 1754 val = val << shift;
1586 if (shift != rshift) {
1587 val2 = (ucontrol->value.integer.value[1] & mask);
1588 if (invert)
1589 val2 = max - val2;
1590 val_mask |= mask << rshift;
1591 val |= val2 << rshift;
1592 }
1593 1755
1594 mutex_lock(&widget->codec->mutex); 1756 mutex_lock(&widget->codec->mutex);
1595 widget->value = val; 1757 widget->value = val;
1596 1758
1597 if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { 1759 change = snd_soc_test_bits(widget->codec, reg, val_mask, val);
1760 if (change) {
1598 if (val) 1761 if (val)
1599 /* new connection */ 1762 /* new connection */
1600 connect = invert ? 0:1; 1763 connect = invert ? 0:1;
@@ -1602,28 +1765,20 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
1602 /* old connection must be powered down */ 1765 /* old connection must be powered down */
1603 connect = invert ? 1:0; 1766 connect = invert ? 1:0;
1604 1767
1768 update.kcontrol = kcontrol;
1769 update.widget = widget;
1770 update.reg = reg;
1771 update.mask = mask;
1772 update.val = val;
1773 widget->dapm->update = &update;
1774
1605 dapm_mixer_update_power(widget, kcontrol, connect); 1775 dapm_mixer_update_power(widget, kcontrol, connect);
1776
1777 widget->dapm->update = NULL;
1606 } 1778 }
1607 1779
1608 if (widget->event) {
1609 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
1610 ret = widget->event(widget, kcontrol,
1611 SND_SOC_DAPM_PRE_REG);
1612 if (ret < 0) {
1613 ret = 1;
1614 goto out;
1615 }
1616 }
1617 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
1618 if (widget->event_flags & SND_SOC_DAPM_POST_REG)
1619 ret = widget->event(widget, kcontrol,
1620 SND_SOC_DAPM_POST_REG);
1621 } else
1622 ret = snd_soc_update_bits(widget->codec, reg, val_mask, val);
1623
1624out:
1625 mutex_unlock(&widget->codec->mutex); 1780 mutex_unlock(&widget->codec->mutex);
1626 return ret; 1781 return 0;
1627} 1782}
1628EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); 1783EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw);
1629 1784
@@ -1671,7 +1826,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1671 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1826 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1672 unsigned int val, mux, change; 1827 unsigned int val, mux, change;
1673 unsigned int mask, bitmask; 1828 unsigned int mask, bitmask;
1674 int ret = 0; 1829 struct snd_soc_dapm_update update;
1675 1830
1676 for (bitmask = 1; bitmask < e->max; bitmask <<= 1) 1831 for (bitmask = 1; bitmask < e->max; bitmask <<= 1)
1677 ; 1832 ;
@@ -1690,24 +1845,20 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
1690 mutex_lock(&widget->codec->mutex); 1845 mutex_lock(&widget->codec->mutex);
1691 widget->value = val; 1846 widget->value = val;
1692 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 1847 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1693 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1694 1848
1695 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1849 update.kcontrol = kcontrol;
1696 ret = widget->event(widget, 1850 update.widget = widget;
1697 kcontrol, SND_SOC_DAPM_PRE_REG); 1851 update.reg = e->reg;
1698 if (ret < 0) 1852 update.mask = mask;
1699 goto out; 1853 update.val = val;
1700 } 1854 widget->dapm->update = &update;
1701 1855
1702 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1856 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1703 1857
1704 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 1858 widget->dapm->update = NULL;
1705 ret = widget->event(widget,
1706 kcontrol, SND_SOC_DAPM_POST_REG);
1707 1859
1708out:
1709 mutex_unlock(&widget->codec->mutex); 1860 mutex_unlock(&widget->codec->mutex);
1710 return ret; 1861 return change;
1711} 1862}
1712EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); 1863EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double);
1713 1864
@@ -1819,7 +1970,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1819 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 1970 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
1820 unsigned int val, mux, change; 1971 unsigned int val, mux, change;
1821 unsigned int mask; 1972 unsigned int mask;
1822 int ret = 0; 1973 struct snd_soc_dapm_update update;
1823 1974
1824 if (ucontrol->value.enumerated.item[0] > e->max - 1) 1975 if (ucontrol->value.enumerated.item[0] > e->max - 1)
1825 return -EINVAL; 1976 return -EINVAL;
@@ -1836,24 +1987,20 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
1836 mutex_lock(&widget->codec->mutex); 1987 mutex_lock(&widget->codec->mutex);
1837 widget->value = val; 1988 widget->value = val;
1838 change = snd_soc_test_bits(widget->codec, e->reg, mask, val); 1989 change = snd_soc_test_bits(widget->codec, e->reg, mask, val);
1839 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1840 1990
1841 if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { 1991 update.kcontrol = kcontrol;
1842 ret = widget->event(widget, 1992 update.widget = widget;
1843 kcontrol, SND_SOC_DAPM_PRE_REG); 1993 update.reg = e->reg;
1844 if (ret < 0) 1994 update.mask = mask;
1845 goto out; 1995 update.val = val;
1846 } 1996 widget->dapm->update = &update;
1847 1997
1848 ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); 1998 dapm_mux_update_power(widget, kcontrol, change, mux, e);
1849 1999
1850 if (widget->event_flags & SND_SOC_DAPM_POST_REG) 2000 widget->dapm->update = NULL;
1851 ret = widget->event(widget,
1852 kcontrol, SND_SOC_DAPM_POST_REG);
1853 2001
1854out:
1855 mutex_unlock(&widget->codec->mutex); 2002 mutex_unlock(&widget->codec->mutex);
1856 return ret; 2003 return change;
1857} 2004}
1858EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); 2005EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double);
1859 2006
@@ -1892,7 +2039,7 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol,
1892 mutex_lock(&codec->mutex); 2039 mutex_lock(&codec->mutex);
1893 2040
1894 ucontrol->value.integer.value[0] = 2041 ucontrol->value.integer.value[0] =
1895 snd_soc_dapm_get_pin_status(codec, pin); 2042 snd_soc_dapm_get_pin_status(&codec->dapm, pin);
1896 2043
1897 mutex_unlock(&codec->mutex); 2044 mutex_unlock(&codec->mutex);
1898 2045
@@ -1915,11 +2062,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol,
1915 mutex_lock(&codec->mutex); 2062 mutex_lock(&codec->mutex);
1916 2063
1917 if (ucontrol->value.integer.value[0]) 2064 if (ucontrol->value.integer.value[0])
1918 snd_soc_dapm_enable_pin(codec, pin); 2065 snd_soc_dapm_enable_pin(&codec->dapm, pin);
1919 else 2066 else
1920 snd_soc_dapm_disable_pin(codec, pin); 2067 snd_soc_dapm_disable_pin(&codec->dapm, pin);
1921 2068
1922 snd_soc_dapm_sync(codec); 2069 snd_soc_dapm_sync(&codec->dapm);
1923 2070
1924 mutex_unlock(&codec->mutex); 2071 mutex_unlock(&codec->mutex);
1925 2072
@@ -1929,26 +2076,43 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch);
1929 2076
1930/** 2077/**
1931 * snd_soc_dapm_new_control - create new dapm control 2078 * snd_soc_dapm_new_control - create new dapm control
1932 * @codec: audio codec 2079 * @dapm: DAPM context
1933 * @widget: widget template 2080 * @widget: widget template
1934 * 2081 *
1935 * Creates a new dapm control based upon the template. 2082 * Creates a new dapm control based upon the template.
1936 * 2083 *
1937 * Returns 0 for success else error. 2084 * Returns 0 for success else error.
1938 */ 2085 */
1939int snd_soc_dapm_new_control(struct snd_soc_codec *codec, 2086int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
1940 const struct snd_soc_dapm_widget *widget) 2087 const struct snd_soc_dapm_widget *widget)
1941{ 2088{
1942 struct snd_soc_dapm_widget *w; 2089 struct snd_soc_dapm_widget *w;
2090 size_t name_len;
1943 2091
1944 if ((w = dapm_cnew_widget(widget)) == NULL) 2092 if ((w = dapm_cnew_widget(widget)) == NULL)
1945 return -ENOMEM; 2093 return -ENOMEM;
1946 2094
1947 w->codec = codec; 2095 name_len = strlen(widget->name) + 1;
2096 if (dapm->codec->name_prefix)
2097 name_len += 1 + strlen(dapm->codec->name_prefix);
2098 w->name = kmalloc(name_len, GFP_KERNEL);
2099 if (w->name == NULL) {
2100 kfree(w);
2101 return -ENOMEM;
2102 }
2103 if (dapm->codec->name_prefix)
2104 snprintf(w->name, name_len, "%s %s",
2105 dapm->codec->name_prefix, widget->name);
2106 else
2107 snprintf(w->name, name_len, "%s", widget->name);
2108
2109 dapm->n_widgets++;
2110 w->dapm = dapm;
2111 w->codec = dapm->codec;
1948 INIT_LIST_HEAD(&w->sources); 2112 INIT_LIST_HEAD(&w->sources);
1949 INIT_LIST_HEAD(&w->sinks); 2113 INIT_LIST_HEAD(&w->sinks);
1950 INIT_LIST_HEAD(&w->list); 2114 INIT_LIST_HEAD(&w->list);
1951 list_add(&w->list, &codec->dapm_widgets); 2115 list_add(&w->list, &dapm->card->widgets);
1952 2116
1953 /* machine layer set ups unconnected pins and insertions */ 2117 /* machine layer set ups unconnected pins and insertions */
1954 w->connected = 1; 2118 w->connected = 1;
@@ -1958,7 +2122,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
1958 2122
1959/** 2123/**
1960 * snd_soc_dapm_new_controls - create new dapm controls 2124 * snd_soc_dapm_new_controls - create new dapm controls
1961 * @codec: audio codec 2125 * @dapm: DAPM context
1962 * @widget: widget array 2126 * @widget: widget array
1963 * @num: number of widgets 2127 * @num: number of widgets
1964 * 2128 *
@@ -1966,18 +2130,18 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control);
1966 * 2130 *
1967 * Returns 0 for success else error. 2131 * Returns 0 for success else error.
1968 */ 2132 */
1969int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, 2133int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm,
1970 const struct snd_soc_dapm_widget *widget, 2134 const struct snd_soc_dapm_widget *widget,
1971 int num) 2135 int num)
1972{ 2136{
1973 int i, ret; 2137 int i, ret;
1974 2138
1975 for (i = 0; i < num; i++) { 2139 for (i = 0; i < num; i++) {
1976 ret = snd_soc_dapm_new_control(codec, widget); 2140 ret = snd_soc_dapm_new_control(dapm, widget);
1977 if (ret < 0) { 2141 if (ret < 0) {
1978 printk(KERN_ERR 2142 dev_err(dapm->dev,
1979 "ASoC: Failed to create DAPM control %s: %d\n", 2143 "ASoC: Failed to create DAPM control %s: %d\n",
1980 widget->name, ret); 2144 widget->name, ret);
1981 return ret; 2145 return ret;
1982 } 2146 }
1983 widget++; 2147 widget++;
@@ -1986,34 +2150,17 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec,
1986} 2150}
1987EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); 2151EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls);
1988 2152
1989 2153static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm,
1990/**
1991 * snd_soc_dapm_stream_event - send a stream event to the dapm core
1992 * @codec: audio codec
1993 * @stream: stream name
1994 * @event: stream event
1995 *
1996 * Sends a stream event to the dapm core. The core then makes any
1997 * necessary widget power changes.
1998 *
1999 * Returns 0 for success else error.
2000 */
2001int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
2002 const char *stream, int event) 2154 const char *stream, int event)
2003{ 2155{
2004 struct snd_soc_codec *codec = rtd->codec;
2005 struct snd_soc_dapm_widget *w; 2156 struct snd_soc_dapm_widget *w;
2006 2157
2007 if (stream == NULL) 2158 list_for_each_entry(w, &dapm->card->widgets, list)
2008 return 0;
2009
2010 mutex_lock(&codec->mutex);
2011 list_for_each_entry(w, &codec->dapm_widgets, list)
2012 { 2159 {
2013 if (!w->sname) 2160 if (!w->sname || w->dapm != dapm)
2014 continue; 2161 continue;
2015 pr_debug("widget %s\n %s stream %s event %d\n", 2162 dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n",
2016 w->name, w->sname, stream, event); 2163 w->name, w->sname, stream, event);
2017 if (strstr(w->sname, stream)) { 2164 if (strstr(w->sname, stream)) {
2018 switch(event) { 2165 switch(event) {
2019 case SND_SOC_DAPM_STREAM_START: 2166 case SND_SOC_DAPM_STREAM_START:
@@ -2031,7 +2178,30 @@ int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
2031 } 2178 }
2032 } 2179 }
2033 2180
2034 dapm_power_widgets(codec, event); 2181 dapm_power_widgets(dapm, event);
2182}
2183
2184/**
2185 * snd_soc_dapm_stream_event - send a stream event to the dapm core
2186 * @rtd: PCM runtime data
2187 * @stream: stream name
2188 * @event: stream event
2189 *
2190 * Sends a stream event to the dapm core. The core then makes any
2191 * necessary widget power changes.
2192 *
2193 * Returns 0 for success else error.
2194 */
2195int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd,
2196 const char *stream, int event)
2197{
2198 struct snd_soc_codec *codec = rtd->codec;
2199
2200 if (stream == NULL)
2201 return 0;
2202
2203 mutex_lock(&codec->mutex);
2204 soc_dapm_stream_event(&codec->dapm, stream, event);
2035 mutex_unlock(&codec->mutex); 2205 mutex_unlock(&codec->mutex);
2036 return 0; 2206 return 0;
2037} 2207}
@@ -2039,7 +2209,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
2039 2209
2040/** 2210/**
2041 * snd_soc_dapm_enable_pin - enable pin. 2211 * snd_soc_dapm_enable_pin - enable pin.
2042 * @codec: SoC codec 2212 * @dapm: DAPM context
2043 * @pin: pin name 2213 * @pin: pin name
2044 * 2214 *
2045 * Enables input/output pin and its parents or children widgets iff there is 2215 * Enables input/output pin and its parents or children widgets iff there is
@@ -2047,15 +2217,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event);
2047 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2217 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2048 * do any widget power switching. 2218 * do any widget power switching.
2049 */ 2219 */
2050int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin) 2220int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin)
2051{ 2221{
2052 return snd_soc_dapm_set_pin(codec, pin, 1); 2222 return snd_soc_dapm_set_pin(dapm, pin, 1);
2053} 2223}
2054EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); 2224EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
2055 2225
2056/** 2226/**
2057 * snd_soc_dapm_force_enable_pin - force a pin to be enabled 2227 * snd_soc_dapm_force_enable_pin - force a pin to be enabled
2058 * @codec: SoC codec 2228 * @dapm: DAPM context
2059 * @pin: pin name 2229 * @pin: pin name
2060 * 2230 *
2061 * Enables input/output pin regardless of any other state. This is 2231 * Enables input/output pin regardless of any other state. This is
@@ -2065,42 +2235,47 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin);
2065 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2235 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2066 * do any widget power switching. 2236 * do any widget power switching.
2067 */ 2237 */
2068int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, const char *pin) 2238int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm,
2239 const char *pin)
2069{ 2240{
2070 struct snd_soc_dapm_widget *w; 2241 struct snd_soc_dapm_widget *w;
2071 2242
2072 list_for_each_entry(w, &codec->dapm_widgets, list) { 2243 list_for_each_entry(w, &dapm->card->widgets, list) {
2244 if (w->dapm != dapm)
2245 continue;
2073 if (!strcmp(w->name, pin)) { 2246 if (!strcmp(w->name, pin)) {
2074 pr_debug("dapm: %s: pin %s\n", codec->name, pin); 2247 dev_dbg(w->dapm->dev,
2248 "dapm: force enable pin %s\n", pin);
2075 w->connected = 1; 2249 w->connected = 1;
2076 w->force = 1; 2250 w->force = 1;
2077 return 0; 2251 return 0;
2078 } 2252 }
2079 } 2253 }
2080 2254
2081 pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); 2255 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
2082 return -EINVAL; 2256 return -EINVAL;
2083} 2257}
2084EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); 2258EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin);
2085 2259
2086/** 2260/**
2087 * snd_soc_dapm_disable_pin - disable pin. 2261 * snd_soc_dapm_disable_pin - disable pin.
2088 * @codec: SoC codec 2262 * @dapm: DAPM context
2089 * @pin: pin name 2263 * @pin: pin name
2090 * 2264 *
2091 * Disables input/output pin and its parents or children widgets. 2265 * Disables input/output pin and its parents or children widgets.
2092 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2266 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2093 * do any widget power switching. 2267 * do any widget power switching.
2094 */ 2268 */
2095int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin) 2269int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm,
2270 const char *pin)
2096{ 2271{
2097 return snd_soc_dapm_set_pin(codec, pin, 0); 2272 return snd_soc_dapm_set_pin(dapm, pin, 0);
2098} 2273}
2099EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); 2274EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
2100 2275
2101/** 2276/**
2102 * snd_soc_dapm_nc_pin - permanently disable pin. 2277 * snd_soc_dapm_nc_pin - permanently disable pin.
2103 * @codec: SoC codec 2278 * @dapm: DAPM context
2104 * @pin: pin name 2279 * @pin: pin name
2105 * 2280 *
2106 * Marks the specified pin as being not connected, disabling it along 2281 * Marks the specified pin as being not connected, disabling it along
@@ -2112,26 +2287,29 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin);
2112 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to 2287 * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to
2113 * do any widget power switching. 2288 * do any widget power switching.
2114 */ 2289 */
2115int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin) 2290int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin)
2116{ 2291{
2117 return snd_soc_dapm_set_pin(codec, pin, 0); 2292 return snd_soc_dapm_set_pin(dapm, pin, 0);
2118} 2293}
2119EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); 2294EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin);
2120 2295
2121/** 2296/**
2122 * snd_soc_dapm_get_pin_status - get audio pin status 2297 * snd_soc_dapm_get_pin_status - get audio pin status
2123 * @codec: audio codec 2298 * @dapm: DAPM context
2124 * @pin: audio signal pin endpoint (or start point) 2299 * @pin: audio signal pin endpoint (or start point)
2125 * 2300 *
2126 * Get audio pin status - connected or disconnected. 2301 * Get audio pin status - connected or disconnected.
2127 * 2302 *
2128 * Returns 1 for connected otherwise 0. 2303 * Returns 1 for connected otherwise 0.
2129 */ 2304 */
2130int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin) 2305int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm,
2306 const char *pin)
2131{ 2307{
2132 struct snd_soc_dapm_widget *w; 2308 struct snd_soc_dapm_widget *w;
2133 2309
2134 list_for_each_entry(w, &codec->dapm_widgets, list) { 2310 list_for_each_entry(w, &dapm->card->widgets, list) {
2311 if (w->dapm != dapm)
2312 continue;
2135 if (!strcmp(w->name, pin)) 2313 if (!strcmp(w->name, pin))
2136 return w->connected; 2314 return w->connected;
2137 } 2315 }
@@ -2142,7 +2320,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
2142 2320
2143/** 2321/**
2144 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint 2322 * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint
2145 * @codec: audio codec 2323 * @dapm: DAPM context
2146 * @pin: audio signal pin endpoint (or start point) 2324 * @pin: audio signal pin endpoint (or start point)
2147 * 2325 *
2148 * Mark the given endpoint or pin as ignoring suspend. When the 2326 * Mark the given endpoint or pin as ignoring suspend. When the
@@ -2151,18 +2329,21 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status);
2151 * normal means at suspend time, it will not be turned on if it was not 2329 * normal means at suspend time, it will not be turned on if it was not
2152 * already enabled. 2330 * already enabled.
2153 */ 2331 */
2154int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin) 2332int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm,
2333 const char *pin)
2155{ 2334{
2156 struct snd_soc_dapm_widget *w; 2335 struct snd_soc_dapm_widget *w;
2157 2336
2158 list_for_each_entry(w, &codec->dapm_widgets, list) { 2337 list_for_each_entry(w, &dapm->card->widgets, list) {
2338 if (w->dapm != dapm)
2339 continue;
2159 if (!strcmp(w->name, pin)) { 2340 if (!strcmp(w->name, pin)) {
2160 w->ignore_suspend = 1; 2341 w->ignore_suspend = 1;
2161 return 0; 2342 return 0;
2162 } 2343 }
2163 } 2344 }
2164 2345
2165 pr_err("Unknown DAPM pin: %s\n", pin); 2346 dev_err(dapm->dev, "dapm: unknown pin %s\n", pin);
2166 return -EINVAL; 2347 return -EINVAL;
2167} 2348}
2168EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); 2349EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
@@ -2173,20 +2354,23 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend);
2173 * 2354 *
2174 * Free all dapm widgets and resources. 2355 * Free all dapm widgets and resources.
2175 */ 2356 */
2176void snd_soc_dapm_free(struct snd_soc_codec *codec) 2357void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm)
2177{ 2358{
2178 snd_soc_dapm_sys_remove(codec->dev); 2359 snd_soc_dapm_sys_remove(dapm->dev);
2179 dapm_free_widgets(codec); 2360 dapm_free_widgets(dapm);
2361 list_del(&dapm->list);
2180} 2362}
2181EXPORT_SYMBOL_GPL(snd_soc_dapm_free); 2363EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
2182 2364
2183static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec) 2365static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
2184{ 2366{
2185 struct snd_soc_dapm_widget *w; 2367 struct snd_soc_dapm_widget *w;
2186 LIST_HEAD(down_list); 2368 LIST_HEAD(down_list);
2187 int powerdown = 0; 2369 int powerdown = 0;
2188 2370
2189 list_for_each_entry(w, &codec->dapm_widgets, list) { 2371 list_for_each_entry(w, &dapm->card->widgets, list) {
2372 if (w->dapm != dapm)
2373 continue;
2190 if (w->power) { 2374 if (w->power) {
2191 dapm_seq_insert(w, &down_list, dapm_down_seq); 2375 dapm_seq_insert(w, &down_list, dapm_down_seq);
2192 w->power = 0; 2376 w->power = 0;
@@ -2198,9 +2382,9 @@ static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec)
2198 * standby. 2382 * standby.
2199 */ 2383 */
2200 if (powerdown) { 2384 if (powerdown) {
2201 snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_PREPARE); 2385 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE);
2202 dapm_seq_run(codec, &down_list, 0, dapm_down_seq); 2386 dapm_seq_run(dapm, &down_list, 0, dapm_down_seq);
2203 snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_STANDBY); 2387 snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY);
2204 } 2388 }
2205} 2389}
2206 2390
@@ -2211,10 +2395,10 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
2211{ 2395{
2212 struct snd_soc_codec *codec; 2396 struct snd_soc_codec *codec;
2213 2397
2214 list_for_each_entry(codec, &card->codec_dev_list, list) 2398 list_for_each_entry(codec, &card->codec_dev_list, list) {
2215 soc_dapm_shutdown_codec(codec); 2399 soc_dapm_shutdown_codec(&codec->dapm);
2216 2400 snd_soc_dapm_set_bias_level(card, &codec->dapm, SND_SOC_BIAS_OFF);
2217 snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); 2401 }
2218} 2402}
2219 2403
2220/* Module information */ 2404/* Module information */
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 8a0a9205b1e7..ac5a5bc7375a 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -13,11 +13,11 @@
13 13
14#include <sound/jack.h> 14#include <sound/jack.h>
15#include <sound/soc.h> 15#include <sound/soc.h>
16#include <sound/soc-dapm.h>
17#include <linux/gpio.h> 16#include <linux/gpio.h>
18#include <linux/interrupt.h> 17#include <linux/interrupt.h>
19#include <linux/workqueue.h> 18#include <linux/workqueue.h>
20#include <linux/delay.h> 19#include <linux/delay.h>
20#include <trace/events/asoc.h>
21 21
22/** 22/**
23 * snd_soc_jack_new - Create a new jack 23 * snd_soc_jack_new - Create a new jack
@@ -60,14 +60,18 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new);
60void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) 60void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
61{ 61{
62 struct snd_soc_codec *codec; 62 struct snd_soc_codec *codec;
63 struct snd_soc_dapm_context *dapm;
63 struct snd_soc_jack_pin *pin; 64 struct snd_soc_jack_pin *pin;
64 int enable; 65 int enable;
65 int oldstatus; 66 int oldstatus;
66 67
68 trace_snd_soc_jack_report(jack, mask, status);
69
67 if (!jack) 70 if (!jack)
68 return; 71 return;
69 72
70 codec = jack->codec; 73 codec = jack->codec;
74 dapm = &codec->dapm;
71 75
72 mutex_lock(&codec->mutex); 76 mutex_lock(&codec->mutex);
73 77
@@ -81,6 +85,8 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
81 if (mask && (jack->status == oldstatus)) 85 if (mask && (jack->status == oldstatus))
82 goto out; 86 goto out;
83 87
88 trace_snd_soc_jack_notify(jack, status);
89
84 list_for_each_entry(pin, &jack->pins, list) { 90 list_for_each_entry(pin, &jack->pins, list) {
85 enable = pin->mask & jack->status; 91 enable = pin->mask & jack->status;
86 92
@@ -88,15 +94,15 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask)
88 enable = !enable; 94 enable = !enable;
89 95
90 if (enable) 96 if (enable)
91 snd_soc_dapm_enable_pin(codec, pin->pin); 97 snd_soc_dapm_enable_pin(dapm, pin->pin);
92 else 98 else
93 snd_soc_dapm_disable_pin(codec, pin->pin); 99 snd_soc_dapm_disable_pin(dapm, pin->pin);
94 } 100 }
95 101
96 /* Report before the DAPM sync to help users updating micbias status */ 102 /* Report before the DAPM sync to help users updating micbias status */
97 blocking_notifier_call_chain(&jack->notifier, status, NULL); 103 blocking_notifier_call_chain(&jack->notifier, status, NULL);
98 104
99 snd_soc_dapm_sync(codec); 105 snd_soc_dapm_sync(dapm);
100 106
101 snd_jack_report(jack->jack, status); 107 snd_jack_report(jack->jack, status);
102 108
@@ -207,6 +213,12 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio)
207static irqreturn_t gpio_handler(int irq, void *data) 213static irqreturn_t gpio_handler(int irq, void *data)
208{ 214{
209 struct snd_soc_jack_gpio *gpio = data; 215 struct snd_soc_jack_gpio *gpio = data;
216 struct device *dev = gpio->jack->codec->card->dev;
217
218 trace_snd_soc_jack_irq(gpio->name);
219
220 if (device_may_wakeup(dev))
221 pm_wakeup_event(dev, gpio->debounce_time + 50);
210 222
211 schedule_delayed_work(&gpio->work, 223 schedule_delayed_work(&gpio->work,
212 msecs_to_jiffies(gpio->debounce_time)); 224 msecs_to_jiffies(gpio->debounce_time));
@@ -263,11 +275,12 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
263 INIT_DELAYED_WORK(&gpios[i].work, gpio_work); 275 INIT_DELAYED_WORK(&gpios[i].work, gpio_work);
264 gpios[i].jack = jack; 276 gpios[i].jack = jack;
265 277
266 ret = request_irq(gpio_to_irq(gpios[i].gpio), 278 ret = request_any_context_irq(gpio_to_irq(gpios[i].gpio),
267 gpio_handler, 279 gpio_handler,
268 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 280 IRQF_TRIGGER_RISING |
269 jack->codec->dev->driver->name, 281 IRQF_TRIGGER_FALLING,
270 &gpios[i]); 282 jack->codec->dev->driver->name,
283 &gpios[i]);
271 if (ret) 284 if (ret)
272 goto err; 285 goto err;
273 286
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 69148212aa70..5b792d2c8061 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -76,7 +76,10 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
76 format = 1 << UAC_FORMAT_TYPE_I_PCM; 76 format = 1 << UAC_FORMAT_TYPE_I_PCM;
77 } 77 }
78 if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) { 78 if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) {
79 if (sample_width > sample_bytes * 8) { 79 if (chip->usb_id == USB_ID(0x0582, 0x0016) /* Edirol SD-90 */ &&
80 sample_width == 24 && sample_bytes == 2)
81 sample_bytes = 3;
82 else if (sample_width > sample_bytes * 8) {
80 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n", 83 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
81 chip->dev->devnum, fp->iface, fp->altsetting, 84 chip->dev->devnum, fp->iface, fp->altsetting,
82 sample_width, sample_bytes); 85 sample_width, sample_bytes);
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 25bce7e5b1af..db2dc5ffe6dd 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -850,8 +850,8 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
850 return; 850 return;
851 } 851 }
852 852
853 memset(urb->transfer_buffer + count, 0xFD, 9 - count); 853 memset(urb->transfer_buffer + count, 0xFD, ep->max_transfer - count);
854 urb->transfer_buffer_length = count; 854 urb->transfer_buffer_length = ep->max_transfer;
855} 855}
856 856
857static struct usb_protocol_ops snd_usbmidi_122l_ops = { 857static struct usb_protocol_ops snd_usbmidi_122l_ops = {
@@ -1295,6 +1295,13 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1295 case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */ 1295 case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */
1296 ep->max_transfer = 4; 1296 ep->max_transfer = 4;
1297 break; 1297 break;
1298 /*
1299 * Some devices only work with 9 bytes packet size:
1300 */
1301 case USB_ID(0x0644, 0x800E): /* Tascam US-122L */
1302 case USB_ID(0x0644, 0x800F): /* Tascam US-144 */
1303 ep->max_transfer = 9;
1304 break;
1298 } 1305 }
1299 for (i = 0; i < OUTPUT_URBS; ++i) { 1306 for (i = 0; i < OUTPUT_URBS; ++i) {
1300 buffer = usb_alloc_coherent(umidi->dev, 1307 buffer = usb_alloc_coherent(umidi->dev,
@@ -1729,13 +1736,7 @@ static int roland_load_info(struct snd_kcontrol *kcontrol,
1729{ 1736{
1730 static const char *const names[] = { "High Load", "Light Load" }; 1737 static const char *const names[] = { "High Load", "Light Load" };
1731 1738
1732 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1739 return snd_ctl_enum_info(info, 1, 2, names);
1733 info->count = 1;
1734 info->value.enumerated.items = 2;
1735 if (info->value.enumerated.item > 1)
1736 info->value.enumerated.item = 1;
1737 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
1738 return 0;
1739} 1740}
1740 1741
1741static int roland_load_get(struct snd_kcontrol *kcontrol, 1742static int roland_load_get(struct snd_kcontrol *kcontrol,
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index f2d74d654b3c..7df89b3d7ded 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1633,18 +1633,11 @@ static int parse_audio_extension_unit(struct mixer_build *state, int unitid, voi
1633static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1633static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1634{ 1634{
1635 struct usb_mixer_elem_info *cval = kcontrol->private_data; 1635 struct usb_mixer_elem_info *cval = kcontrol->private_data;
1636 char **itemlist = (char **)kcontrol->private_value; 1636 const char **itemlist = (const char **)kcontrol->private_value;
1637 1637
1638 if (snd_BUG_ON(!itemlist)) 1638 if (snd_BUG_ON(!itemlist))
1639 return -EINVAL; 1639 return -EINVAL;
1640 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1640 return snd_ctl_enum_info(uinfo, 1, cval->max, itemlist);
1641 uinfo->count = 1;
1642 uinfo->value.enumerated.items = cval->max;
1643 if (uinfo->value.enumerated.item >= cval->max)
1644 uinfo->value.enumerated.item = cval->max - 1;
1645 strlcpy(uinfo->value.enumerated.name, itemlist[uinfo->value.enumerated.item],
1646 sizeof(uinfo->value.enumerated.name));
1647 return 0;
1648} 1641}
1649 1642
1650/* get callback for selector unit */ 1643/* get callback for selector unit */
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index ad7079d1676c..35999874d301 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -705,11 +705,11 @@ YAMAHA_DEVICE(0x7010, "UB99"),
705 .data = (const struct snd_usb_audio_quirk[]) { 705 .data = (const struct snd_usb_audio_quirk[]) {
706 { 706 {
707 .ifnum = 0, 707 .ifnum = 0,
708 .type = QUIRK_IGNORE_INTERFACE 708 .type = QUIRK_AUDIO_STANDARD_INTERFACE
709 }, 709 },
710 { 710 {
711 .ifnum = 1, 711 .ifnum = 1,
712 .type = QUIRK_IGNORE_INTERFACE 712 .type = QUIRK_AUDIO_STANDARD_INTERFACE
713 }, 713 },
714 { 714 {
715 .ifnum = 2, 715 .ifnum = 2,
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 6ef68e42138e..084e6fc8d5bf 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -273,29 +273,26 @@ static unsigned int usb_stream_hwdep_poll(struct snd_hwdep *hw,
273 struct file *file, poll_table *wait) 273 struct file *file, poll_table *wait)
274{ 274{
275 struct us122l *us122l = hw->private_data; 275 struct us122l *us122l = hw->private_data;
276 struct usb_stream *s = us122l->sk.s;
277 unsigned *polled; 276 unsigned *polled;
278 unsigned int mask; 277 unsigned int mask;
279 278
280 poll_wait(file, &us122l->sk.sleep, wait); 279 poll_wait(file, &us122l->sk.sleep, wait);
281 280
282 switch (s->state) { 281 mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
283 case usb_stream_ready: 282 if (mutex_trylock(&us122l->mutex)) {
284 if (us122l->first == file) 283 struct usb_stream *s = us122l->sk.s;
285 polled = &s->periods_polled; 284 if (s && s->state == usb_stream_ready) {
286 else 285 if (us122l->first == file)
287 polled = &us122l->second_periods_polled; 286 polled = &s->periods_polled;
288 if (*polled != s->periods_done) { 287 else
289 *polled = s->periods_done; 288 polled = &us122l->second_periods_polled;
290 mask = POLLIN | POLLOUT | POLLWRNORM; 289 if (*polled != s->periods_done) {
291 break; 290 *polled = s->periods_done;
291 mask = POLLIN | POLLOUT | POLLWRNORM;
292 } else
293 mask = 0;
292 } 294 }
293 /* Fall through */ 295 mutex_unlock(&us122l->mutex);
294 mask = 0;
295 break;
296 default:
297 mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
298 break;
299 } 296 }
300 return mask; 297 return mask;
301} 298}
@@ -381,6 +378,7 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
381{ 378{
382 struct usb_stream_config *cfg; 379 struct usb_stream_config *cfg;
383 struct us122l *us122l = hw->private_data; 380 struct us122l *us122l = hw->private_data;
381 struct usb_stream *s;
384 unsigned min_period_frames; 382 unsigned min_period_frames;
385 int err = 0; 383 int err = 0;
386 bool high_speed; 384 bool high_speed;
@@ -426,18 +424,18 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
426 snd_power_wait(hw->card, SNDRV_CTL_POWER_D0); 424 snd_power_wait(hw->card, SNDRV_CTL_POWER_D0);
427 425
428 mutex_lock(&us122l->mutex); 426 mutex_lock(&us122l->mutex);
427 s = us122l->sk.s;
429 if (!us122l->master) 428 if (!us122l->master)
430 us122l->master = file; 429 us122l->master = file;
431 else if (us122l->master != file) { 430 else if (us122l->master != file) {
432 if (memcmp(cfg, &us122l->sk.s->cfg, sizeof(*cfg))) { 431 if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg))) {
433 err = -EIO; 432 err = -EIO;
434 goto unlock; 433 goto unlock;
435 } 434 }
436 us122l->slave = file; 435 us122l->slave = file;
437 } 436 }
438 if (!us122l->sk.s || 437 if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg)) ||
439 memcmp(cfg, &us122l->sk.s->cfg, sizeof(*cfg)) || 438 s->state == usb_stream_xrun) {
440 us122l->sk.s->state == usb_stream_xrun) {
441 us122l_stop(us122l); 439 us122l_stop(us122l);
442 if (!us122l_start(us122l, cfg->sample_rate, cfg->period_frames)) 440 if (!us122l_start(us122l, cfg->sample_rate, cfg->period_frames))
443 err = -EIO; 441 err = -EIO;
@@ -448,6 +446,7 @@ unlock:
448 mutex_unlock(&us122l->mutex); 446 mutex_unlock(&us122l->mutex);
449free: 447free:
450 kfree(cfg); 448 kfree(cfg);
449 wake_up_all(&us122l->sk.sleep);
451 return err; 450 return err;
452} 451}
453 452